refactor(cli): 重构清屏和which命令实现
1. 提取清屏、设置环境变量、命令查找逻辑到system任务模块 2. 统一命令行工具的任务实现方式,减少重复代码 3. 修正pyproject.toml中的cli命令名拼写错误 4. 移除过时的测试用例代码
This commit is contained in:
+1
-1
@@ -25,7 +25,7 @@ version = "0.2.5"
|
||||
[project.scripts]
|
||||
autofmt = "pyflowx.cli.autofmt:main"
|
||||
bumpversion = "pyflowx.cli.bumpversion:main"
|
||||
cls = "pyflowx.cli.clearscreen:main"
|
||||
clr = "pyflowx.cli.clearscreen:main"
|
||||
emlman = "pyflowx.cli.emlmanager:main"
|
||||
envdev = "pyflowx.cli.envdev:main"
|
||||
envpy = "pyflowx.cli.envpy:main"
|
||||
|
||||
@@ -6,14 +6,10 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import pyflowx as px
|
||||
from pyflowx.conditions import Constants
|
||||
from pyflowx.tasks.system import CLR
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""清屏工具主函数."""
|
||||
graph = px.Graph.from_specs([
|
||||
px.TaskSpec("cls_win", cmd=["cmd", "/c", "cls"], conditions=(lambda: Constants.IS_WINDOWS,)),
|
||||
px.TaskSpec("cls_unix", cmd=["clear"], conditions=(lambda: not Constants.IS_WINDOWS,)),
|
||||
px.TaskSpec("cls_ascii", fn=lambda: print("\033[2J\033[H", end="")),
|
||||
])
|
||||
graph = px.Graph.from_specs([CLR()])
|
||||
px.run(graph, strategy="thread")
|
||||
|
||||
@@ -6,46 +6,16 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
import pyflowx as px
|
||||
|
||||
|
||||
def which_command(command: str) -> Path | None:
|
||||
"""查找命令路径.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
command : str
|
||||
命令名称
|
||||
|
||||
Returns
|
||||
-------
|
||||
Path | None
|
||||
命令路径, 如果未找到则返回 None
|
||||
"""
|
||||
cmd_path = shutil.which(command)
|
||||
if cmd_path:
|
||||
print(f"匹配路径: - {cmd_path}")
|
||||
return Path(cmd_path)
|
||||
else:
|
||||
print(f"{command}: 未找到")
|
||||
return None
|
||||
from pyflowx.tasks.system import WHICH
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""命令查找工具主函数."""
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Which - 命令查找工具",
|
||||
usage="which <command> [command ...]",
|
||||
)
|
||||
parser.add_argument(
|
||||
"commands",
|
||||
type=str,
|
||||
nargs="+",
|
||||
help="要查找的命令名称 (如: python pip node npm git uv rustc cargo)",
|
||||
)
|
||||
parser = argparse.ArgumentParser(description="Which - 命令查找工具")
|
||||
parser.add_argument("commands", nargs="+", help="要查找的命令名称, 如: python ls ps gcc...")
|
||||
args = parser.parse_args()
|
||||
graph = px.Graph.from_specs([px.TaskSpec(f"which_{cmd}", fn=which_command, args=(cmd,)) for cmd in args.commands])
|
||||
|
||||
graph = px.Graph.from_specs([WHICH(cmd) for cmd in args.commands])
|
||||
px.run(graph, strategy="thread")
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import pyflowx as px
|
||||
|
||||
|
||||
def CLR():
|
||||
"""清屏."""
|
||||
import subprocess
|
||||
|
||||
from pyflowx.conditions import Constants
|
||||
|
||||
return px.TaskSpec(
|
||||
"clear_screen", fn=lambda: subprocess.run(["cls"] if Constants.IS_WINDOWS else ["clear"], check=True)
|
||||
)
|
||||
|
||||
|
||||
def SETENV(name: str, value: str):
|
||||
"""设置环境变量."""
|
||||
import os
|
||||
|
||||
return px.TaskSpec("set_env", fn=lambda: os.environ.setdefault(name, value))
|
||||
|
||||
|
||||
def WHICH(cmd: str):
|
||||
"""查找命令路径."""
|
||||
import subprocess
|
||||
|
||||
def find_command() -> str | None:
|
||||
"""查找命令并返回路径, 找不到时返回 None."""
|
||||
result = subprocess.run(["which", cmd], capture_output=True, text=True, check=False)
|
||||
|
||||
if result.returncode == 0:
|
||||
path = result.stdout.strip()
|
||||
print(f"{cmd:<8} -> {path}")
|
||||
return path
|
||||
|
||||
print(f"{cmd:<8} -> 未找到命令")
|
||||
return None
|
||||
|
||||
return px.TaskSpec(f"which_{cmd}", fn=find_command)
|
||||
@@ -3,7 +3,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
@@ -12,45 +11,6 @@ import pyflowx as px
|
||||
from pyflowx.cli import which
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------- #
|
||||
# which_command
|
||||
# ---------------------------------------------------------------------- #
|
||||
class TestWhichCommand:
|
||||
"""Test which_command function."""
|
||||
|
||||
def test_returns_path_when_command_found(self, capsys: pytest.CaptureFixture[str]) -> None:
|
||||
"""Should return Path when command is found."""
|
||||
with patch.object(shutil, "which", return_value="/usr/bin/python"):
|
||||
result = which.which_command("python")
|
||||
assert result == Path("/usr/bin/python")
|
||||
captured = capsys.readouterr()
|
||||
assert "匹配路径" in captured.out
|
||||
assert "/usr/bin/python" in captured.out
|
||||
|
||||
def test_returns_none_when_command_not_found(self, capsys: pytest.CaptureFixture[str]) -> None:
|
||||
"""Should return None when command is not found."""
|
||||
with patch.object(shutil, "which", return_value=None):
|
||||
result = which.which_command("nonexistent_cmd")
|
||||
assert result is None
|
||||
captured = capsys.readouterr()
|
||||
assert "未找到" in captured.out
|
||||
assert "nonexistent_cmd" in captured.out
|
||||
|
||||
def test_prints_match_path_on_success(self, capsys: pytest.CaptureFixture[str]) -> None:
|
||||
"""Should print '匹配路径: - <path>' on success."""
|
||||
with patch.object(shutil, "which", return_value="C:\\Python\\python.exe"):
|
||||
_ = which.which_command("python")
|
||||
captured = capsys.readouterr()
|
||||
assert "匹配路径: - C:\\Python\\python.exe" in captured.out
|
||||
|
||||
def test_prints_not_found_on_failure(self, capsys: pytest.CaptureFixture[str]) -> None:
|
||||
"""Should print '<command>: 未找到' on failure."""
|
||||
with patch.object(shutil, "which", return_value=None):
|
||||
_ = which.which_command("missing")
|
||||
captured = capsys.readouterr()
|
||||
assert "missing: 未找到" in captured.out
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------- #
|
||||
# main function
|
||||
# ---------------------------------------------------------------------- #
|
||||
|
||||
Reference in New Issue
Block a user