From a8fc40a77c247040d88b748a4168b94d7d14bd7b Mon Sep 17 00:00:00 2001 From: light4 Date: Thu, 22 Jun 2023 14:37:09 +0400 Subject: [PATCH] support `pdm` or pyproject like scripts https://pdm.fming.dev/latest/usage/scripts/#call --- docs/guide/pyproject.md | 9 +++++++ rye/src/cli/run.rs | 25 +++++++++++++++++ rye/src/pyproject.rs | 59 ++++++++++++++++++++++++++++------------- 3 files changed, 75 insertions(+), 18 deletions(-) diff --git a/docs/guide/pyproject.md b/docs/guide/pyproject.md index ac1f39c6e0..64d0ca2757 100644 --- a/docs/guide/pyproject.md +++ b/docs/guide/pyproject.md @@ -140,6 +140,15 @@ lint = { chain = ["lint:black", "lint:flake8" ] } "lint:flake8" = "flake8 src" ``` +### `call` + +This is a special key that can be set instead of `cmd` to make a command callable without install. + +```toml +[tool.rye.scripts] +entry = { call = "hello.world:main" } +``` + ## `tool.rye.workspace` When a table with that key is stored, then a project is declared to be a workspace root. By diff --git a/rye/src/cli/run.rs b/rye/src/cli/run.rs index 1a3c776171..8a2c42e7da 100644 --- a/rye/src/cli/run.rs +++ b/rye/src/cli/run.rs @@ -62,6 +62,31 @@ fn invoke_script( let mut env_overrides = None; match pyproject.get_script_cmd(&args[0].to_string_lossy()) { + Some(Script::Call(entry, env_vars)) => { + if entry.is_empty() { + bail!("script has no arguments"); + } + env_overrides = Some(env_vars); + let splited: Vec<&str> = entry.split(':').collect(); + let (module, func) = (splited[0], splited[1]); + if module.is_empty() || func.is_empty() { + bail!("Python callable must be in the form :"); + } + let short_name = "_1"; + let real_func = if regex::Regex::new(r"\(.*?\)").unwrap().find(func).is_none() { + format!("{func}()") + } else { + func.to_string() + }; + args = [ + "python", + "-c", + &format!("import sys, {module} as {short_name};sys.exit({short_name}.{real_func})"), + ] + .into_iter() + .map(OsString::from) + .collect(); + } Some(Script::Cmd(script_args, env_vars)) => { if script_args.is_empty() { bail!("script has no arguments"); diff --git a/rye/src/pyproject.rs b/rye/src/pyproject.rs index 9769d279f7..657613d7fe 100644 --- a/rye/src/pyproject.rs +++ b/rye/src/pyproject.rs @@ -19,7 +19,7 @@ use pep440_rs::{Operator, Version, VersionSpecifiers}; use pep508_rs::Requirement; use regex::Regex; use serde::Serialize; -use toml_edit::{Array, Document, Formatted, Item, Table, Value}; +use toml_edit::{Array, Document, Formatted, Item, Table, TableLike, Value}; use url::Url; use crate::config::Config; @@ -182,6 +182,8 @@ type EnvVars = HashMap; /// A reference to a script #[derive(Clone, Debug)] pub enum Script { + /// Call python module entry + Call(String, EnvVars), /// A command alias Cmd(Vec, EnvVars), /// A multi-script execution @@ -210,29 +212,38 @@ fn toml_value_as_command_args(value: &Value) -> Option> { impl Script { fn from_toml_item(item: &Item) -> Option