Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/chsrc-main.c
Original file line number Diff line number Diff line change
Expand Up @@ -788,7 +788,6 @@ chefs_handle_Get_Source (Dish_t *dish, const char *input, char *option)
Dish_t *sub_dish = xy_seq_at (dish->sub_dishes, i);
sub_dish->preparefn();
println (bdpurple(sub_dish->aliases));
chsrc_set_dish_group_mode();
chefs_handle_Get_Source (sub_dish, dish_get_first_alias(sub_dish), option);
br();
}
Expand All @@ -814,6 +813,8 @@ chefs_handle_Set_Source (Dish_t *dish, const char *input, char *option)
{
if (dish_has_sub_dishes(dish))
{
chsrc_begin_combo_source_resolution (dish);

for (size_t i=0; i<xy_seq_len(dish->sub_dishes); i++)
{
Dish_t *sub_dish = xy_seq_at (dish->sub_dishes, i);
Expand All @@ -822,6 +823,8 @@ chefs_handle_Set_Source (Dish_t *dish, const char *input, char *option)
chefs_handle_Set_Source (sub_dish, dish_get_first_alias(sub_dish), option);
br();
}

chsrc_end_combo_source_resolution ();
return;
}

Expand Down
155 changes: 131 additions & 24 deletions src/framework/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@

static int chsrc_get_cpucore ();

/* 定义于 dish.c,core.c 在 combo 源解析时需要提前声明 */
bool dish_has_source_from_mirror (Dish_t *dish, const char *code);


/* Global Program Mode */
struct
Expand All @@ -43,9 +46,6 @@ struct
bool MeasureMode;
bool ResetMode;

// 内部实现
bool DishGroupMode;

// 用户命令选项
bool Ipv6Mode;
Scope_t Scope;
Expand All @@ -57,7 +57,6 @@ ProgMode =
{
.MeasureMode = false,
.ResetMode = false,
.DishGroupMode = false,
.Ipv6Mode = false,
.Scope = ImplementationDefinedScope,
.EnglishMode = false,
Expand All @@ -66,10 +65,9 @@ ProgMode =
};

/* recipe 相关 mode */
bool chsrc_in_dish_group_mode() {return ProgMode.DishGroupMode;}
// 并非作为 sub dish,而是自身作为一个独立的 dish 执行
bool chsrc_in_standalone_mode() {return !ProgMode.DishGroupMode;}
void chsrc_set_dish_group_mode(){ProgMode.DishGroupMode = true;}
// combo dish 递归不再复用旧的 DishGroupMode;每个 leaf dish 仍负责自己的
// 确认和收尾输出。
bool chsrc_in_standalone_mode() {return true;}

bool chsrc_in_reset_mode(){return ProgMode.ResetMode;}
/* 默认换源作用域就是 ImplementationDefinedScope */
Expand Down Expand Up @@ -113,23 +111,29 @@ typedef enum ChgType_t
ChgType_Untested
} ChgType_t;

#define MaxComboStackDepth 16
Comment thread
Mikachu2333 marked this conversation as resolved.

/* Global Program Status */
struct
{
int leader_selected_index; /* combo dish 选中的索引 */
ChgType_t chgtype; /* 换源实现的类型 */
ChgType_t chgtype; /* 换源实现的类型 */

/* 此时 chsrc_run() 不再是recipe中指定要运行的一个外部命令,而是作为一个功能实现的支撑 */
bool chsrc_run_faas;
char *user_agent;

/* combo dish 源解析上下文。用户只给一个 code/URL,但不同 sub dish 可能
* 使用不同的源列表;该栈记录当前正在处理的 combo dish。 */
Dish_t *ComboStack[MaxComboStackDepth];
XySeq_t *ComboBackedUpPaths[MaxComboStackDepth];
int ComboStackDepth;
}
ProgStatus =
{
.leader_selected_index = -1,
.chgtype = ChgType_Auto,
.chsrc_run_faas = false,
.user_agent = "chsrc/" Chsrc_Version,
.ComboStackDepth = 0,
};


