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
72c96a81
Commit
72c96a81
authored
Aug 08, 2019
by
Tom Milligan
Committed by
Sébastien Eustace
Aug 08, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
export: add extras flag and exclude optional packages by default (#1285)
parent
b637e9a1
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
165 additions
and
3 deletions
+165
-3
docs/docs/cli.md
+1
-0
poetry/console/commands/export.py
+10
-1
poetry/utils/exporter.py
+30
-2
tests/console/commands/test_export.py
+31
-0
tests/utils/test_exporter.py
+93
-0
No files found.
docs/docs/cli.md
View file @
72c96a81
...
@@ -442,6 +442,7 @@ poetry export -f requirements.txt > requirements.txt
...
@@ -442,6 +442,7 @@ poetry export -f requirements.txt > requirements.txt
* `
--output (-o)
`: The name of the output file. If omitted, print to standard
* `
--output (-o)
`: The name of the output file. If omitted, print to standard
output.
output.
* `
--dev
`: Include development dependencies.
* `
--dev
`: Include development dependencies.
* `
--extras (-E)
`: Extra sets of dependencies to include.
* `
--without-hashes
`: Exclude hashes from the exported file.
* `
--without-hashes
`: Exclude hashes from the exported file.
* `
--with-credentials
`: Include credentials for extra indices.
* `
--with-credentials
`: Include credentials for extra indices.
...
...
poetry/console/commands/export.py
View file @
72c96a81
from
cleo
import
option
from
poetry.utils.exporter
import
Exporter
from
poetry.utils.exporter
import
Exporter
from
cleo
import
option
from
.command
import
Command
from
.command
import
Command
...
@@ -14,6 +15,13 @@ class ExportCommand(Command):
...
@@ -14,6 +15,13 @@ class ExportCommand(Command):
option
(
"output"
,
"o"
,
"The name of the output file."
,
flag
=
False
),
option
(
"output"
,
"o"
,
"The name of the output file."
,
flag
=
False
),
option
(
"without-hashes"
,
None
,
"Exclude hashes from the exported file."
),
option
(
"without-hashes"
,
None
,
"Exclude hashes from the exported file."
),
option
(
"dev"
,
None
,
"Include development dependencies."
),
option
(
"dev"
,
None
,
"Include development dependencies."
),
option
(
"extras"
,
"E"
,
"Extra sets of dependencies to include."
,
flag
=
False
,
multiple
=
True
,
),
option
(
"with-credentials"
,
None
,
"Include credentials for extra indices."
),
option
(
"with-credentials"
,
None
,
"Include credentials for extra indices."
),
]
]
...
@@ -55,5 +63,6 @@ class ExportCommand(Command):
...
@@ -55,5 +63,6 @@ class ExportCommand(Command):
output
or
self
.
io
,
output
or
self
.
io
,
with_hashes
=
not
self
.
option
(
"without-hashes"
),
with_hashes
=
not
self
.
option
(
"without-hashes"
),
dev
=
self
.
option
(
"dev"
),
dev
=
self
.
option
(
"dev"
),
extras
=
self
.
option
(
"extras"
),
with_credentials
=
self
.
option
(
"with-credentials"
),
with_credentials
=
self
.
option
(
"with-credentials"
),
)
)
poetry/utils/exporter.py
View file @
72c96a81
...
@@ -23,7 +23,14 @@ class Exporter(object):
...
@@ -23,7 +23,14 @@ class Exporter(object):
self
.
_poetry
=
poetry
self
.
_poetry
=
poetry
def
export
(
def
export
(
self
,
fmt
,
cwd
,
output
,
with_hashes
=
True
,
dev
=
False
,
with_credentials
=
False
self
,
fmt
,
cwd
,
output
,
with_hashes
=
True
,
dev
=
False
,
extras
=
None
,
with_credentials
=
False
,
):
# type: (str, Path, Union[IO, str], bool, bool, bool) -> None
):
# type: (str, Path, Union[IO, str], bool, bool, bool) -> None
if
fmt
not
in
self
.
ACCEPTED_FORMATS
:
if
fmt
not
in
self
.
ACCEPTED_FORMATS
:
raise
ValueError
(
"Invalid export format: {}"
.
format
(
fmt
))
raise
ValueError
(
"Invalid export format: {}"
.
format
(
fmt
))
...
@@ -33,18 +40,39 @@ class Exporter(object):
...
@@ -33,18 +40,39 @@ class Exporter(object):
output
,
output
,
with_hashes
=
with_hashes
,
with_hashes
=
with_hashes
,
dev
=
dev
,
dev
=
dev
,
extras
=
extras
,
with_credentials
=
with_credentials
,
with_credentials
=
with_credentials
,
)
)
def
_export_requirements_txt
(
def
_export_requirements_txt
(
self
,
cwd
,
output
,
with_hashes
=
True
,
dev
=
False
,
with_credentials
=
False
self
,
cwd
,
output
,
with_hashes
=
True
,
dev
=
False
,
extras
=
None
,
with_credentials
=
False
,
):
# type: (Path, Union[IO, str], bool, bool, bool) -> None
):
# type: (Path, Union[IO, str], bool, bool, bool) -> None
indexes
=
[]
indexes
=
[]
content
=
""
content
=
""
# Generate a list of package names we have opted into via `extras`
extras_set
=
frozenset
(
extras
or
())
extra_package_names
=
set
()
if
extras
:
for
extra_name
,
extra_packages
in
self
.
_poetry
.
locker
.
lock_data
.
get
(
"extras"
,
{}
)
.
items
():
if
extra_name
in
extras_set
:
extra_package_names
.
update
(
extra_packages
)
for
package
in
sorted
(
for
package
in
sorted
(
self
.
_poetry
.
locker
.
locked_repository
(
dev
)
.
packages
,
key
=
lambda
p
:
p
.
name
self
.
_poetry
.
locker
.
locked_repository
(
dev
)
.
packages
,
key
=
lambda
p
:
p
.
name
):
):
# If a package is optional and we haven't opted in to it, continue
if
package
.
optional
and
package
.
name
not
in
extra_package_names
:
continue
if
package
.
source_type
==
"git"
:
if
package
.
source_type
==
"git"
:
dependency
=
VCSDependency
(
dependency
=
VCSDependency
(
package
.
name
,
package
.
name
,
...
...
tests/console/commands/test_export.py
View file @
72c96a81
...
@@ -39,6 +39,10 @@ classifiers = [
...
@@ -39,6 +39,10 @@ classifiers = [
[tool.poetry.dependencies]
[tool.poetry.dependencies]
python = "~2.7 || ^3.4"
python = "~2.7 || ^3.4"
foo = "^1.0"
foo = "^1.0"
bar = { version = "^1.1", optional = true }
[tool.poetry.extras]
feature_bar = ["bar"]
"""
"""
...
@@ -68,6 +72,7 @@ def test_export_exports_requirements_txt_file_locks_if_no_lock_file(app, repo):
...
@@ -68,6 +72,7 @@ def test_export_exports_requirements_txt_file_locks_if_no_lock_file(app, repo):
assert
not
app
.
poetry
.
locker
.
lock
.
exists
()
assert
not
app
.
poetry
.
locker
.
lock
.
exists
()
repo
.
add_package
(
get_package
(
"foo"
,
"1.0.0"
))
repo
.
add_package
(
get_package
(
"foo"
,
"1.0.0"
))
repo
.
add_package
(
get_package
(
"bar"
,
"1.1.0"
))
tester
.
execute
(
"--format requirements.txt --output requirements.txt"
)
tester
.
execute
(
"--format requirements.txt --output requirements.txt"
)
...
@@ -89,6 +94,7 @@ foo==1.0.0
...
@@ -89,6 +94,7 @@ foo==1.0.0
def
test_export_exports_requirements_txt_uses_lock_file
(
app
,
repo
):
def
test_export_exports_requirements_txt_uses_lock_file
(
app
,
repo
):
repo
.
add_package
(
get_package
(
"foo"
,
"1.0.0"
))
repo
.
add_package
(
get_package
(
"foo"
,
"1.0.0"
))
repo
.
add_package
(
get_package
(
"bar"
,
"1.1.0"
))
command
=
app
.
find
(
"lock"
)
command
=
app
.
find
(
"lock"
)
tester
=
CommandTester
(
command
)
tester
=
CommandTester
(
command
)
...
@@ -119,6 +125,7 @@ foo==1.0.0
...
@@ -119,6 +125,7 @@ foo==1.0.0
def
test_export_fails_on_invalid_format
(
app
,
repo
):
def
test_export_fails_on_invalid_format
(
app
,
repo
):
repo
.
add_package
(
get_package
(
"foo"
,
"1.0.0"
))
repo
.
add_package
(
get_package
(
"foo"
,
"1.0.0"
))
repo
.
add_package
(
get_package
(
"bar"
,
"1.1.0"
))
command
=
app
.
find
(
"lock"
)
command
=
app
.
find
(
"lock"
)
tester
=
CommandTester
(
command
)
tester
=
CommandTester
(
command
)
...
@@ -135,6 +142,7 @@ def test_export_fails_on_invalid_format(app, repo):
...
@@ -135,6 +142,7 @@ def test_export_fails_on_invalid_format(app, repo):
def
test_export_prints_to_stdout_by_default
(
app
,
repo
):
def
test_export_prints_to_stdout_by_default
(
app
,
repo
):
repo
.
add_package
(
get_package
(
"foo"
,
"1.0.0"
))
repo
.
add_package
(
get_package
(
"foo"
,
"1.0.0"
))
repo
.
add_package
(
get_package
(
"bar"
,
"1.1.0"
))
command
=
app
.
find
(
"lock"
)
command
=
app
.
find
(
"lock"
)
tester
=
CommandTester
(
command
)
tester
=
CommandTester
(
command
)
...
@@ -152,3 +160,26 @@ foo==1.0.0
...
@@ -152,3 +160,26 @@ foo==1.0.0
"""
"""
assert
expected
==
tester
.
io
.
fetch_output
()
assert
expected
==
tester
.
io
.
fetch_output
()
def
test_export_includes_extras_by_flag
(
app
,
repo
):
repo
.
add_package
(
get_package
(
"foo"
,
"1.0.0"
))
repo
.
add_package
(
get_package
(
"bar"
,
"1.1.0"
))
command
=
app
.
find
(
"lock"
)
tester
=
CommandTester
(
command
)
tester
.
execute
()
assert
app
.
poetry
.
locker
.
lock
.
exists
()
command
=
app
.
find
(
"export"
)
tester
=
CommandTester
(
command
)
tester
.
execute
(
"--format requirements.txt --extras feature_bar"
)
expected
=
"""
\
bar==1.1.0
foo==1.0.0
"""
assert
expected
==
tester
.
io
.
fetch_output
()
tests/utils/test_exporter.py
View file @
72c96a81
...
@@ -310,6 +310,99 @@ foo==1.2.3 \\
...
@@ -310,6 +310,99 @@ foo==1.2.3 \\
assert
expected
==
content
assert
expected
==
content
def
test_exporter_exports_requirements_txt_without_optional_packages
(
tmp_dir
,
poetry
):
poetry
.
locker
.
mock_lock_data
(
{
"package"
:
[
{
"name"
:
"foo"
,
"version"
:
"1.2.3"
,
"category"
:
"main"
,
"optional"
:
False
,
"python-versions"
:
"*"
,
},
{
"name"
:
"bar"
,
"version"
:
"4.5.6"
,
"category"
:
"dev"
,
"optional"
:
True
,
"python-versions"
:
"*"
,
},
],
"metadata"
:
{
"python-versions"
:
"*"
,
"content-hash"
:
"123456789"
,
"hashes"
:
{
"foo"
:
[
"12345"
],
"bar"
:
[
"67890"
]},
},
}
)
exporter
=
Exporter
(
poetry
)
exporter
.
export
(
"requirements.txt"
,
Path
(
tmp_dir
),
"requirements.txt"
,
dev
=
True
)
with
(
Path
(
tmp_dir
)
/
"requirements.txt"
)
.
open
(
encoding
=
"utf-8"
)
as
f
:
content
=
f
.
read
()
expected
=
"""
\
foo==1.2.3
\\
--hash=sha256:12345
"""
assert
expected
==
content
def
test_exporter_exports_requirements_txt_with_optional_packages_if_opted_in
(
tmp_dir
,
poetry
):
poetry
.
locker
.
mock_lock_data
(
{
"package"
:
[
{
"name"
:
"foo"
,
"version"
:
"1.2.3"
,
"category"
:
"main"
,
"optional"
:
False
,
"python-versions"
:
"*"
,
},
{
"name"
:
"bar"
,
"version"
:
"4.5.6"
,
"category"
:
"dev"
,
"optional"
:
True
,
"python-versions"
:
"*"
,
},
],
"metadata"
:
{
"python-versions"
:
"*"
,
"content-hash"
:
"123456789"
,
"hashes"
:
{
"foo"
:
[
"12345"
],
"bar"
:
[
"67890"
]},
},
"extras"
:
{
"feature_bar"
:
[
"bar"
]},
}
)
exporter
=
Exporter
(
poetry
)
exporter
.
export
(
"requirements.txt"
,
Path
(
tmp_dir
),
"requirements.txt"
,
dev
=
True
,
extras
=
[
"feature_bar"
],
)
with
(
Path
(
tmp_dir
)
/
"requirements.txt"
)
.
open
(
encoding
=
"utf-8"
)
as
f
:
content
=
f
.
read
()
expected
=
"""
\
bar==4.5.6
\\
--hash=sha256:67890
foo==1.2.3
\\
--hash=sha256:12345
"""
assert
expected
==
content
def
test_exporter_can_export_requirements_txt_with_git_packages
(
tmp_dir
,
poetry
):
def
test_exporter_can_export_requirements_txt_with_git_packages
(
tmp_dir
,
poetry
):
poetry
.
locker
.
mock_lock_data
(
poetry
.
locker
.
mock_lock_data
(
{
{
...
...
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