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
c0fcaf71
Unverified
Commit
c0fcaf71
authored
Mar 14, 2018
by
Sébastien Eustace
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add basic support for virtualenvs autogeneration
parent
241033c1
Show whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
313 additions
and
146 deletions
+313
-146
CHANGELOG.md
+6
-0
poetry/config.py
+88
-0
poetry/console/application.py
+0
-11
poetry/console/commands/add.py
+3
-2
poetry/console/commands/build.py
+2
-2
poetry/console/commands/command.py
+1
-1
poetry/console/commands/config.py
+67
-51
poetry/console/commands/install.py
+3
-3
poetry/console/commands/lock.py
+3
-2
poetry/console/commands/remove.py
+3
-2
poetry/console/commands/show.py
+2
-2
poetry/console/commands/update.py
+3
-3
poetry/console/commands/venv_command.py
+23
-0
poetry/console/styles/poetry.py
+1
-7
poetry/installation/installer.py
+5
-3
poetry/io/null_io.py
+5
-25
poetry/masonry/builder.py
+3
-4
poetry/masonry/builders/builder.py
+2
-1
poetry/masonry/builders/complete.py
+2
-2
poetry/masonry/builders/sdist.py
+0
-3
poetry/masonry/builders/wheel.py
+7
-7
poetry/utils/venv.py
+61
-1
tests/installation/test_installer.py
+11
-5
tests/masonry/builders/test_complete.py
+2
-1
tests/masonry/builders/test_sdist.py
+6
-5
tests/masonry/builders/test_wheel.py
+4
-3
No files found.
CHANGELOG.md
View file @
c0fcaf71
# Change Log
## [Unreleased]
### Added
-
Added support for virtualenv autogeneration (Python 3.6+ only).
## [0.5.0] - 2018-03-14
...
...
poetry/config.py
0 → 100644
View file @
c0fcaf71
from
pathlib
import
Path
from
typing
import
Any
from
.locations
import
CONFIG_DIR
from
.utils.toml_file
import
TomlFile
class
Config
:
def
__init__
(
self
,
file
:
TomlFile
):
self
.
_file
=
file
self
.
_raw_content
=
file
.
read
(
raw
=
True
)
self
.
_content
=
file
.
read
()
@property
def
name
(
self
):
return
str
(
self
.
_file
.
path
)
@property
def
file
(
self
):
return
self
.
_file
@property
def
raw_content
(
self
):
return
self
.
_raw_content
@property
def
content
(
self
):
return
self
.
_content
def
setting
(
self
,
setting_name
:
str
)
->
Any
:
"""
Retrieve a setting value.
"""
keys
=
setting_name
.
split
(
'.'
)
config
=
self
.
_raw_content
for
key
in
keys
:
if
key
not
in
config
:
return
None
config
=
config
[
key
]
return
config
def
add_property
(
self
,
key
,
value
):
keys
=
key
.
split
(
'.'
)
config
=
self
.
_content
for
i
,
key
in
enumerate
(
keys
):
if
key
not
in
config
and
i
<
len
(
keys
)
-
1
:
config
[
key
]
=
{}
if
i
==
len
(
keys
)
-
1
:
config
[
key
]
=
value
break
config
=
config
[
key
]
self
.
dump
()
def
remove_property
(
self
,
key
):
keys
=
key
.
split
(
'.'
)
config
=
self
.
_content
for
i
,
key
in
enumerate
(
keys
):
if
key
not
in
config
:
return
if
i
==
len
(
keys
)
-
1
:
del
config
[
key
]
break
config
=
config
[
key
]
self
.
dump
()
def
dump
(
self
):
self
.
_file
.
write
(
self
.
_content
)
@classmethod
def
create
(
cls
,
file
,
base_dir
=
None
)
->
'Config'
:
if
base_dir
is
None
:
base_dir
=
CONFIG_DIR
file
=
TomlFile
(
Path
(
base_dir
)
/
file
)
return
cls
(
file
)
poetry/console/application.py
View file @
c0fcaf71
...
...
@@ -24,7 +24,6 @@ class Application(BaseApplication):
super
()
.
__init__
(
'Poetry'
,
Poetry
.
VERSION
)
self
.
_poetry
=
None
self
.
_venv
=
Venv
.
create
()
@property
def
poetry
(
self
)
->
Poetry
:
...
...
@@ -38,10 +37,6 @@ class Application(BaseApplication):
def
reset_poetry
(
self
)
->
None
:
self
.
_poetry
=
None
@property
def
venv
(
self
)
->
Venv
:
return
self
.
_venv
def
get_default_commands
(
self
)
->
list
:
commands
=
super
(
Application
,
self
)
.
get_default_commands
()
...
...
@@ -58,9 +53,3 @@ class Application(BaseApplication):
ShowCommand
(),
UpdateCommand
(),
]
def
do_run
(
self
,
i
,
o
)
->
int
:
if
self
.
_venv
.
is_venv
()
and
o
.
is_verbose
():
o
.
writeln
(
f
'Using virtualenv: <comment>{self._venv.venv}</>'
)
return
super
()
.
do_run
(
i
,
o
)
poetry/console/commands/add.py
View file @
c0fcaf71
...
...
@@ -7,10 +7,10 @@ from poetry.installation import Installer
from
poetry.semver.version_parser
import
VersionParser
from
poetry.version.version_selector
import
VersionSelector
from
.
command
import
Command
from
.
venv_command
import
Venv
Command
class
AddCommand
(
Command
):
class
AddCommand
(
Venv
Command
):
"""
Add a new depdency to <comment>poetry.toml</>.
...
...
@@ -66,6 +66,7 @@ If you do not specify a version constraint, poetry will choose a suitable one ba
installer
=
Installer
(
self
.
output
,
self
.
venv
,
self
.
poetry
.
package
,
self
.
poetry
.
locker
,
self
.
poetry
.
pool
...
...
poetry/console/commands/build.py
View file @
c0fcaf71
from
.
command
import
Command
from
.
venv_command
import
Venv
Command
from
poetry.masonry
import
Builder
class
BuildCommand
(
Command
):
class
BuildCommand
(
Venv
Command
):
"""
Builds a package, as a tarball and a wheel by default.
...
...
poetry/console/commands/command.py
View file @
c0fcaf71
...
...
@@ -35,6 +35,6 @@ class Command(BaseCommand):
Initialize command.
"""
self
.
input
=
i
self
.
output
=
PoetryStyle
(
i
,
o
,
self
.
get_application
()
.
venv
)
self
.
output
=
PoetryStyle
(
i
,
o
)
return
super
(
BaseCommand
,
self
)
.
run
(
i
,
o
)
poetry/console/commands/config.py
View file @
c0fcaf71
import
json
import
re
from
pathlib
import
Path
from
poetry.locations
import
CONFIG_DIR
from
poetry.toml
import
loads
from
poetry.config
import
Config
from
.command
import
Command
TEMPLATE
=
"""[repositories]
TEMPLATE
=
"""[settings]
[repositories]
"""
AUTH_TEMPLATE
=
"""[http-basic]
...
...
@@ -41,36 +40,24 @@ To remove a repository (repo is a short alias for repositories):
def
__init__
(
self
):
super
()
.
__init__
()
self
.
_config_file
=
None
self
.
_config
=
{}
self
.
_auth_config_file
=
None
self
.
_auth_config
=
{}
self
.
_config
=
Config
.
create
(
'config.toml'
)
self
.
_auth_config
=
Config
.
create
(
'auth.toml'
)
def
initialize
(
self
,
i
,
o
):
super
()
.
initialize
(
i
,
o
)
# Create config file if it does not exist
self
.
_config_file
=
Path
(
CONFIG_DIR
)
/
'config.toml'
self
.
_auth_config_file
=
Path
(
CONFIG_DIR
)
/
'auth.toml'
if
not
self
.
_config_file
.
exists
():
self
.
_config_file
.
parent
.
mkdir
(
parents
=
True
,
exist_ok
=
True
)
self
.
_config_file
.
write_text
(
TEMPLATE
)
if
not
self
.
_auth_config_file
.
exists
():
if
not
self
.
_config
.
file
.
exists
():
self
.
_config
.
file
.
parent
.
mkdir
(
parents
=
True
,
exist_ok
=
True
)
self
.
_config
.
file
.
write_text
(
TEMPLATE
)
self
.
_auth_config_file
.
parent
.
mkdir
(
parents
=
True
,
exist_ok
=
True
)
self
.
_auth_config_file
.
write_text
(
AUTH_TEMPLATE
)
with
self
.
_config_file
.
open
()
as
f
:
self
.
_config
=
loads
(
f
.
read
())
with
self
.
_auth_config_file
.
open
()
as
f
:
self
.
_auth_config
=
loads
(
f
.
read
())
if
not
self
.
_auth_config
.
file
.
exists
():
self
.
_auth_config
.
file
.
parent
.
mkdir
(
parents
=
True
,
exist_ok
=
True
)
self
.
_auth_config
.
file
.
write_text
(
AUTH_TEMPLATE
)
def
handle
(
self
):
if
self
.
option
(
'list'
):
self
.
_list_configuration
(
self
.
_config
)
self
.
_list_configuration
(
self
.
_config
.
raw_content
)
return
0
...
...
@@ -87,15 +74,16 @@ To remove a repository (repo is a short alias for repositories):
if
m
:
if
not
m
.
group
(
1
):
value
=
{}
if
'repositories'
in
self
.
_config
:
value
=
self
.
_config
[
'repositories'
]
if
self
.
_config
.
setting
(
'repositories'
)
is
not
None
:
value
=
self
.
_config
.
setting
(
'repositories'
)
else
:
if
m
.
group
(
1
)
not
in
self
.
_config
[
'repositories'
]:
repo
=
self
.
_config
.
setting
(
f
'repositories.{m.group(1)}'
)
if
repo
is
None
:
raise
ValueError
(
f
'There is no
t
{m.group(1)} repository defined'
f
'There is no {m.group(1)} repository defined'
)
value
=
self
.
_config
[
'repositories'
][
m
.
group
(
1
)]
value
=
repo
self
.
line
(
str
(
value
))
...
...
@@ -103,6 +91,23 @@ To remove a repository (repo is a short alias for repositories):
values
=
self
.
argument
(
'value'
)
boolean_validator
=
lambda
val
:
val
in
{
'true'
,
'false'
,
'1'
,
'0'
}
boolean_normalizer
=
lambda
val
:
True
if
val
in
[
'true'
,
'1'
]
else
False
unique_config_values
=
{
'settings.virtualenvs.create'
:
(
boolean_validator
,
boolean_normalizer
)
}
if
setting_key
in
unique_config_values
:
if
self
.
option
(
'unset'
):
return
self
.
_remove_single_value
(
setting_key
)
return
self
.
_handle_single_value
(
setting_key
,
unique_config_values
[
setting_key
],
values
)
# handle repositories
m
=
re
.
match
(
'^repos?(?:itories)?(?:
\
.(.+))?'
,
self
.
argument
(
'key'
))
if
m
:
...
...
@@ -110,26 +115,18 @@ To remove a repository (repo is a short alias for repositories):
raise
ValueError
(
'You cannot remove the [repositories] section'
)
if
self
.
option
(
'unset'
):
if
m
.
group
(
1
)
not
in
self
.
_config
[
'repositories'
]:
raise
ValueError
(
f
'There is not {m.group(1)} repository defined'
)
del
self
.
_config
[
m
.
group
(
1
)]
repo
=
self
.
_config
.
setting
(
f
'repositories.{m.group(1)}'
)
if
repo
is
None
:
raise
ValueError
(
f
'There is no {m.group(1)} repository defined'
)
self
.
_config
_file
.
write_text
(
self
.
_config
.
dumps
()
)
self
.
_config
.
remove_property
(
f
'repositories.{m.group(1)}'
)
return
0
if
len
(
values
)
==
1
:
url
=
values
[
0
]
if
m
.
group
(
1
)
in
self
.
_config
[
'repositories'
]:
self
.
_config
[
'repositories'
][
m
.
group
(
1
)][
'url'
]
=
url
else
:
self
.
_config
[
'repositories'
][
m
.
group
(
1
)]
=
{
'url'
:
url
}
self
.
_config_file
.
write_text
(
self
.
_config
.
dumps
())
self
.
_config
.
add_property
(
f
'repositories.{m.group(1)}.url'
,
url
)
return
0
...
...
@@ -142,14 +139,12 @@ To remove a repository (repo is a short alias for repositories):
m
=
re
.
match
(
'^(http-basic)
\
.(.+)'
,
self
.
argument
(
'key'
))
if
m
:
if
self
.
option
(
'unset'
):
if
m
.
group
(
2
)
not
in
self
.
_auth_config
[
m
.
group
(
1
)]
:
if
not
self
.
_auth_config
.
setting
(
f
'{m.group(1)}.{m.group(2)}'
)
:
raise
ValueError
(
f
'There is no {m.group(2)} {m.group(1)} defined'
)
del
self
.
_auth_config
[
m
.
group
(
1
)][
m
.
group
(
2
)]
self
.
_auth_config_file
.
write_text
(
self
.
_auth_config
.
dumps
())
self
.
_auth_config
.
remove_property
(
f
'{m.group(1)}.{m.group(2)}'
)
return
0
...
...
@@ -165,17 +160,38 @@ To remove a repository (repo is a short alias for repositories):
username
=
values
[
0
]
password
=
values
[
1
]
self
.
_auth_config
[
m
.
group
(
1
)][
m
.
group
(
2
)]
=
{
self
.
_auth_config
.
add_property
(
f
'{m.group(1)}.{m.group(2)}'
,
{
'username'
:
username
,
'password'
:
password
}
self
.
_auth_config_file
.
write_text
(
self
.
_auth_config
.
dumps
())
)
return
0
raise
ValueError
(
f
'Setting {self.argument("key")} does not exist'
)
def
_handle_single_value
(
self
,
key
,
callbacks
,
values
):
validator
,
normalizer
=
callbacks
if
len
(
values
)
>
1
:
raise
RuntimeError
(
'You can only pass one value.'
)
value
=
values
[
0
]
if
not
validator
(
value
):
raise
RuntimeError
(
f
'"{value}" is an invalid value for {key}'
)
self
.
_config
.
add_property
(
key
,
normalizer
(
value
))
return
0
def
_remove_single_value
(
self
,
key
):
self
.
_config
.
remove_property
(
key
)
return
0
def
_list_configuration
(
self
,
contents
,
k
=
None
):
orig_k
=
k
...
...
poetry/console/commands/install.py
View file @
c0fcaf71
from
poetry.installation
import
Installer
from
poetry.repositories.pypi_repository
import
PyPiRepository
from
.
command
import
Command
from
.
venv_command
import
Venv
Command
class
InstallCommand
(
Command
):
class
InstallCommand
(
Venv
Command
):
"""
Installs the project dependencies.
...
...
@@ -27,6 +26,7 @@ exist it will look for <comment>poetry.toml</> and do the same.
def
handle
(
self
):
installer
=
Installer
(
self
.
output
,
self
.
venv
,
self
.
poetry
.
package
,
self
.
poetry
.
locker
,
self
.
poetry
.
pool
...
...
poetry/console/commands/lock.py
View file @
c0fcaf71
from
poetry.installation
import
Installer
from
.
command
import
Command
from
.
venv_command
import
Venv
Command
class
LockCommand
(
Command
):
class
LockCommand
(
Venv
Command
):
"""
Locks the project dependencies.
...
...
@@ -19,6 +19,7 @@ the current directory, processes it, and locks the depdencies in the <comment>po
def
handle
(
self
):
installer
=
Installer
(
self
.
output
,
self
.
venv
,
self
.
poetry
.
package
,
self
.
poetry
.
locker
,
self
.
poetry
.
pool
...
...
poetry/console/commands/remove.py
View file @
c0fcaf71
from
poetry.installation
import
Installer
from
.
command
import
Command
from
.
venv_command
import
Venv
Command
class
RemoveCommand
(
Command
):
class
RemoveCommand
(
Venv
Command
):
"""
Removes a package from the project dependencies.
...
...
@@ -54,6 +54,7 @@ list of installed packages
installer
=
Installer
(
self
.
output
,
self
.
venv
,
self
.
poetry
.
package
,
self
.
poetry
.
locker
,
self
.
poetry
.
pool
...
...
poetry/console/commands/show.py
View file @
c0fcaf71
from
poetry.semver
import
statisfies
from
poetry.version.version_selector
import
VersionSelector
from
.
command
import
Command
from
.
venv_command
import
Venv
Command
class
ShowCommand
(
Command
):
class
ShowCommand
(
Venv
Command
):
"""
Shows information about packages.
...
...
poetry/console/commands/update.py
View file @
c0fcaf71
from
poetry.installation
import
Installer
from
poetry.repositories.pypi_repository
import
PyPiRepository
from
.
command
import
Command
from
.
venv_command
import
Venv
Command
class
UpdateCommand
(
Command
):
class
UpdateCommand
(
Venv
Command
):
"""
Update dependencies as according to the <comment>poetry.toml</> file.
...
...
@@ -20,6 +19,7 @@ class UpdateCommand(Command):
installer
=
Installer
(
self
.
output
,
self
.
venv
,
self
.
poetry
.
package
,
self
.
poetry
.
locker
,
self
.
poetry
.
pool
...
...
poetry/console/commands/venv_command.py
0 → 100644
View file @
c0fcaf71
from
poetry.utils.venv
import
Venv
from
.command
import
Command
class
VenvCommand
(
Command
):
def
__init__
(
self
,
name
=
None
):
self
.
_venv
=
None
super
()
.
__init__
(
name
)
def
initialize
(
self
,
i
,
o
):
super
()
.
initialize
(
i
,
o
)
self
.
_venv
=
Venv
.
create
(
o
,
self
.
poetry
.
package
.
name
)
if
self
.
_venv
.
is_venv
()
and
o
.
is_verbose
():
o
.
writeln
(
f
'Using virtualenv: <comment>{self._venv.venv}</>'
)
@property
def
venv
(
self
):
return
self
.
_venv
poetry/console/styles/poetry.py
View file @
c0fcaf71
...
...
@@ -4,18 +4,12 @@ from cleo.styles import OutputStyle
class
PoetryStyle
(
CleoStyle
):
def
__init__
(
self
,
i
,
o
,
venv
):
self
.
_venv
=
venv
def
__init__
(
self
,
i
,
o
):
super
()
.
__init__
(
i
,
o
)
self
.
output
.
get_formatter
()
.
add_style
(
'warning'
,
'black'
,
'yellow'
)
self
.
output
.
get_formatter
()
.
add_style
(
'question'
,
'blue'
)
@property
def
venv
(
self
):
return
self
.
_venv
def
writeln
(
self
,
messages
,
type
=
OutputStyle
.
OUTPUT_NORMAL
,
verbosity
=
OutputStyle
.
VERBOSITY_NORMAL
):
...
...
poetry/installation/installer.py
View file @
c0fcaf71
...
...
@@ -25,10 +25,12 @@ class Installer:
def
__init__
(
self
,
io
,
venv
,
package
:
Package
,
locker
:
Locker
,
pool
:
Pool
):
self
.
_io
=
io
self
.
_venv
=
venv
self
.
_package
=
package
self
.
_locker
=
locker
self
.
_pool
=
pool
...
...
@@ -345,7 +347,7 @@ class Installer:
def
_get_operations_from_lock
(
self
,
locked_repository
:
Repository
)
->
List
[
Operation
]:
installed_repo
=
InstalledRepository
.
load
(
self
.
_
io
.
venv
)
installed_repo
=
InstalledRepository
.
load
(
self
.
_venv
)
ops
=
[]
extra_packages
=
[
...
...
@@ -390,7 +392,7 @@ class Installer:
continue
parser
=
VersionParser
()
python
=
'.'
.
join
([
str
(
i
)
for
i
in
self
.
_
io
.
venv
.
version_info
[:
3
]])
python
=
'.'
.
join
([
str
(
i
)
for
i
in
self
.
_venv
.
version_info
[:
3
]])
if
'python'
in
package
.
requirements
:
python_constraint
=
parser
.
parse_constraints
(
package
.
requirements
[
'python'
]
...
...
@@ -462,4 +464,4 @@ class Installer:
return
_extra_packages
(
extra_packages
)
def
_get_installer
(
self
)
->
BaseInstaller
:
return
PipInstaller
(
self
.
_
io
.
venv
,
self
.
_io
)
return
PipInstaller
(
self
.
_venv
,
self
.
_io
)
poetry/io/null_io.py
View file @
c0fcaf71
from
poetry.console.styles.poetry
import
PoetryStyle
from
poetry.utils.venv
import
Venv
class
NullVenv
(
Venv
):
def
__init__
(
self
,
execute
=
False
):
super
()
.
__init__
()
self
.
executed
=
[]
self
.
_execute
=
execute
from
cleo.inputs
import
ListInput
from
cleo.outputs
import
NullOutput
def
run
(
self
,
bin
:
str
,
*
args
):
self
.
executed
.
append
([
bin
]
+
list
(
args
))
if
self
.
_execute
:
return
super
()
.
run
(
bin
,
*
args
)
def
_bin
(
self
,
bin
):
return
bin
from
poetry.console.styles.poetry
import
PoetryStyle
class
NullIO
(
PoetryStyle
):
def
__init__
(
self
,
execute
=
False
):
self
.
_venv
=
NullVenv
(
execute
=
execute
)
@property
def
venv
(
self
)
->
NullVenv
:
return
self
.
_venv
def
__init__
(
self
):
super
()
.
__init__
(
ListInput
([]),
NullOutput
())
def
is_quiet
(
self
)
->
bool
:
return
False
...
...
poetry/masonry/builder.py
View file @
c0fcaf71
from
poetry.semver.constraints
import
MultiConstraint
from
.builders
import
CompleteBuilder
from
.builders
import
SdistBuilder
from
.builders
import
WheelBuilder
...
...
@@ -13,14 +11,15 @@ class Builder:
'all'
:
CompleteBuilder
}
def
__init__
(
self
,
poetry
,
io
):
def
__init__
(
self
,
poetry
,
venv
,
io
):
self
.
_poetry
=
poetry
self
.
_venv
=
venv
self
.
_io
=
io
def
build
(
self
,
fmt
:
str
):
if
fmt
not
in
self
.
_FORMATS
:
raise
ValueError
(
f
'Invalid format: {fmt}'
)
builder
=
self
.
_FORMATS
[
fmt
](
self
.
_poetry
,
self
.
_io
)
builder
=
self
.
_FORMATS
[
fmt
](
self
.
_poetry
,
self
.
_
venv
,
self
.
_
io
)
return
builder
.
build
()
poetry/masonry/builders/builder.py
View file @
c0fcaf71
...
...
@@ -24,8 +24,9 @@ class Builder:
'3.4'
,
'3.5'
,
'3.6'
,
'3.7'
}
def
__init__
(
self
,
poetry
,
io
):
def
__init__
(
self
,
poetry
,
venv
,
io
):
self
.
_poetry
=
poetry
self
.
_venv
=
venv
self
.
_io
=
io
self
.
_package
=
poetry
.
package
self
.
_path
=
poetry
.
file
.
parent
...
...
poetry/masonry/builders/complete.py
View file @
c0fcaf71
...
...
@@ -17,7 +17,7 @@ class CompleteBuilder(Builder):
def
build
(
self
):
# We start by building the tarball
# We will use it to build the wheel
sdist_builder
=
SdistBuilder
(
self
.
_poetry
,
self
.
_io
)
sdist_builder
=
SdistBuilder
(
self
.
_poetry
,
self
.
_
venv
,
self
.
_
io
)
sdist_file
=
sdist_builder
.
build
()
sdist_info
=
SimpleNamespace
(
builder
=
sdist_builder
,
file
=
sdist_file
)
...
...
@@ -26,7 +26,7 @@ class CompleteBuilder(Builder):
dist_dir
=
self
.
_path
/
'dist'
with
self
.
unpacked_tarball
(
sdist_file
)
as
tmpdir
:
wheel_info
=
WheelBuilder
.
make_in
(
poetry
.
Poetry
.
create
(
tmpdir
),
self
.
_io
,
dist_dir
,
poetry
.
Poetry
.
create
(
tmpdir
),
self
.
_
venv
,
self
.
_
io
,
dist_dir
,
original
=
self
.
_poetry
)
...
...
poetry/masonry/builders/sdist.py
View file @
c0fcaf71
...
...
@@ -51,9 +51,6 @@ Author-email: {author_email}
class
SdistBuilder
(
Builder
):
def
__init__
(
self
,
poetry
,
io
):
super
()
.
__init__
(
poetry
,
io
)
def
build
(
self
,
target_dir
:
Path
=
None
)
->
Path
:
self
.
_io
.
writeln
(
' - Building <info>sdist</info>'
)
if
target_dir
is
None
:
...
...
poetry/masonry/builders/wheel.py
View file @
c0fcaf71
...
...
@@ -35,8 +35,8 @@ Root-Is-Purelib: true
class
WheelBuilder
(
Builder
):
def
__init__
(
self
,
poetry
,
io
,
target_fp
,
original
=
None
):
super
()
.
__init__
(
poetry
,
io
)
def
__init__
(
self
,
poetry
,
venv
,
io
,
target_fp
,
original
=
None
):
super
()
.
__init__
(
poetry
,
venv
,
io
)
self
.
_records
=
[]
self
.
_original_path
=
self
.
_path
...
...
@@ -48,14 +48,14 @@ class WheelBuilder(Builder):
compression
=
zipfile
.
ZIP_DEFLATED
)
@classmethod
def
make_in
(
cls
,
poetry
,
io
,
directory
,
original
=
None
)
->
SimpleNamespace
:
def
make_in
(
cls
,
poetry
,
venv
,
io
,
directory
,
original
=
None
)
->
SimpleNamespace
:
# We don't know the final filename until metadata is loaded, so write to
# a temporary_file, and rename it afterwards.
(
fd
,
temp_path
)
=
tempfile
.
mkstemp
(
suffix
=
'.whl'
,
dir
=
str
(
directory
))
try
:
with
open
(
fd
,
'w+b'
)
as
fp
:
wb
=
WheelBuilder
(
poetry
,
io
,
fp
,
original
=
original
)
wb
=
WheelBuilder
(
poetry
,
venv
,
io
,
fp
,
original
=
original
)
wb
.
build
()
wheel_path
=
directory
/
wb
.
wheel_filename
...
...
@@ -67,7 +67,7 @@ class WheelBuilder(Builder):
return
SimpleNamespace
(
builder
=
wb
,
file
=
wheel_path
)
@classmethod
def
make
(
cls
,
poetry
,
io
)
->
SimpleNamespace
:
def
make
(
cls
,
poetry
,
venv
,
io
)
->
SimpleNamespace
:
"""Build a wheel in the dist/ directory, and optionally upload it.
"""
dist_dir
=
poetry
.
file
.
parent
/
'dist'
...
...
@@ -76,7 +76,7 @@ class WheelBuilder(Builder):
except
FileExistsError
:
pass
return
cls
.
make_in
(
poetry
,
io
,
dist_dir
)
return
cls
.
make_in
(
poetry
,
venv
,
io
,
dist_dir
)
def
build
(
self
)
->
None
:
self
.
_io
.
writeln
(
' - Building <info>wheel</info>'
)
...
...
@@ -99,7 +99,7 @@ class WheelBuilder(Builder):
current_path
=
os
.
getcwd
()
try
:
os
.
chdir
(
str
(
self
.
_path
))
self
.
_
io
.
venv
.
run
(
self
.
_venv
.
run
(
'python'
,
str
(
setup
),
'build'
,
...
...
poetry/utils/venv.py
View file @
c0fcaf71
...
...
@@ -3,8 +3,14 @@ import os
import
subprocess
import
sys
from
pathlib
import
Path
from
subprocess
import
CalledProcessError
from
venv
import
EnvBuilder
from
poetry.config
import
Config
from
poetry.locations
import
CACHE_DIR
class
VenvError
(
Exception
):
...
...
@@ -27,11 +33,47 @@ class Venv:
self
.
_version_info
=
None
@classmethod
def
create
(
cls
)
->
'Venv'
:
def
create
(
cls
,
io
,
name
=
None
)
->
'Venv'
:
if
'VIRTUAL_ENV'
not
in
os
.
environ
:
# Not in a virtualenv
# Checking if we need to create one
config
=
Config
.
create
(
'config.toml'
)
create_venv
=
config
.
setting
(
'settings.virtualenvs.create'
)
if
create_venv
is
False
:
io
.
writeln
(
'<fg=black;bg=yellow>'
'Skipping virtualenv creation, '
'as specified in config file.'
'</>'
)
return
cls
()
venv_path
=
config
.
setting
(
'settings.virtualenvs.path'
)
if
venv_path
is
None
:
venv_path
=
Path
(
CACHE_DIR
)
/
'virtualenvs'
else
:
venv_path
=
Path
(
venv_path
)
if
not
name
:
name
=
Path
.
cwd
()
.
name
name
=
f
'{name}-py{".".join([str(v) for v in sys.version_info[:2]])}'
venv
=
venv_path
/
name
if
not
venv
.
exists
():
io
.
writeln
(
f
'Creating virtualenv <info>{name}</> in {str(venv_path)}'
)
builder
=
EnvBuilder
(
with_pip
=
True
)
builder
.
create
(
str
(
venv
))
else
:
if
io
.
is_very_verbose
():
io
.
writeln
(
f
'Virtualenv <info>{name}</> already exists.'
)
os
.
environ
[
'VIRTUAL_ENV'
]
=
str
(
venv
)
# venv detection:
# stdlib venv may symlink sys.executable, so we can't use realpath.
# but others can symlink *to* the venv Python,
...
...
@@ -134,3 +176,21 @@ class Venv:
def
is_venv
(
self
)
->
bool
:
return
self
.
_venv
is
not
None
class
NullVenv
(
Venv
):
def
__init__
(
self
,
execute
=
False
):
super
()
.
__init__
()
self
.
executed
=
[]
self
.
_execute
=
execute
def
run
(
self
,
bin
:
str
,
*
args
):
self
.
executed
.
append
([
bin
]
+
list
(
args
))
if
self
.
_execute
:
return
super
()
.
run
(
bin
,
*
args
)
def
_bin
(
self
,
bin
):
return
bin
tests/installation/test_installer.py
View file @
c0fcaf71
...
...
@@ -11,6 +11,7 @@ from poetry.packages import Locker as BaseLocker
from
poetry.repositories
import
Pool
from
poetry.repositories
import
Repository
from
poetry.repositories.installed_repository
import
InstalledRepository
from
poetry.utils.venv
import
NullVenv
from
tests.helpers
import
get_dependency
from
tests.helpers
import
get_package
...
...
@@ -108,17 +109,22 @@ def locker():
return
Locker
()
@pytest.fixture
()
def
venv
():
return
NullVenv
()
@pytest.fixture
()
def
installer
(
package
,
pool
,
locker
,
venv
):
return
Installer
(
NullIO
(),
venv
,
package
,
locker
,
pool
)
def
fixture
(
name
):
file
=
Path
(
__file__
)
.
parent
/
'fixtures'
/
f
'{name}.test'
return
toml
.
loads
(
file
.
read_text
())
@pytest.fixture
()
def
installer
(
package
,
pool
,
locker
):
return
Installer
(
NullIO
(),
package
,
locker
,
pool
)
def
test_run_no_dependencies
(
installer
,
locker
):
installer
.
run
()
expected
=
fixture
(
'no-dependencies'
)
...
...
tests/masonry/builders/test_complete.py
View file @
c0fcaf71
...
...
@@ -8,6 +8,7 @@ from pathlib import Path
from
poetry
import
Poetry
from
poetry.io
import
NullIO
from
poetry.masonry.builders
import
CompleteBuilder
from
poetry.utils.venv
import
NullVenv
fixtures_dir
=
Path
(
__file__
)
.
parent
/
'fixtures'
...
...
@@ -29,7 +30,7 @@ def clear_samples_dist():
def
test_wheel_c_extension
():
module_path
=
fixtures_dir
/
'extended'
builder
=
CompleteBuilder
(
Poetry
.
create
(
module_path
),
Null
IO
(
True
))
builder
=
CompleteBuilder
(
Poetry
.
create
(
module_path
),
Null
Venv
(
True
),
NullIO
(
))
builder
.
build
()
sdist
=
fixtures_dir
/
'extended'
/
'dist'
/
'extended-0.1.tar.gz'
...
...
tests/masonry/builders/test_sdist.py
View file @
c0fcaf71
...
...
@@ -8,6 +8,7 @@ from pathlib import Path
from
poetry
import
Poetry
from
poetry.io
import
NullIO
from
poetry.masonry.builders.sdist
import
SdistBuilder
from
poetry.utils.venv
import
NullVenv
from
tests.helpers
import
get_dependency
...
...
@@ -71,7 +72,7 @@ def test_convert_dependencies():
def
test_make_setup
():
poetry
=
Poetry
.
create
(
project
(
'complete'
))
builder
=
SdistBuilder
(
poetry
,
NullIO
())
builder
=
SdistBuilder
(
poetry
,
Null
Venv
(),
Null
IO
())
setup
=
builder
.
build_setup
()
setup_ast
=
ast
.
parse
(
setup
)
...
...
@@ -94,7 +95,7 @@ def test_make_setup():
def
test_find_files_to_add
():
poetry
=
Poetry
.
create
(
project
(
'complete'
))
builder
=
SdistBuilder
(
poetry
,
NullIO
())
builder
=
SdistBuilder
(
poetry
,
Null
Venv
(),
Null
IO
())
result
=
builder
.
find_files_to_add
()
assert
result
==
[
...
...
@@ -111,7 +112,7 @@ def test_find_files_to_add():
def
test_package
():
poetry
=
Poetry
.
create
(
project
(
'complete'
))
builder
=
SdistBuilder
(
poetry
,
NullIO
())
builder
=
SdistBuilder
(
poetry
,
Null
Venv
(),
Null
IO
())
builder
.
build
()
sdist
=
fixtures_dir
/
'complete'
/
'dist'
/
'my-package-1.2.3.tar.gz'
...
...
@@ -122,7 +123,7 @@ def test_package():
def
test_prelease
():
poetry
=
Poetry
.
create
(
project
(
'prerelease'
))
builder
=
SdistBuilder
(
poetry
,
NullIO
())
builder
=
SdistBuilder
(
poetry
,
Null
Venv
(),
Null
IO
())
builder
.
build
()
sdist
=
fixtures_dir
/
'prerelease'
/
'dist'
/
'prerelease-0.1b1.tar.gz'
...
...
@@ -133,7 +134,7 @@ def test_prelease():
def
test_with_c_extensions
():
poetry
=
Poetry
.
create
(
project
(
'extended'
))
builder
=
SdistBuilder
(
poetry
,
NullIO
())
builder
=
SdistBuilder
(
poetry
,
Null
Venv
(),
Null
IO
())
builder
.
build
()
sdist
=
fixtures_dir
/
'extended'
/
'dist'
/
'extended-0.1.tar.gz'
...
...
tests/masonry/builders/test_wheel.py
View file @
c0fcaf71
...
...
@@ -6,6 +6,7 @@ from pathlib import Path
from
poetry
import
Poetry
from
poetry.io
import
NullIO
from
poetry.masonry.builders
import
WheelBuilder
from
poetry.utils.venv
import
NullVenv
fixtures_dir
=
Path
(
__file__
)
.
parent
/
'fixtures'
...
...
@@ -28,7 +29,7 @@ def clear_samples_dist():
def
test_wheel_module
():
module_path
=
fixtures_dir
/
'module1'
WheelBuilder
.
make
(
Poetry
.
create
(
str
(
module_path
)),
NullIO
())
WheelBuilder
.
make
(
Poetry
.
create
(
str
(
module_path
)),
Null
Venv
(),
Null
IO
())
whl
=
module_path
/
'dist'
/
'module1-0.1-py2.py3-none-any.whl'
...
...
@@ -37,7 +38,7 @@ def test_wheel_module():
def
test_wheel_package
():
module_path
=
fixtures_dir
/
'complete'
WheelBuilder
.
make
(
Poetry
.
create
(
str
(
module_path
)),
NullIO
())
WheelBuilder
.
make
(
Poetry
.
create
(
str
(
module_path
)),
Null
Venv
(),
Null
IO
())
whl
=
module_path
/
'dist'
/
'my_package-1.2.3-py3-none-any.whl'
...
...
@@ -46,7 +47,7 @@ def test_wheel_package():
def
test_wheel_prerelease
():
module_path
=
fixtures_dir
/
'prerelease'
WheelBuilder
.
make
(
Poetry
.
create
(
str
(
module_path
)),
NullIO
())
WheelBuilder
.
make
(
Poetry
.
create
(
str
(
module_path
)),
Null
Venv
(),
Null
IO
())
whl
=
module_path
/
'dist'
/
'prerelease-0.1b1-py2.py3-none-any.whl'
...
...
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