Expand All @@ -151,8 +155,6 @@ ProgStore =
.contributors = NULL,
};



#define Exit_OK 0
#define Exit_Fatal 1
#define Exit_Unknown 2
Expand All @@ -175,6 +177,33 @@ ProgStore =
/* 多语句必须括起来,否则在不带 { } 的 if else 等语句中会出错 */
#define chsrc_breakdown(reason) { xy_error(App_Name "(BREAKDOWN)",reason); exit(Exit_MaintainerCause); }

bool
chsrc_in_dish_group_mode (void)
{
return ProgStatus.ComboStackDepth > 0;
}

void
chsrc_begin_combo_source_resolution (Dish_t *dish)
{
if (ProgStatus.ComboStackDepth >= MaxComboStackDepth)
chsrc_breakdown ("combo dish 嵌套层级过深");

int depth = ProgStatus.ComboStackDepth;
ProgStatus.ComboStack[depth] = dish;
ProgStatus.ComboBackedUpPaths[depth] = xy_seq_new ();
ProgStatus.ComboStackDepth++;
}

void
chsrc_end_combo_source_resolution (void)
{
if (ProgStatus.ComboStackDepth <= 0)
chsrc_breakdown ("combo dish 解析上下文已为空");

ProgStatus.ComboStackDepth--;
}

#define faint(str) xy_str2faint(str)
#define red(str) xy_str2red(str)
#define blue(str) xy_str2blue(str)
Expand Down Expand Up @@ -1039,6 +1068,54 @@ source_has_empty_url (Source_t *source)
return source->url == NULL;
}

static bool
subdish_sibling_has_source_from_mirror (Dish_t *current, const char *code)
{
if (ProgStatus.ComboStackDepth <= 0)
return false;

Dish_t *combo = ProgStatus.ComboStack[ProgStatus.ComboStackDepth - 1];
if (!combo || !combo->sub_dishes)
return false;

for (size_t i=0; i < xy_seq_len(combo->sub_dishes); i++)
{
Dish_t *sub_dish = xy_seq_at (combo->sub_dishes, i);
if (sub_dish == current)
continue;

if (!sub_dish->inited)
sub_dish->preparefn ();

if (dish_has_source_from_mirror (sub_dish, code))
return true;
}

return false;
}

/**
* @brief 在 combo dish 中为当前 sub dish 解析源
*
* 用户只提供一个 code。若当前 sub dish 拥有该 code,直接使用它;否则,
* 若某个兄弟 sub dish 拥有该 code,说明该 code 仅属于另一类源,当前 sub
* dish 应自动测速选择其最快镜像。都不存在时走普通查询路径并报错。
*/
int
chsrc_resolve_combo_subdish_source (Dish_t *dish, char *option)
{
if (dish_has_source_from_mirror (dish, option))
return query_mirror_exist (dish->sources, dish->sources_n, dish->aliases, option);

if (subdish_sibling_has_source_from_mirror (dish, option))
return auto_select_mirror (dish->sources, dish->sources_n, dish->aliases);

chsrc_breakdown (ENGLISH
? "This combo sub dish has no source from the requested mirror"
: "该 combo sub dish 没有所请求镜像站的源");
return 0;
}



/**
Expand All @@ -1051,10 +1128,9 @@ source_has_empty_url (Source_t *source)
* 3. 用户什么都没指定, 即 chsrc set <dish>
* 4. 用户正在重置源, 即 chsrc reset <dish>
*
* 如果处于 Dish Group 模式下,combo dish 已经测速过了,sub dish
* 不能再次测速,而是直接选择 combo dish 测过的结果
*
* 5. combo dish 测速出来的某个源
* 如果处于 combo source resolution 上下文中,则按 sub dish 与 sibling
* 的源列表集中决定:code 命中本 dish 则直接使用;命中 sibling 则本 dish
* 自动测速;传入 URL 时,支持自定义 URL 的 sub dish 使用 URL,其余自动测速。
*
*/
Source_t
Expand All @@ -1069,14 +1145,29 @@ chsrc_yield_source (Dish_t *dish, char *option)
if (!dish->inited) dish->preparefn();

