Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
后端镜像
Pdm
提交
f8f93cea
P
Pdm
项目概览
后端镜像
/
Pdm
通知
0
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Pdm
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
f8f93cea
编写于
11月 24, 2020
作者:
F
Frost Ming
提交者:
GitHub
11月 24, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #179 from frostming/feature/dot-env
Support dotenv file loading
上级
0251e18b
efe62a56
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
91 addition
and
9 deletion
+91
-9
docs/docs/project.md
docs/docs/project.md
+12
-0
news/178.feature
news/178.feature
+3
-0
pdm.lock
pdm.lock
+12
-1
pdm/cli/commands/run.py
pdm/cli/commands/run.py
+34
-8
pyproject.toml
pyproject.toml
+1
-0
tests/cli/test_run.py
tests/cli/test_run.py
+29
-0
未找到文件。
docs/docs/project.md
浏览文件 @
f8f93cea
...
...
@@ -251,6 +251,18 @@ start_server.env = {FOO = "bar", FLASK_ENV = "development"}
Note how we use
[
TOML's syntax
](
https://github.com/toml-lang/toml
)
to define a compound dictionary.
A dotenv file is also supported via
`env_file = "<file_path>"`
setting.
For environment variables and/or dotenv file shared by all scripts, you can define
`env`
and
`env_file`
settings under a special key named
`_`
of
`tool.pdm.scripts`
table:
```
toml
[tool.pdm.scripts]
_.env_file
=
".env"
start_server
=
"flask run -p 54321"
migrate_db
=
"flask db upgrade"
```
### Show the list of scripts shortcuts
Use
`pdm run --list/-l`
to show the list of available script shortcuts:
...
...
news/178.feature
0 → 100644
浏览文件 @
f8f93cea
Improve the user experience of `pdm run`
:
-
Add
a
special key in tool.pdm.scripts that holds configurations shared by all scripts.
-
Support
loading
env
var
from
a
dot-env file.
pdm.lock
浏览文件 @
f8f93cea
...
...
@@ -400,6 +400,12 @@ summary = "Sexy fonts for the console"
[package.dependencies]
colorama = "*"
[[package]]
name = "python-dotenv"
sections = ["default"]
version = "0.15.0"
summary = "Add .env support to your django/flask apps in development and deployments"
[[package]]
name = "pythonfinder"
sections = ["default"]
...
...
@@ -775,6 +781,10 @@ summary = "Backport of pathlib-compatible object wrapper for zip files"
{file = "python_cfonts-1.3.1-py2.py3-none-any.whl", hash = "sha256:8329e38f393f7e9cbd8c1c905c9fd8645bf0837348114a281639d619e0a0f4e2"},
{file = "python-cfonts-1.3.1.tar.gz", hash = "sha256:50d9e3153034d7e27e74c3c62009275ff0fe0d54d8cd3d283e7f014a9d830d43"},
]
"python-dotenv 0.15.0" = [
{file = "python_dotenv-0.15.0-py2.py3-none-any.whl", hash = "sha256:0c8d1b80d1a1e91717ea7d526178e3882732420b03f08afea0406db6402e220e"},
{file = "python-dotenv-0.15.0.tar.gz", hash = "sha256:587825ed60b1711daea4832cf37524dfd404325b7db5e25ebe88c495c9f807a0"},
]
"pythonfinder 1.2.5" = [
{file = "pythonfinder-1.2.5-py2.py3-none-any.whl", hash = "sha256:b1bd693bcd6fb142d85d395ec2dad5e1791fb16b0fe29616b9395c8c72a69752"},
{file = "pythonfinder-1.2.5.tar.gz", hash = "sha256:481fba9cb7ffa43fe5b5b5c4c5cbcec565a79762e24daff65043158a93fc1986"},
...
...
@@ -931,4 +941,5 @@ summary = "Backport of pathlib-compatible object wrapper for zip files"
[root]
meta_version = "0.0.1"
content_hash = "md5:5307e1dc97bc1df4e9488bc372f767a8"
content_hash = "md5:320ab920bc7cee68a94fd078fda5541f"
pdm/cli/commands/run.py
浏览文件 @
f8f93cea
...
...
@@ -5,7 +5,7 @@ import re
import
shlex
import
subprocess
import
sys
from
typing
import
List
,
Union
from
typing
import
Dict
,
List
,
Optional
,
Union
from
pdm.cli.commands.base
import
BaseCommand
from
pdm.exceptions
import
PdmUsageError
...
...
@@ -17,7 +17,7 @@ from pdm.utils import find_project_root
class
Command
(
BaseCommand
):
"""Run commands or scripts with local packages loaded"""
OPTIONS
=
[
"env"
,
"help"
]
OPTIONS
=
[
"env"
,
"
env_file"
,
"
help"
]
TYPES
=
[
"cmd"
,
"shell"
,
"call"
]
def
add_arguments
(
self
,
parser
:
argparse
.
ArgumentParser
)
->
None
:
...
...
@@ -38,10 +38,18 @@ class Command(BaseCommand):
def
_run_command
(
project
:
Project
,
args
:
Union
[
List
[
str
],
str
],
shell
=
False
,
env
=
None
,
shell
:
bool
=
False
,
env
:
Optional
[
Dict
[
str
,
str
]]
=
None
,
env_file
:
Optional
[
str
]
=
None
,
)
->
None
:
with
project
.
environment
.
activate
():
if
env_file
:
import
dotenv
stream
.
echo
(
f
"Loading .env file:
{
stream
.
green
(
env_file
)
}
"
,
err
=
True
)
dotenv
.
load_dotenv
(
project
.
root
.
joinpath
(
env_file
).
as_posix
(),
override
=
True
)
if
env
:
os
.
environ
.
update
(
env
)
if
shell
:
...
...
@@ -90,7 +98,13 @@ class Command(BaseCommand):
)
return
kind
,
value
,
options
def
_run_script
(
self
,
project
:
Project
,
script_name
:
str
,
args
:
List
[
str
])
->
None
:
def
_run_script
(
self
,
project
:
Project
,
script_name
:
str
,
args
:
List
[
str
],
global_env_options
:
Dict
[
str
,
Union
[
str
,
Dict
[
str
,
str
]]],
)
->
None
:
script
=
project
.
scripts
[
script_name
]
kind
,
value
,
options
=
self
.
_normalize_script
(
script
)
if
kind
==
"cmd"
:
...
...
@@ -113,6 +127,11 @@ class Command(BaseCommand):
f
"import sys,
{
module
}
as
{
short_name
}
;"
f
"sys.exit(
{
short_name
}
.
{
func
}
)"
,
]
+
args
if
"env"
in
global_env_options
:
options
[
"env"
]
=
{
**
global_env_options
[
"env"
],
**
options
.
get
(
"env"
,
{})}
options
[
"env_file"
]
=
options
.
get
(
"env_file"
,
global_env_options
.
get
(
"env_file"
)
)
stream
.
echo
(
f
"Running
{
kind
}
script:
{
stream
.
green
(
str
(
args
))
}
"
,
err
=
True
)
return
self
.
_run_command
(
project
,
args
,
**
options
)
...
...
@@ -129,14 +148,21 @@ class Command(BaseCommand):
def
handle
(
self
,
project
:
Project
,
options
:
argparse
.
Namespace
)
->
None
:
if
options
.
list
:
return
self
.
_show_list
(
project
)
global_env_options
=
project
.
scripts
.
get
(
"_"
,
{})
if
project
.
scripts
else
{}
if
project
.
scripts
and
options
.
command
in
project
.
scripts
:
self
.
_run_script
(
project
,
options
.
command
,
options
.
args
)
self
.
_run_script
(
project
,
options
.
command
,
options
.
args
,
global_env_options
)
elif
os
.
path
.
isfile
(
options
.
command
)
and
options
.
command
.
endswith
(
".py"
):
# Allow executing py scripts like `pdm run my_script.py`.
# In this case, the nearest `__pypackages__` will be loaded as
# the library source.
new_root
=
find_project_root
(
os
.
path
.
abspath
(
options
.
command
))
project
=
Project
(
new_root
)
if
new_root
else
project
self
.
_run_command
(
project
,
[
"python"
,
options
.
command
]
+
options
.
args
)
self
.
_run_command
(
project
,
[
"python"
,
options
.
command
]
+
options
.
args
,
**
global_env_options
,
)
else
:
self
.
_run_command
(
project
,
[
options
.
command
]
+
options
.
args
)
self
.
_run_command
(
project
,
[
options
.
command
]
+
options
.
args
,
**
global_env_options
)
pyproject.toml
浏览文件 @
f8f93cea
...
...
@@ -38,6 +38,7 @@ pdm-pep517 = "<1.0.0,>=0.1.0"
importlib-metadata
=
{
version
=
"*"
,
marker
=
"python_version<'3.8'"
}
pep517
=
"*"
pycomplete
=
"<1.0.0,>=0.2.0"
python-dotenv
=
"<1.0.0,>=0.15.0"
[tool.pdm.dev-dependencies]
pytest
=
"*"
...
...
tests/cli/test_run.py
浏览文件 @
f8f93cea
...
...
@@ -128,6 +128,35 @@ def test_run_script_with_env_defined(project, invoke, capfd):
assert
capfd
.
readouterr
()[
0
].
strip
()
==
"bar"
def
test_run_script_with_dotenv_file
(
project
,
invoke
,
capfd
):
(
project
.
root
/
"test_script.py"
).
write_text
(
"import os; print(os.getenv('FOO'))"
)
project
.
tool_settings
[
"scripts"
]
=
{
"test_script"
:
{
"cmd"
:
"python test_script.py"
,
"env_file"
:
".env"
}
}
project
.
write_pyproject
()
(
project
.
root
/
".env"
).
write_text
(
"FOO=bar"
)
capfd
.
readouterr
()
with
cd
(
project
.
root
):
invoke
([
"run"
,
"test_script"
],
obj
=
project
)
assert
capfd
.
readouterr
()[
0
].
strip
()
==
"bar"
def
test_run_script_override_global_env
(
project
,
invoke
,
capfd
):
(
project
.
root
/
"test_script.py"
).
write_text
(
"import os; print(os.getenv('FOO'))"
)
project
.
tool_settings
[
"scripts"
]
=
{
"_"
:
{
"env"
:
{
"FOO"
:
"bar"
}},
"test_env"
:
{
"cmd"
:
"python test_script.py"
},
"test_env_override"
:
{
"cmd"
:
"python test_script.py"
,
"env"
:
{
"FOO"
:
"foobar"
}},
}
project
.
write_pyproject
()
capfd
.
readouterr
()
with
cd
(
project
.
root
):
invoke
([
"run"
,
"test_env"
],
obj
=
project
)
assert
capfd
.
readouterr
()[
0
].
strip
()
==
"bar"
invoke
([
"run"
,
"test_env_override"
],
obj
=
project
)
assert
capfd
.
readouterr
()[
0
].
strip
()
==
"foobar"
def
test_run_show_list_of_scripts
(
project
,
invoke
):
project
.
tool_settings
[
"scripts"
]
=
{
"test_cmd"
:
"flask db upgrade"
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录