Add CLI add argument
This commit is contained in:
parent
54bed5b64c
commit
1b6a69a598
@ -6,7 +6,7 @@ A python lib came from [Difficult Rocket](https://github.com/shenjackyuanjie/Dif
|
||||
|
||||
## Information/信息
|
||||
|
||||
- Version / 版本: 0.2.0-beta.0
|
||||
- Version / 版本: 0.2.0-beta.3
|
||||
- Author / 作者: shenjackyuanjie <3695888@qq.com>
|
||||
|
||||
> [shenjackyuanjie](https://github.com/shenjackyuanjie)
|
||||
@ -61,7 +61,14 @@ logger.trace('so this message will be in the same line', tag='same line!')
|
||||
[tool.lndl.nuitka]
|
||||
main = "main.py"
|
||||
# --main=main.py
|
||||
standalone = true
|
||||
onefile = false
|
||||
```
|
||||
|
||||
```bash
|
||||
lndl-nuitka .
|
||||
lndl-nuitka . -- --onefile
|
||||
# add --onefile to nuitka
|
||||
```
|
||||
|
||||
### Nuitka Compiler Helper
|
||||
|
@ -1,5 +1,13 @@
|
||||
# Change log / 更新日志
|
||||
|
||||
## 0.2.0-beta.2
|
||||
|
||||
### lndl-nuitka
|
||||
|
||||
- 可以使用 `--` 单独添加参数了
|
||||
- 例如 `lndl-nuitka -- --onefile`
|
||||
- 会将 `--onefile` 添加到 `nuitka` 的参数中
|
||||
|
||||
## 0.2.0-beta.0/1
|
||||
|
||||
### 重构
|
||||
|
@ -65,3 +65,9 @@ line-length = 150
|
||||
src = [
|
||||
"src",
|
||||
]
|
||||
|
||||
[tool.lndl.nuitka]
|
||||
main = "test-only.py"
|
||||
onefile = false
|
||||
standalone = true
|
||||
|
||||
|
@ -4,7 +4,17 @@
|
||||
# All rights reserved
|
||||
# -------------------------------
|
||||
|
||||
__version__ = '0.2.0-beta.2'
|
||||
__version__ = '0.2.0-beta.3'
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from lib_not_dr import (
|
||||
logger,
|
||||
nuitka,
|
||||
types,
|
||||
command
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
'__version__',
|
||||
|
@ -8,7 +8,11 @@ import time
|
||||
import subprocess
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Iterable
|
||||
from typing import Dict, Union, List
|
||||
|
||||
from lib_not_dr.nuitka.reader.arg_parser import pyproject_toml, toml_path_cli, gen_subprocess_args
|
||||
|
||||
support_config_dict = Dict[str, Union[str, bool, List[Union[str, tuple]]]]
|
||||
|
||||
USEAGE = """
|
||||
usage:
|
||||
@ -60,8 +64,8 @@ TOML_READERS = (
|
||||
def get_toml_reader():
|
||||
for module_name in TOML_READERS:
|
||||
try:
|
||||
toml_loads = __import__(module_name).loads
|
||||
return toml_loads
|
||||
loaded = __import__(module_name).loads
|
||||
return loaded
|
||||
except ImportError:
|
||||
continue
|
||||
error_msg = """No toml reader found, please install any below by pip:
|
||||
@ -75,91 +79,54 @@ def get_toml_reader():
|
||||
toml_loads = get_toml_reader()
|
||||
|
||||
|
||||
def validate_toml(toml_data: dict, file_name: Path) -> dict:
|
||||
if "tool" not in toml_data:
|
||||
raise ValueError(f"No tool section in {file_name}")
|
||||
|
||||
if "lndl" not in toml_data["tool"]:
|
||||
raise ValueError(f"No lib-not-dr(lndl) section in {file_name}")
|
||||
|
||||
if "nuitka" not in toml_data["tool"]["lndl"]:
|
||||
raise ValueError(f"No lib-not-dr(lndl).nuitka section in {file_name}")
|
||||
|
||||
nuitka_config = toml_data["tool"]["lndl"]["nuitka"]
|
||||
|
||||
if "main" not in nuitka_config:
|
||||
raise ValueError(
|
||||
"'main' not define in lib-not-dr(lndl).nuitka section\ndefine it with 'main = [<main.py>]'"
|
||||
)
|
||||
|
||||
return nuitka_config
|
||||
def display_config(subprocess_command: list) -> None:
|
||||
print(f"The config is:\n\033[34m{subprocess_command} \033[0m")
|
||||
print("shell command is:\n\033[34m", end="")
|
||||
print(" ".join(subprocess_command), '\033[0m')
|
||||
print(f"Working Dir: \033[32m {Path().cwd().absolute()} \033[0m")
|
||||
|
||||
|
||||
def gen_subprocess_args(nuitka_config: dict) -> list:
|
||||
cmd_list = [sys.executable, "-m", "nuitka"]
|
||||
|
||||
for name, value in nuitka_config.items():
|
||||
if value is True:
|
||||
# --<name>
|
||||
cmd_list.append(f"--{name}")
|
||||
continue
|
||||
elif isinstance(value, str):
|
||||
# --<name>=<value>
|
||||
cmd_list.append(f"--{name}={value}")
|
||||
continue
|
||||
elif isinstance(value, Iterable):
|
||||
# --<name>=<value1>,<value2>,...
|
||||
cmd_list.append(f"--{name}={','.join(value)}")
|
||||
continue
|
||||
|
||||
return cmd_list
|
||||
|
||||
|
||||
def get_toml() -> Path:
|
||||
if len(sys.argv) < 2:
|
||||
raw_path = Path().cwd()
|
||||
else:
|
||||
raw_path = Path(sys.argv[1])
|
||||
if raw_path.is_file():
|
||||
return raw_path
|
||||
|
||||
elif raw_path.is_dir():
|
||||
if (raw_path / "pyproject.toml").exists():
|
||||
return raw_path / "pyproject.toml"
|
||||
else:
|
||||
raise FileNotFoundError(f"pyproject.toml not found in {raw_path}")
|
||||
else:
|
||||
raise FileNotFoundError(f"{raw_path} not found")
|
||||
|
||||
|
||||
def main():
|
||||
toml_file = get_toml()
|
||||
|
||||
with open(toml_file, "r", encoding="utf-8") as f:
|
||||
toml = toml_loads(f.read())
|
||||
|
||||
nuitka_config = validate_toml(toml, toml_file)
|
||||
|
||||
subprocess_command = gen_subprocess_args(nuitka_config)
|
||||
|
||||
# printed in blue text
|
||||
# \033[34m is the escape code for blue text
|
||||
print(f"\033[34mRunning: {subprocess_command}\033[0m")
|
||||
print(f"Working Dir: {Path().cwd()}")
|
||||
|
||||
def run_nuitka(subprocess_command: list) -> None:
|
||||
start_time = time.time()
|
||||
subprocess.run(subprocess_command, shell=True)
|
||||
end_time = time.time()
|
||||
|
||||
print(f"Time Elapsed: {end_time - start_time} seconds")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
def main(config: support_config_dict) -> None:
|
||||
"""
|
||||
enter point for python direct call
|
||||
:param config: nuitka config dict
|
||||
:return: None
|
||||
"""
|
||||
subprocess_command = gen_subprocess_args(config)
|
||||
display_config(subprocess_command)
|
||||
run_nuitka(subprocess_command)
|
||||
|
||||
|
||||
def cli_main() -> None:
|
||||
"""
|
||||
entering point of cli
|
||||
:return: None
|
||||
"""
|
||||
if "--help" in sys.argv or "-h" in sys.argv:
|
||||
print(USEAGE)
|
||||
sys.exit(0)
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print(USEAGE)
|
||||
if input("are you sure to run? (y/n)") not in ["y", "Y", "yes", "Yes"]:
|
||||
sys.exit(0)
|
||||
main()
|
||||
|
||||
toml_file = toml_path_cli()
|
||||
|
||||
with open(toml_file, "r", encoding="utf-8") as f:
|
||||
toml = toml_loads(f.read())
|
||||
|
||||
nuitka_config = pyproject_toml(toml)
|
||||
|
||||
subprocess_command = gen_subprocess_args(nuitka_config)
|
||||
display_config(subprocess_command)
|
||||
if input("are you sure to run? (y/n)") not in ["y", "Y", "yes", "Yes"]:
|
||||
sys.exit(0)
|
||||
run_nuitka(subprocess_command)
|
168
src/lib_not_dr/nuitka/reader/arg_parser.py
Normal file
168
src/lib_not_dr/nuitka/reader/arg_parser.py
Normal file
@ -0,0 +1,168 @@
|
||||
# -------------------------------
|
||||
# Difficult Rocket
|
||||
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
||||
# All rights reserved
|
||||
# -------------------------------
|
||||
|
||||
import sys
|
||||
|
||||
from pathlib import Path
|
||||
from warnings import warn
|
||||
from typing import Iterable, Dict, Union, List
|
||||
|
||||
|
||||
def pyproject_toml(toml_data: dict) -> dict:
|
||||
"""
|
||||
:param toml_data: dict (from pyproject/ raw dict)
|
||||
:return: dict
|
||||
"""
|
||||
if "tool" not in toml_data:
|
||||
raise ValueError(f"No tool section in config file/dict")
|
||||
|
||||
if "lndl" not in toml_data["tool"]:
|
||||
raise ValueError(f"No lib-not-dr(lndl) section in config file/dict")
|
||||
|
||||
if "nuitka" not in toml_data["tool"]["lndl"]:
|
||||
raise ValueError(f"No lib-not-dr(lndl).nuitka section in config file/dict")
|
||||
|
||||
nuitka_config = toml_data["tool"]["lndl"]["nuitka"]
|
||||
|
||||
if "main" not in nuitka_config:
|
||||
raise ValueError(
|
||||
"'main' not define in lib-not-dr(lndl).nuitka section\ndefine it with 'main = [<main.py>]'"
|
||||
)
|
||||
|
||||
return nuitka_config
|
||||
|
||||
|
||||
def toml_path_cli() -> Path:
|
||||
"""
|
||||
get toml path from cli args
|
||||
:return: Path
|
||||
"""
|
||||
if len(sys.argv) < 2:
|
||||
raw_path = Path().cwd()
|
||||
else:
|
||||
raw_path = Path(sys.argv[1])
|
||||
if raw_path.is_file():
|
||||
return raw_path
|
||||
|
||||
elif raw_path.is_dir():
|
||||
if (raw_path / "pyproject.toml").exists():
|
||||
return raw_path / "pyproject.toml"
|
||||
else:
|
||||
raise FileNotFoundError(f"pyproject.toml not found in {raw_path}")
|
||||
else:
|
||||
raise FileNotFoundError(f"{raw_path} not found")
|
||||
|
||||
|
||||
def get_cli_nuitka_args() -> dict:
|
||||
"""
|
||||
get -- from sys.argv
|
||||
:return: list
|
||||
"""
|
||||
# no -- in sys.argv
|
||||
if len(sys.argv) < 2:
|
||||
return {}
|
||||
if '--' not in sys.argv:
|
||||
print(f"invalid args: {sys.argv}")
|
||||
return {}
|
||||
|
||||
# start from --
|
||||
index = sys.argv.index('--')
|
||||
new_args = sys.argv[index + 1:]
|
||||
arg_dict = {}
|
||||
for arg in new_args:
|
||||
if not arg.startswith('--'):
|
||||
warn(f"invalid arg: {arg}")
|
||||
else:
|
||||
arg = arg[2:] # remove --
|
||||
# arg_name: --<name>=<value>
|
||||
arg_name = arg.split('=')[0]
|
||||
if '=' in arg:
|
||||
arg_value = arg.split('=')[1]
|
||||
else:
|
||||
arg_value = True
|
||||
arg_dict[arg_name] = arg_value
|
||||
|
||||
print(f"cli config: {arg_dict}")
|
||||
return arg_dict
|
||||
|
||||
|
||||
def merge_cli_config(toml_config: dict, cli_config: dict) -> dict:
|
||||
"""
|
||||
merge toml config and cli config
|
||||
:param toml_config:
|
||||
:param cli_config:
|
||||
:return:
|
||||
"""
|
||||
for name, value in cli_config.items():
|
||||
if name in toml_config:
|
||||
warn(f"\033[33mcli config will overwrite toml config\n{name}:{toml_config[name]} -> {value}\033[0m")
|
||||
if isinstance(toml_config[name], bool):
|
||||
if not isinstance(value, bool):
|
||||
warn(f"cli config {name} is bool but toml config is not\n{value} -> {value}")
|
||||
continue
|
||||
toml_config[name] = value
|
||||
elif isinstance(toml_config[name], str):
|
||||
if not isinstance(value, str):
|
||||
warn(f"cli config {name} is str but toml config is not\n{value} -> {value}")
|
||||
continue
|
||||
toml_config[name] = value
|
||||
elif isinstance(toml_config[name], Iterable):
|
||||
if not isinstance(value, str):
|
||||
warn(f"cli config {name} is Iterable but toml config is not\n{value} -> {value}")
|
||||
continue
|
||||
toml_config[name].append(value)
|
||||
else:
|
||||
toml_config[name] = value
|
||||
return toml_config
|
||||
|
||||
|
||||
def gen_subprocess_args(nuitka_config:
|
||||
Dict[str, Union[str, bool, List[Union[str, tuple]]]]) -> list:
|
||||
cmd_list = [sys.executable, "-m", "nuitka"]
|
||||
|
||||
nuitka_config = merge_cli_config(nuitka_config, get_cli_nuitka_args())
|
||||
|
||||
def parse_value(arg_name, arg_value) -> list:
|
||||
if isinstance(value, bool):
|
||||
warn(f"bool value is not supported in list config {arg_name}")
|
||||
return []
|
||||
elif isinstance(value, str):
|
||||
return [f"--{arg_name}={arg_value}"]
|
||||
else:
|
||||
return [f"--{arg_name}={arg_value[0]}={arg_value[1]}"]
|
||||
|
||||
for name, value in nuitka_config.items():
|
||||
if value is True:
|
||||
# --<name>
|
||||
cmd_list.append(f"--{name}")
|
||||
continue
|
||||
elif isinstance(value, str):
|
||||
# --<name>=<value>
|
||||
cmd_list.append(f"--{name}={value}")
|
||||
continue
|
||||
elif isinstance(value, Iterable):
|
||||
if '__spilt__' in value:
|
||||
# --<name>=<value1> --<name>=<value2> ...
|
||||
for item in value:
|
||||
if item == '__spilt__':
|
||||
continue
|
||||
cmd_list += parse_value(name, item)
|
||||
continue
|
||||
if all(isinstance(item, str) for item in value):
|
||||
# --<name>=<value1>,<value2>,...
|
||||
cmd_list.append(f"--{name}={','.join(value)}")
|
||||
elif all(isinstance(item, (tuple, list)) for item in value):
|
||||
# --<name>=<value1>=<value2>
|
||||
# --<name>=<value3>=<value4>,...
|
||||
for item in value:
|
||||
cmd_list.append(f"--{name}={item[0]}={item[1]}")
|
||||
else:
|
||||
# 处理混杂的情况
|
||||
for item in value:
|
||||
cmd_list += parse_value(name, item)
|
||||
continue
|
||||
|
||||
return cmd_list
|
@ -4,9 +4,9 @@
|
||||
# All rights reserved
|
||||
# -------------------------------
|
||||
|
||||
from lib_not_dr.nuitka.parse import main
|
||||
from lib_not_dr.nuitka.reader import cli_main
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
cli_main()
|
||||
|
||||
main = main
|
||||
main = cli_main
|
||||
|
Loading…
Reference in New Issue
Block a user