pdm icon indicating copy to clipboard operation
pdm copied to clipboard

OS Specific Scripts

Open ameily opened this issue 1 year ago • 5 comments

Is your feature/enhancement proposal related to a problem? Please describe.

I have a Python project that runs on both Windows and Linux. I have a lint PDM script that runs pylint. The problem is that I need to ignore Windows-specific source files when running on Linux and ignore Linux-specific source files when running on Windows. I have what I consider a HACK that works:

[tool.pdm.scripts]
# This is ugly but runs the correct lint command based on the OS. This check works on both Windows
# and Linux
lint = {shell = "(python -c \"import sys;import platform;sys.exit(1 if any(platform.win32_ver()) else 0)\" && {pdm} run lint-linux) || {pdm} run lint-windows" }

lint-windows = "pylint --ignore '[LINUX_SPECIFIC_SOURCE_FILES]' my_project"
lint-linux = "pylint --ignore '[WINDOWS_SPECIFIC_SOURCE_FILES]' my_project"

Describe the solution you'd like

I assume there's a better way to do what I need. If not, I think a new script type that selects the script to run based on the OS. Something like:

[tool.pdm.scripts]
lint = { os_match = { win32 = "lint-windows", linux = "lint-linux" } }

lint-windows = "pylint --ignore '[LINUX_SPECIFIC_SOURCE_FILES]' my_project"
lint-linux = "pylint --ignore '[WINDOWS_SPECIFIC_SOURCE_FILES]' my_project"

Looking at TaskRunner.run_task, I think we would add a new kind that behaves something like:

if kind == "os_match":
    assert isinstance(value, dict)
    if sys.platform.startswith("linux") and "linux" in value:
        # generic linux
        script = value["linux"]
    else:
        # match the platform exactly
        script = value[sys.platform]
    
    self.run(...)

ameily avatar Apr 24 '24 14:04 ameily

That's IMO better solved with a Python wrapper script that builds the ignore flag value and calls pylint. The main reason being: to avoid scope-creep in PDM :)

pawamoy avatar Apr 24 '24 15:04 pawamoy

That makes sense. For context, I'm migrating from poetry and was using the poe task runner, which has a switch/case task for selecting the command to run based on some predicate. If that's outside the scope of PDM I understand, although I do think it would have value for cross-platform projects. Looking at the PDM code, I think its something I could add and make a PR for. Otherwise I'll take your advice and make a small Python wrapper.

ameily avatar Apr 24 '24 18:04 ameily

I'm just a passer-by, @frostming gets the last word :smile:

Maybe that's achievable through a PDM plugin by the way?

pawamoy avatar Apr 24 '24 18:04 pawamoy

IMHO your solution only solves a very specific need (what if I want Python version specific scripts?), and makes the configuration very complicated, which is not worth it.

Good to learn poe supported such a complex configuration to specify conditions, which is impressing. But PDM won't follow this path. If it were up to me I'd consider a Makefile, or a Python script wrapper.

frostming avatar Apr 25 '24 01:04 frostming

I agree with all of the responses. You will have the best results creating a pylint wrapper script and tossing it in your /scripts top level folder in your repo, then calling that script.

[tool.pdm.scripts]
lint = "scripts/run-pylint.py [--args] DIR"

SealedServant avatar Apr 26 '24 00:04 SealedServant