From 90ecd7f5ed8e5d9a173506394433aa9d168abd2a Mon Sep 17 00:00:00 2001 From: happy game Date: Wed, 11 Dec 2024 14:24:23 +0800 Subject: [PATCH] Support `uv` for Python --- src/chsrc-main.c | 3 +- src/recipe/lang/Python/uv.c | 138 ++++++++++++++++++++++++++++++++++++ src/recipe/menu.c | 5 +- 3 files changed, 143 insertions(+), 3 deletions(-) create mode 100644 src/recipe/lang/Python/uv.c diff --git a/src/chsrc-main.c b/src/chsrc-main.c index 47c34ad..e4da02d 100644 --- a/src/chsrc-main.c +++ b/src/chsrc-main.c @@ -21,7 +21,7 @@ * | yongxiang <1926885268@qq.com> * | * Created On : <2023-08-28> - * Last Modified : <2024-12-08> + * Last Modified : <2024-12-11> * * chsrc: Change Source —— 全平台通用命令行换源工具 * ------------------------------------------------------------*/ @@ -41,6 +41,7 @@ #include "recipe/lang/Python/Poetry.c" #include "recipe/lang/Python/PDM.c" #include "recipe/lang/Python/Rye.c" + #include "recipe/lang/Python/uv.c" #include "recipe/lang/Python/Python.c" #include "recipe/lang/Node.js/common.h" diff --git a/src/recipe/lang/Python/uv.c b/src/recipe/lang/Python/uv.c new file mode 100644 index 0000000..2034ba9 --- /dev/null +++ b/src/recipe/lang/Python/uv.c @@ -0,0 +1,138 @@ +/** ------------------------------------------------------------ + * SPDX-License-Identifier: GPL-3.0-or-later + * ------------------------------------------------------------- + * File Authors : happy game + * Contributors : Nul None + * Created On : <2024-12-11> + * Last Modified : <2024-12-11> + * ------------------------------------------------------------*/ + + +/** + * chsrc get uv + * uv的配置优先级顺序如下(高到低): + * 1. $workspaces/uv.toml + * 2. $workspaces/pyproject.toml + * 3. ~/.config/uv/uv.toml + * 4. /etc/uv/uv.toml + */ + +#define UV_CONFIG "uv.toml" +#define UV_LOCAL_CONFIG_PATH "./" +#define UV_USER_CONFIG_PATH "~/.config/uv/" + + +char * +pl_python_find_uv_config (bool mkdir) +{ + if (CliOpt_Locally) + { + return xy_strjoin (2, UV_LOCAL_CONFIG_PATH, UV_CONFIG); + } + else + { + if (mkdir) + { + chsrc_ensure_dir (UV_USER_CONFIG_PATH); + } + return xy_strjoin (2, UV_USER_CONFIG_PATH, UV_CONFIG); + } +} + +void +pl_python_uv_getsrc (char *option) +{ + char *uv_config = pl_python_find_uv_config (false); + if (!chsrc_check_file (uv_config)) + { + chsrc_error2 ("未找到 uv 配置文件"); + return; + } + // grep -A 2 'index' config_file | sed -n 's/^url = "\(.*\)"/\1/p' + // 获取 [[index]] 配置项的 url + char *cmd = xy_strjoin (3, "grep -A 2 'index' ", + uv_config, + " | sed -n 's/^url = \"\\(.*\\)\"/\\1/p'"); + chsrc_run (cmd, RunOpt_Default); +} + + +/** + * @consult https://docs.astral.sh/uv/configuration/files/ + * https://github.com/RubyMetric/chsrc/issues/139 + * + * chsrc set uv + */ +void +pl_python_uv_setsrc (char *option) +{ + chsrc_ensure_program("uv"); + + Source_t source; + chsrc_yield_for_the_source (pl_python); + + char *uv_config = pl_python_find_uv_config (true); + chsrc_backup (uv_config); + + const char *source_content = xy_strjoin (5, + "[[index]]\n", + "url = \"", source.url, "\"\n", + "default = true\n"); + + // sed -i '/^\[\[index\]\]$/,/^default = true$/{s|^url = ".*"$|url = " source.url "|}' uv_config + // 将 [[index]] 到 default = true 之间的 url = ".*" 替换为 url = "source.url" + char *update_source_cmd = xy_strjoin (5, "sed -i ", + "'/^\\[\\[index\\]\\]$/,/^default = true$/{s|^url = \".*\"$|url = \"", + source.url, + "\"|}' ", + uv_config); + + char *append_source_cmd = xy_strjoin (4, "echo -e '", source_content, "' >> ", uv_config); + + // grep -q '^[[index]]$' uv_config && update_source_cmd || append_source_cmd + // 如果 uv_config 中存在 [[index]] 则更新, 否则追加到文件末尾 + // 文件不存在也是追加到新文件末尾 + char *cmd = xy_strjoin (6, "grep -q '^\\[\\[index\\]\\]$' ", + uv_config, + " && ", + update_source_cmd, + " || ", + append_source_cmd); + + chsrc_run (cmd, RunOpt_Default); +} + + +/** + * chsrc reset uv + */ +void +pl_python_uv_resetsrc (char *option) +{ + pl_python_uv_setsrc (option); +} + + +/** + * chsrc ls uv + */ +Feature_t +pl_python_uv_feat (char *option) +{ + Feature_t f = {0}; + + f.can_get = true; + f.can_reset = true; + + f.cap_locally = true; + f.cap_locally_explain = NULL; + + f.can_english = false; + f.can_user_define = true; + + f.note = NULL; + return f; +} + +// def_target_gsrf(pl_python_uv); +Target_t pl_python_uv_target = {def_target_inner_gsrf(pl_python_uv),def_target_sourcesn(pl_python)}; diff --git a/src/recipe/menu.c b/src/recipe/menu.c index c17e040..306d665 100644 --- a/src/recipe/menu.c +++ b/src/recipe/menu.c @@ -5,7 +5,7 @@ * Contributors : Nil Null * Created On : <2023-09-01> * Major Revision : 1 - * Last Modified : <2024-12-06> + * Last Modified : <2024-12-11> * ------------------------------------------------------------*/ /* Begin Target Matrix */ @@ -18,6 +18,7 @@ static const char *pl_python_poetry[] = {"poetry", NULL, t(&pl_python_poetry_target)}, *pl_python_pdm[] = {"pdm", NULL, t(&pl_python_pdm_target)}, *pl_python_rye[] = {"rye", NULL, t(&pl_python_rye_target)}, + *pl_python_uv[] = {"uv", NULL, t(&pl_python_uv_target)}, *pl_nodejs[] = {"node", "nodejs", NULL, t(&pl_nodejs_target)}, *pl_nodejs_bun[] = {"bun", NULL, t(&pl_nodejs_bun_target)}, @@ -48,7 +49,7 @@ static const char **pl_packagers[] = { pl_ruby, - pl_python, pl_python_pip, pl_python_poetry, pl_python_pdm, pl_python_rye, + pl_python, pl_python_pip, pl_python_poetry, pl_python_pdm, pl_python_rye, pl_python_uv, pl_nodejs, pl_nodejs_bun, pl_nodejs_npm, pl_nodejs_pnpm, pl_nodejs_yarn, pl_nodejs_nvm,