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
4113773a
Unverified
Commit
4113773a
authored
May 21, 2018
by
Sébastien Eustace
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add a new init command
parent
e552d9ab
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
238 additions
and
140 deletions
+238
-140
CHANGELOG.md
+1
-0
README.md
+18
-0
docs/docs/cli.md
+20
-0
poetry/console/application.py
+2
-0
poetry/console/commands/__init__.py
+1
-0
poetry/console/commands/add.py
+2
-97
poetry/console/commands/init.py
+0
-0
poetry/console/commands/new.py
+11
-3
poetry/console/styles/poetry.py
+1
-1
poetry/layouts/layout.py
+55
-29
poetry/repositories/repository.py
+9
-0
poetry/vcs/git.py
+12
-9
pyproject.toml
+1
-1
tests/console/commands/test_init.py
+105
-0
No files found.
CHANGELOG.md
View file @
4113773a
...
...
@@ -5,6 +5,7 @@
### Added
-
Added a new, more efficient dependency resolver.
-
Added a new
`init`
command to generate a
`pyproject.toml`
file in existing projects.
-
Added the
`--extras`
and
`--python`
options to
`debug:resolve`
to help debug dependency resolution.
### Changed
...
...
README.md
View file @
4113773a
...
...
@@ -264,6 +264,24 @@ the `--name` option:
poetry new my-folder
--name
my-package
```
### init
This command will help you create a
`pyproject.toml`
file interactively
by prompting you to provide basic information about your package.
It will interactively ask you to fill in the fields, while using some smart defaults.
```
bash
poetry init
```
#### Options
*
`--name`
: Name of the package.
*
`--description`
: Description of the package.
*
`--author`
: Author of the package.
*
`--dependency`
: Package to require with a version constraint. Should be in format
`foo:1.0.0`
.
*
`--dev-dependency`
: Development requirements, see
`--require`
.
### install
...
...
docs/docs/cli.md
View file @
4113773a
...
...
@@ -54,6 +54,26 @@ the `--name` option:
poetry new my-folder
--name
my-package
```
## init
This command will help you create a
`pyproject.toml`
file interactively
by prompting you to provide basic information about your package.
It will interactively ask you to fill in the fields, while using some smart defaults.
```
bash
poetry init
```
### Options
*
`--name`
: Name of the package.
*
`--description`
: Description of the package.
*
`--author`
: Author of the package.
*
`--dependency`
: Package to require with a version constraint. Should be in format
`foo:1.0.0`
.
*
`--dev-dependency`
: Development requirements, see
`--require`
.
## install
The
`install`
command reads the
`pyproject.toml`
file from the current project,
...
...
poetry/console/application.py
View file @
4113773a
...
...
@@ -18,6 +18,7 @@ from .commands import AddCommand
from
.commands
import
BuildCommand
from
.commands
import
CheckCommand
from
.commands
import
ConfigCommand
from
.commands
import
InitCommand
from
.commands
import
InstallCommand
from
.commands
import
LockCommand
from
.commands
import
NewCommand
...
...
@@ -106,6 +107,7 @@ class Application(BaseApplication):
BuildCommand
(),
CheckCommand
(),
ConfigCommand
(),
InitCommand
(),
InstallCommand
(),
LockCommand
(),
NewCommand
(),
...
...
poetry/console/commands/__init__.py
View file @
4113773a
...
...
@@ -3,6 +3,7 @@ from .add import AddCommand
from
.build
import
BuildCommand
from
.check
import
CheckCommand
from
.config
import
ConfigCommand
from
.init
import
InitCommand
from
.install
import
InstallCommand
from
.lock
import
LockCommand
from
.new
import
NewCommand
...
...
poetry/console/commands/add.py
View file @
4113773a
import
re
from
typing
import
List
from
typing
import
Tuple
from
.init
import
InitCommand
from
.venv_command
import
VenvCommand
class
AddCommand
(
VenvCommand
):
class
AddCommand
(
VenvCommand
,
InitCommand
):
"""
Add a new dependency to <comment>pyproject.toml</>.
...
...
@@ -147,94 +143,3 @@ If you do not specify a version constraint, poetry will choose a suitable one ba
self
.
poetry
.
file
.
write
(
original_content
)
return
status
def
_determine_requirements
(
self
,
requires
,
# type: List[str]
allow_prereleases
=
False
,
# type: bool
):
# type: (...) -> List[str]
if
not
requires
:
return
[]
requires
=
self
.
_parse_name_version_pairs
(
requires
)
result
=
[]
for
requirement
in
requires
:
if
'version'
not
in
requirement
:
# determine the best version automatically
name
,
version
=
self
.
_find_best_version_for_package
(
requirement
[
'name'
],
allow_prereleases
=
allow_prereleases
)
requirement
[
'version'
]
=
version
requirement
[
'name'
]
=
name
self
.
line
(
'Using version <info>{}</> for <info>{}</>'
.
format
(
version
,
name
)
)
else
:
# check that the specified version/constraint exists
# before we proceed
name
,
_
=
self
.
_find_best_version_for_package
(
requirement
[
'name'
],
requirement
[
'version'
],
allow_prereleases
=
allow_prereleases
)
requirement
[
'name'
]
=
name
result
.
append
(
'{} {}'
.
format
(
requirement
[
'name'
],
requirement
[
'version'
])
)
return
result
def
_find_best_version_for_package
(
self
,
name
,
required_version
=
None
,
allow_prereleases
=
False
):
# type: (...) -> Tuple[str, str]
from
poetry.version.version_selector
import
VersionSelector
selector
=
VersionSelector
(
self
.
poetry
.
pool
)
package
=
selector
.
find_best_candidate
(
name
,
required_version
,
allow_prereleases
=
allow_prereleases
)
if
not
package
:
# TODO: find similar
raise
ValueError
(
'Could not find a matching version of package {}'
.
format
(
name
)
)
return
(
package
.
pretty_name
,
selector
.
find_recommended_require_version
(
package
)
)
def
_parse_name_version_pairs
(
self
,
pairs
):
# type: (list) -> list
result
=
[]
for
i
in
range
(
len
(
pairs
)):
pair
=
re
.
sub
(
'^([^=: ]+)[=: ](.*)$'
,
'
\\
1
\\
2'
,
pairs
[
i
]
.
strip
())
pair
=
pair
.
strip
()
if
' '
in
pair
:
name
,
version
=
pair
.
split
(
' '
,
2
)
result
.
append
({
'name'
:
name
,
'version'
:
version
})
else
:
result
.
append
({
'name'
:
pair
})
return
result
def
_format_requirements
(
self
,
requirements
):
# type: (List[str]) -> dict
requires
=
{}
requirements
=
self
.
_parse_name_version_pairs
(
requirements
)
for
requirement
in
requirements
:
requires
[
requirement
[
'name'
]]
=
requirement
[
'version'
]
return
requires
poetry/console/commands/init.py
0 → 100644
View file @
4113773a
This diff is collapsed.
Click to expand it.
poetry/console/commands/new.py
View file @
4113773a
from
poetry.utils._compat
import
Path
from
.command
import
Command
...
...
@@ -14,6 +12,8 @@ class NewCommand(Command):
def
handle
(
self
):
from
poetry.layouts
import
layout
from
poetry.utils._compat
import
Path
from
poetry.vcs.git
import
GitConfig
layout_
=
layout
(
'standard'
)
...
...
@@ -34,7 +34,15 @@ class NewCommand(Command):
readme_format
=
'rst'
layout_
=
layout_
(
name
,
'0.1.0'
,
readme_format
=
readme_format
)
config
=
GitConfig
()
author
=
None
if
config
.
get
(
'user.name'
):
author
=
config
[
'user.name'
]
author_email
=
config
.
get
(
'user.email'
)
if
author_email
:
author
+=
' <{}>'
.
format
(
author_email
)
layout_
=
layout_
(
name
,
'0.1.0'
,
author
=
author
,
readme_format
=
readme_format
)
layout_
.
create
(
path
)
self
.
line
(
...
...
poetry/console/styles/poetry.py
View file @
4113773a
...
...
@@ -9,7 +9,7 @@ class PoetryStyle(CleoStyle):
self
.
output
.
get_formatter
()
.
add_style
(
'error'
,
'red'
)
self
.
output
.
get_formatter
()
.
add_style
(
'warning'
,
'yellow'
)
self
.
output
.
get_formatter
()
.
add_style
(
'question'
,
'
blue
'
)
self
.
output
.
get_formatter
()
.
add_style
(
'question'
,
'
cyan
'
)
self
.
output
.
get_formatter
()
.
add_style
(
'comment'
,
'blue'
)
def
writeln
(
self
,
messages
,
...
...
poetry/layouts/layout.py
View file @
4113773a
from
poetry.toml
import
dumps
from
poetry.toml
import
loads
from
poetry.utils.helpers
import
module_name
from
poetry.vcs.git
import
Git
TESTS_DEFAULT
=
u"""from {package_name} import __version__
...
...
@@ -20,45 +19,52 @@ description = ""
authors = []
[tool.poetry.dependencies]
python = "*"
[tool.poetry.dev-dependencies]
pytest = "^3.5"
"""
POETRY_WITH_LICENSE
=
"""
\
[tool.poetry]
name = ""
version = ""
description = ""
authors = []
license = ""
[tool.poetry.dependencies]
[tool.poetry.dev-dependencies]
"""
class
Layout
(
object
):
def
__init__
(
self
,
project
,
version
=
'0.1.0'
,
readme_format
=
'md'
,
author
=
None
):
def
__init__
(
self
,
project
,
version
=
'0.1.0'
,
description
=
''
,
readme_format
=
'md'
,
author
=
None
,
license
=
None
,
python
=
'*'
,
dependencies
=
None
,
dev_dependencies
=
None
):
self
.
_project
=
project
self
.
_package_name
=
module_name
(
project
)
self
.
_version
=
version
self
.
_description
=
description
self
.
_readme_format
=
readme_format
self
.
_dependencies
=
{}
self
.
_dev_dependencies
=
{}
self
.
_include
=
[]
self
.
_license
=
license
self
.
_python
=
python
self
.
_dependencies
=
dependencies
or
{}
self
.
_dev_dependencies
=
dev_dependencies
or
{
'pytest'
:
'^3.5'
}
self
.
_git
=
Git
()
git_config
=
self
.
_git
.
config
if
not
author
:
if
(
git_config
.
get
(
'user.name'
)
and
git_config
.
get
(
'user.email'
)
):
author
=
u'{} <{}>'
.
format
(
git_config
[
'user.name'
],
git_config
[
'user.email'
]
)
else
:
author
=
'Your Name <you@example.com>'
author
=
'Your Name <you@example.com>'
self
.
_author
=
author
def
create
(
self
,
path
,
with_tests
=
True
):
self
.
_dependencies
=
{}
self
.
_dev_dependencies
=
{}
self
.
_include
=
[]
path
.
mkdir
(
parents
=
True
,
exist_ok
=
True
)
self
.
_create_default
(
path
)
...
...
@@ -69,6 +75,30 @@ class Layout(object):
self
.
_write_poetry
(
path
)
def
generate_poetry_content
(
self
):
template
=
POETRY_DEFAULT
if
self
.
_license
:
template
=
POETRY_WITH_LICENSE
content
=
loads
(
template
)
poetry_content
=
content
[
'tool'
][
'poetry'
]
poetry_content
[
'name'
]
=
self
.
_project
poetry_content
[
'version'
]
=
self
.
_version
poetry_content
[
'description'
]
=
self
.
_description
poetry_content
[
'authors'
]
.
append
(
self
.
_author
)
if
self
.
_license
:
poetry_content
[
'license'
]
=
self
.
_license
poetry_content
[
'dependencies'
][
'python'
]
=
self
.
_python
for
dep_name
,
dep_constraint
in
self
.
_dependencies
.
items
():
poetry_content
[
'dependencies'
][
dep_name
]
=
dep_constraint
for
dep_name
,
dep_constraint
in
self
.
_dev_dependencies
.
items
():
poetry_content
[
'dev-dependencies'
][
dep_name
]
=
dep_constraint
return
dumps
(
content
)
def
_create_default
(
self
,
path
,
src
=
True
):
raise
NotImplementedError
()
...
...
@@ -99,13 +129,9 @@ class Layout(object):
)
def
_write_poetry
(
self
,
path
):
content
=
loads
(
POETRY_DEFAULT
)
poetry_content
=
content
[
'tool'
][
'poetry'
]
poetry_content
[
'name'
]
=
self
.
_project
poetry_content
[
'version'
]
=
self
.
_version
poetry_content
[
'authors'
]
.
append
(
self
.
_author
)
content
=
self
.
generate_poetry_content
()
poetry
=
path
/
'pyproject.toml'
with
poetry
.
open
(
'w'
)
as
f
:
f
.
write
(
dumps
(
content
)
)
f
.
write
(
content
)
poetry/repositories/repository.py
View file @
4113773a
...
...
@@ -80,5 +80,14 @@ class Repository(BaseRepository):
if
index
is
not
None
:
del
self
.
_packages
[
index
]
def
search
(
self
,
query
,
mode
=
0
):
results
=
[]
for
package
in
self
.
packages
:
if
query
in
package
.
name
:
results
.
append
(
package
)
return
results
def
__len__
(
self
):
return
len
(
self
.
_packages
)
poetry/vcs/git.py
View file @
4113773a
...
...
@@ -9,17 +9,20 @@ from poetry.utils._compat import decode
class
GitConfig
:
def
__init__
(
self
):
config_list
=
decode
(
subprocess
.
check_output
(
[
'git'
,
'config'
,
'-l'
],
stderr
=
subprocess
.
STDOUT
))
self
.
_config
=
{}
m
=
re
.
findall
(
'(?ms)^([^=]+)=(.*?)$'
,
config_list
)
if
m
:
for
group
in
m
:
self
.
_config
[
group
[
0
]]
=
group
[
1
]
try
:
config_list
=
decode
(
subprocess
.
check_output
(
[
'git'
,
'config'
,
'-l'
],
stderr
=
subprocess
.
STDOUT
))
m
=
re
.
findall
(
'(?ms)^([^=]+)=(.*?)$'
,
config_list
)
if
m
:
for
group
in
m
:
self
.
_config
[
group
[
0
]]
=
group
[
1
]
except
subprocess
.
CalledProcessError
:
pass
def
get
(
self
,
key
,
default
=
None
):
return
self
.
_config
.
get
(
key
,
default
)
...
...
pyproject.toml
View file @
4113773a
...
...
@@ -23,7 +23,7 @@ classifiers = [
# Requirements
[tool.poetry.dependencies]
python
=
"~2.7 || ^3.4"
cleo
=
"^0.6"
cleo
=
"^0.6
.6
"
requests
=
"^2.18"
toml
=
"^0.9"
cachy
=
"^0.2"
...
...
tests/console/commands/test_init.py
0 → 100644
View file @
4113773a
import
pytest
import
shutil
import
tempfile
from
cleo.testers
import
CommandTester
from
poetry.utils._compat
import
Path
from
tests.helpers
import
get_package
@pytest.fixture
def
tmp_dir
():
dir_
=
tempfile
.
mkdtemp
(
prefix
=
'poetry_'
)
yield
dir_
shutil
.
rmtree
(
dir_
)
def
test_basic_interactive
(
app
,
mocker
):
command
=
app
.
find
(
'init'
)
mocker
.
patch
(
'poetry.utils._compat.Path.open'
)
p
=
mocker
.
patch
(
'poetry.utils._compat.Path.cwd'
)
p
.
return_value
=
Path
(
__file__
)
tester
=
CommandTester
(
command
)
tester
.
set_inputs
([
'my-package'
,
# Package name
'1.2.3'
,
# Version
'This is a description'
,
# Description
'n'
,
# Author
'MIT'
,
# License
'~2.7 || ^3.6'
,
# Python
'n'
,
# Interactive packages
'n'
,
# Interactive dev packages
'
\n
'
# Generate
])
tester
.
execute
([(
'command'
,
command
.
name
)])
output
=
tester
.
get_display
()
expected
=
"""
\
[tool.poetry]
name = "my-package"
version = "1.2.3"
description = "This is a description"
authors = ["Your Name <you@example.com>"]
license = "MIT"
[tool.poetry.dependencies]
python = "~2.7 || ^3.6"
[tool.poetry.dev-dependencies]
pytest = "^3.5"
"""
assert
expected
in
output
def
test_interactive_with_dependencies
(
app
,
repo
,
mocker
):
repo
.
add_package
(
get_package
(
'pendulum'
,
'2.0.0'
))
command
=
app
.
find
(
'init'
)
mocker
.
patch
(
'poetry.utils._compat.Path.open'
)
p
=
mocker
.
patch
(
'poetry.utils._compat.Path.cwd'
)
p
.
return_value
=
Path
(
__file__
)
.
parent
tester
=
CommandTester
(
command
)
tester
.
set_inputs
([
'my-package'
,
# Package name
'1.2.3'
,
# Version
'This is a description'
,
# Description
'n'
,
# Author
'MIT'
,
# License
'~2.7 || ^3.6'
,
# Python
''
,
# Interactive packages
'pendulum'
,
# Search for package
'0'
,
# First option
''
,
# Do not set constraint
''
,
# Stop searching for packages
'n'
,
# Interactive dev packages
'
\n
'
# Generate
])
tester
.
execute
([(
'command'
,
command
.
name
)])
output
=
tester
.
get_display
()
expected
=
"""
\
[tool.poetry]
name = "my-package"
version = "1.2.3"
description = "This is a description"
authors = ["Your Name <you@example.com>"]
license = "MIT"
[tool.poetry.dependencies]
python = "~2.7 || ^3.6"
pendulum = "^2.0"
[tool.poetry.dev-dependencies]
pytest = "^3.5"
"""
print
(
output
)
assert
expected
in
output
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