Source_t source;
if (chsrc_in_dish_group_mode() && ProgStatus.leader_selected_index==-1)
{
ProgStatus.leader_selected_index = use_specific_mirror_or_auto_select (option, dish);
source = dish->sources[ProgStatus.leader_selected_index];
}
else if (chsrc_in_dish_group_mode() && ProgStatus.leader_selected_index!=-1)
if (chsrc_in_dish_group_mode() && option)
{
source = dish->sources[ProgStatus.leader_selected_index];
if (hp_is_url (option))
{
/* combo dish 传入 URL 时,支持该 sub dish 自定义 URL 的则直接使用;
* 不支持则自动选择该 sub dish 的最快源。这样 uv 可只把 URL 当作
* PyPI index,而 python-install-mirror 仍自动选择。 */
if (dish->can_user_define)
{
Source_t tmp = { &UserDefinedProvider, option };
source = tmp;
}
else
{
int index = auto_select_mirror (dish->sources, dish->sources_n, dish->aliases);
source = dish->sources[index];
}
}
else
{
int index = chsrc_resolve_combo_subdish_source (dish, option);
source = dish->sources[index];
}
}
else if (hp_is_url (option))
{
Expand Down Expand Up @@ -1972,6 +2063,22 @@ chsrc_backup (const char *path)
return;
}

/* combo dish 中多个 sub dish 可能操作同一配置文件。首个 sub dish
Comment thread
Mikachu2333 marked this conversation as resolved.
* 已经保留原始内容后,后续 sub dish 不应再覆盖该备份。 */
if (chsrc_in_dish_group_mode())
{
int depth = ProgStatus.ComboStackDepth - 1;
XySeq_t *backed_up_paths = ProgStatus.ComboBackedUpPaths[depth];

for (size_t i=0; i < xy_seq_len(backed_up_paths); i++)
{
if (xy_streql (xy_seq_at (backed_up_paths, i), path))
goto log_anyway;
}

xy_seq_push (backed_up_paths, xy_strdup (path));
}

if (xy.on_bsd || xy.on_macos)
{
/* BSD 和 macOS 的 cp 不支持 --backup 选项 */
Expand Down
23 changes: 23 additions & 0 deletions src/framework/dish.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,26 @@ dish_has_sub_dishes (Dish_t *dish)
{
return (dish->sub_dishes && xy_seq_len(dish->sub_dishes) > 1);
}



bool
dish_has_source_from_mirror (Dish_t *dish, const char *code)
{
if (!dish || !dish->sources || !code)
return false;

if (xy_streql (code, "upstream"))
return dish->sources_n > 0;

if (xy_streql (code, "first"))
return dish->sources_n > 1;

for (int i=0; i < dish->sources_n; i++)
{
if (xy_streql (dish->sources[i].mirror->code, code))
return true;
}

return false;
}
5 changes: 4 additions & 1 deletion src/recipe/lang/Python/uv/uv-python-build.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ pl_uv_python_build_prepare (void)
chef_set_default_scope (this, UserScope);

chef_deny_english (this);
chef_allow_user_define (this);
chef_deny_user_define (this);
this->can_user_define_explain =
CHINESE ? "python-install-mirror 不支持手动指定,chsrc 会自动选择"
: "python-install-mirror cannot be specified manually; chsrc selects it automatically";

def_sources_begin ()
{&UpstreamProvider, "https://github.com/astral-sh/python-build-standalone/releases/download", DelegateToUpstream},
Expand Down
Loading