chsrc/src/chsrc-main.c

838 lines
26 KiB
C
Raw Normal View History

/** ------------------------------------------------------------
2024-07-31 12:38:52 +08:00
* Copyright © 2023-2024 Aoran Zeng, Heng Guo
2024-08-19 10:58:20 +08:00
* SPDX-License-Identifier: GPL-3.0-or-later
2024-06-11 20:18:02 +08:00
* -------------------------------------------------------------
2024-08-19 10:58:20 +08:00
* Project Name : chsrc
* Project Authors : Aoran Zeng <ccmywish@qq.com>
* | Heng Guo <2085471348@qq.com>
* Contributors : Aaron Ruan <aaron212cn@outlook.com>
* | Rui Chen <rui@chenrui.dev>
2024-08-15 20:51:36 +08:00
* | Shengwei Chen <414685209@qq.com>
2024-08-19 10:58:20 +08:00
* | BlockLune <blocklune@gmail.com>
2024-08-29 03:19:16 +08:00
* | Mr. Will <mr.will.com@outlook.com>
* | Terrasse <terrasse@qq.com>
2024-08-15 20:51:36 +08:00
* |
* Created On : <2023-08-28>
2024-09-29 10:57:41 +08:00
* Last Modified : <2024-09-29>
*
2024-06-11 20:18:02 +08:00
* chsrc: Change Source
* ------------------------------------------------------------*/
2023-08-29 15:54:21 +08:00
2024-09-23 23:43:44 +08:00
#define Chsrc_Version "0.1.9.Beta1Dev2"
2024-09-29 10:57:41 +08:00
#define Chsrc_Release_Date "2024/09/29"
2024-08-19 11:28:51 +08:00
#define Chsrc_Banner_Version "v" Chsrc_Version "-" Chsrc_Release_Date
#define Chsrc_Maintain_URL "https://github.com/RubyMetric/chsrc"
#define Chsrc_Maintain_URL2 "https://gitee.com/RubyMetric/chsrc"
2023-09-21 14:34:16 +08:00
2024-09-10 19:13:25 +08:00
#include "chsrc-framework.h"
2023-08-28 22:21:33 +08:00
2024-08-17 09:27:20 +08:00
#include "recipe/lang/Ruby.c"
2024-09-13 19:17:51 +08:00
#include "recipe/lang/Python/common.h"
#include "recipe/lang/Python/pip.c"
#include "recipe/lang/Python/Poetry.c"
#include "recipe/lang/Python/PDM.c"
#include "recipe/lang/Python/Python.c"
#include "recipe/lang/Node.js/common.h"
2024-09-10 18:43:27 +08:00
#include "recipe/lang/Node.js/npm.c"
#include "recipe/lang/Node.js/pnpm.c"
#include "recipe/lang/Node.js/Yarn.c"
#include "recipe/lang/Node.js/Node.js.c"
2024-09-23 23:43:44 +08:00
#include "recipe/lang/Node.js/nvm.c"
2024-08-17 09:27:20 +08:00
#include "recipe/lang/Perl.c"
#include "recipe/lang/PHP.c"
#include "recipe/lang/Lua.c"
#include "recipe/lang/Go.c"
#include "recipe/lang/Java.c"
#include "recipe/lang/Rust.c"
2024-09-14 03:29:36 +08:00
#include "recipe/lang/Dart/Pub.c"
#include "recipe/lang/Dart/Flutter.c"
2024-08-17 09:27:20 +08:00
#include "recipe/lang/Haskell.c"
#include "recipe/lang/OCaml.c"
#include "recipe/lang/R.c"
#include "recipe/lang/Julia.c"
2024-08-16 04:38:46 +08:00
#include "recipe/lang/NuGet.c"
2024-08-16 04:43:02 +08:00
#include "recipe/lang/Clojure.c"
2023-09-10 18:44:34 +08:00
2024-08-16 02:48:26 +08:00
2024-08-17 09:52:10 +08:00
#include "recipe/os/APT/common.h"
2024-08-16 02:48:26 +08:00
// Debian-based
2024-08-17 11:01:23 +08:00
#include "recipe/os/APT/Debian.c"
#include "recipe/os/APT/Ubuntu.c"
2024-08-17 09:52:10 +08:00
#include "recipe/os/APT/Kali-Linux.c"
2024-08-17 11:01:23 +08:00
#include "recipe/os/APT/Raspberry-Pi-OS.c"
2024-08-16 02:48:26 +08:00
// Ubuntu-based
2024-08-17 09:52:10 +08:00
#include "recipe/os/APT/Linux-Mint.c"
2024-08-17 11:01:23 +08:00
#include "recipe/os/APT/Trisquel.c"
2024-08-17 09:52:10 +08:00
#include "recipe/os/APT/Linux-Lite.c"
2024-08-17 11:01:23 +08:00
// Debian-based and Ubuntu-based
#include "recipe/os/APT/Armbian.c"
2024-08-16 02:48:26 +08:00
// Independent
2024-08-17 11:01:23 +08:00
#include "recipe/os/APT/ROS.c"
2024-08-17 09:52:10 +08:00
#include "recipe/os/APT/openKylin.c"
#include "recipe/os/APT/deepin.c"
2024-08-17 09:52:10 +08:00
#include "recipe/os/YUM/common.h"
#include "recipe/os/YUM/Fedora-Linux.c"
#include "recipe/os/YUM/AlmaLinux.c"
#include "recipe/os/YUM/Rocky-Linux.c"
#include "recipe/os/YUM/openEuler.c"
#include "recipe/os/YUM/Anolis-OS.c"
2024-08-17 09:52:10 +08:00
#include "recipe/os/pacman/Arch-Linux.c"
#include "recipe/os/pacman/Manjaro-Linux.c"
#include "recipe/os/pacman/MSYS2.c"
2024-08-17 11:01:23 +08:00
#include "recipe/os/openSUSE.c"
#include "recipe/os/Alpine-Linux.c"
#include "recipe/os/Gentoo-Linux.c"
#include "recipe/os/Void-Linux.c"
#include "recipe/os/Solus.c"
#include "recipe/os/OpenWrt.c"
2024-08-08 18:30:28 +08:00
2024-08-16 04:02:25 +08:00
#include "recipe/os/BSD/FreeBSD.c"
#include "recipe/os/BSD/NetBSD.c"
#include "recipe/os/BSD/OpenBSD.c"
2023-09-24 21:07:39 +08:00
2024-08-16 04:43:02 +08:00
2024-08-16 04:31:48 +08:00
#include "recipe/ware/TeX-Live.c"
2024-08-17 09:16:59 +08:00
#include "recipe/ware/Emacs.c"
2024-08-16 04:11:38 +08:00
#include "recipe/ware/WinGet.c"
2024-08-16 04:07:54 +08:00
#include "recipe/ware/Homebrew.c"
2024-08-16 04:15:05 +08:00
#include "recipe/ware/CocoaPods.c"
2024-08-16 04:18:27 +08:00
#include "recipe/ware/Nix.c"
2024-08-16 04:20:48 +08:00
#include "recipe/ware/Guix.c"
2024-08-16 04:28:50 +08:00
#include "recipe/ware/Flathub.c"
2024-08-16 21:13:21 +08:00
#include "recipe/ware/Docker-Hub.c"
2024-08-16 04:28:50 +08:00
#include "recipe/ware/Anaconda.c"
2024-08-21 22:33:52 +08:00
#include "recipe/menu.c"
2023-08-30 22:27:08 +08:00
2024-06-07 21:17:29 +08:00
static const char *
2024-06-08 13:26:52 +08:00
Chsrc_Usage[] = {
2024-06-05 13:51:24 +08:00
"使用: chsrc <command> [options] [target] [mirror]",
"help 打印此帮助,或 h, -h, --help",
2024-08-18 10:03:00 +08:00
"issue 查看相关issue\n",
2024-08-22 22:26:26 +08:00
2024-08-18 10:03:00 +08:00
"list (或 ls, 或 l) 列出可用镜像源,和可换源目标",
"list mirror/target 列出可用镜像源,或可换源目标",
"list os/lang/ware 列出可换源的操作系统/编程语言/软件\n",
"measure <target> 对该目标所有源测速",
"cesu <target> \n",
"list <target> 查看该目标可用源与支持功能",
"get <target> 查看该目标当前源的使用情况\n",
"set <target> 换源,自动测速后挑选最快源",
"set <target> first 换源,使用维护团队测速第一的源",
2024-08-18 10:03:00 +08:00
"set <target> <mirror> 换源,指定使用某镜像站 (通过list <target>查看)",
"set <target> https://url 换源,用户自定义源URL",
2024-06-05 16:13:46 +08:00
"reset <target> 重置,使用上游默认使用的源\n",
2024-06-05 13:51:24 +08:00
"选项:",
2024-08-09 01:46:58 +08:00
"-dry Dry Run,模拟换源过程,命令仅打印并不运行",
2024-08-22 22:26:26 +08:00
"-local 仅对本项目而非全局换源 (通过ls <target>查看支持情况)",
2024-09-04 01:03:53 +08:00
"-ipv6 使用IPv6测速",
2024-08-23 08:09:39 +08:00
"-en(glish) 使用英文输出",
"-no-color 无颜色输出\n",
2024-08-22 22:26:26 +08:00
2024-09-04 12:28:59 +08:00
"镜像站状态: <https://github.com/RubyMetric/chsrc/wiki>",
2024-08-22 22:26:26 +08:00
"维护: <" Chsrc_Maintain_URL ">"
};
static const char *
Chsrc_Usage_English[] = {
"Usage: chsrc <command> [options] [target] [mirror]",
"help Print this help, or h, -h, --help",
"issue See related issues\n",
"list (or ls, or l) List available mirror sites and supported targets",
"list mirror/target List available mirror sites or supported targets",
"list os/lang/ware List supported OS/Programming Language/Software\n",
"measure <target> Measure velocity of all sources of <target>",
"cesu <target> \n",
"list <target> View available sources and supporting features for <target>",
2024-08-23 08:59:50 +08:00
"get <target> View the current source state for <target>\n",
2024-08-22 22:26:26 +08:00
"set <target> Change source, select the fastest source by automatic speed measurement",
2024-08-23 16:50:51 +08:00
"set <target> first Change source, select the fastest source measured by the maintainers team",
"set <target> <mirror> Change source, specify a mirror site (Via `list <target>`)",
2024-08-22 22:26:26 +08:00
"set <target> https://url Change source, using user-defined source URL",
"reset <target> Reset source to the upstream's default\n",
"Options:",
"-dry Dry Run. Simulate the source changing process, command only prints, not run",
2024-08-23 16:50:51 +08:00
"-local Change source only for this project rather than globally (Via `ls <target>`)",
2024-09-04 01:03:53 +08:00
"-ipv6 Speed measurement using IPv6",
2024-08-23 08:09:39 +08:00
"-en(glish) Output in English",
"-no-color Output without color\n",
2024-08-22 22:26:26 +08:00
2024-09-04 12:28:59 +08:00
"Mirror status: <https://github.com/RubyMetric/chsrc/wiki>",
"Maintain: <" Chsrc_Maintain_URL ">"
2023-08-28 22:21:33 +08:00
};
2023-08-31 21:40:32 +08:00
void
2024-08-17 06:46:06 +08:00
cli_print_available_mirrors ()
2023-08-31 21:40:32 +08:00
{
2024-08-23 09:23:32 +08:00
{
char *msg = CliOpt_InEnglish ? "To specify a source, use chsrc set " : "指定使用某源,请使用 chsrc set ";
say (bdblue(xy_strjoin (3, msg, "<target>", " <code>\n")));
}
{
char *msg = CliOpt_InEnglish ? "Available Mirror Sites: \n" : "可用镜像站: \n";
say (bdgreen(msg));
}
{
char *msg1 = CliOpt_InEnglish ? "Mirror abbr" : "镜像站简写";
char *msg2 = CliOpt_InEnglish ? "Mirror URL" : "镜像站URL";
char *msg3 = CliOpt_InEnglish ? "Mirror Name" : "镜像站";
char *format = CliOpt_InEnglish ? " %-13s%-28s%-35s%s\n" : " %-13s%-33s%-42s%s\n";
printf (format, "code", msg1, msg2, msg3);
say ("--------- -------------- ------------------------------------- ---------------------");
}
2024-07-24 18:54:20 +08:00
for (int i = 0; i < xy_arylen (available_mirrors); i++)
2024-04-25 16:33:17 +08:00
{
2024-06-05 14:42:31 +08:00
MirrorSite* mir = available_mirrors[i];
2024-08-19 11:42:31 +08:00
printf ("%-14s%-18s%-41s ", mir->code, mir->abbr, mir->site); say (mir->name);
2024-04-25 16:33:17 +08:00
}
2023-08-31 21:40:32 +08:00
}
void
2024-08-17 06:46:06 +08:00
cli_print_supported_targets_ (const char ***array, size_t size)
2023-08-31 21:40:32 +08:00
{
for (int i=0; i<size; i++)
{
2024-04-25 16:33:17 +08:00
const char **target = array[i];
const char *alias = target[0];
for (int k=1; alias!=NULL; k++)
{
printf ("%s\t", alias);
alias = target[k];
}
2024-08-17 07:21:47 +08:00
br();
2023-08-31 21:40:32 +08:00
}
2024-08-17 07:21:47 +08:00
br();
2023-08-31 21:40:32 +08:00
}
void
2024-08-17 06:46:06 +08:00
cli_print_supported_targets ()
2023-08-31 21:40:32 +08:00
{
2024-08-23 09:23:32 +08:00
{
char *msg = CliOpt_InEnglish ? "Support following targets (same line indicates these targets are compatible)"
: "支持对以下目标换源 (同一行表示这几个命令兼容)" ;
say (bdblue(msg)); br();
}
{
char *msg = CliOpt_InEnglish ? "Programming Languages" : "编程语言";
say (bdgreen(msg));
2024-08-19 11:42:31 +08:00
say ("-------------------------");
2024-08-17 06:46:06 +08:00
cli_print_supported_targets_ (pl_packagers, xy_arylen(pl_packagers));
2024-08-23 09:23:32 +08:00
}
{
char *msg = CliOpt_InEnglish ? "Operating Systems" : "操作系统";
say (bdgreen(msg));
2024-08-19 11:42:31 +08:00
say ("-------------------------");
2024-08-17 06:46:06 +08:00
cli_print_supported_targets_ (os_systems, xy_arylen(os_systems));
2024-08-23 09:23:32 +08:00
}
{
char *msg = CliOpt_InEnglish ? "Softwares" : "软件";
say (bdgreen(msg));
2024-08-19 11:42:31 +08:00
say ("-------------------------");
2024-08-17 06:46:06 +08:00
cli_print_supported_targets_ (wr_softwares, xy_arylen(wr_softwares));
2024-08-23 09:23:32 +08:00
}
2023-08-31 21:40:32 +08:00
}
void
2024-08-17 06:46:06 +08:00
cli_print_supported_pl ()
{
2024-08-23 09:23:32 +08:00
char *msg = CliOpt_InEnglish ? "Support following Programming Languages (same line indicates these targets are compatible)\n"
: "支持对以下编程语言生态换源 (同一行表示这几个目标兼容)\n";
say (bdgreen(msg));
2024-08-17 06:46:06 +08:00
cli_print_supported_targets_ (pl_packagers, xy_arylen(pl_packagers));
}
void
2024-08-17 06:46:06 +08:00
cli_print_supported_os ()
{
2024-08-23 09:23:32 +08:00
char *msg = CliOpt_InEnglish ? "Support following Operating Systems (same line indicates these targets are compatible)\n"
: "支持对以下操作系统换源 (同一行表示这几个目标兼容)\n";
say (bdgreen(msg));
2024-08-19 11:42:31 +08:00
cli_print_supported_targets_ (os_systems, xy_arylen(os_systems));
}
void
2024-08-17 06:46:06 +08:00
cli_print_supported_wr ()
{
2024-08-23 09:23:32 +08:00
char *msg = CliOpt_InEnglish ? "Support following Softwares (same line indicates these targets are compatible)\n"
: "支持对以下软件换源 (同一行表示这几个目标兼容)\n";
say (bdgreen(msg));
2024-08-19 11:42:31 +08:00
cli_print_supported_targets_ (wr_softwares, xy_arylen(wr_softwares));
}
2023-08-31 21:40:32 +08:00
2023-08-31 22:57:09 +08:00
2023-09-02 16:49:55 +08:00
/**
* chsrc list <target>
*/
void
2024-08-16 20:54:37 +08:00
cli_print_target_available_sources (SourceInfo sources[], size_t size)
2023-09-02 16:49:55 +08:00
{
2023-09-09 16:56:03 +08:00
for (int i=0;i<size;i++)
2024-04-25 16:33:17 +08:00
{
SourceInfo src = sources[i];
2024-06-05 14:42:31 +08:00
const MirrorSite *mir = src.mirror;
2024-07-24 18:54:20 +08:00
if (NULL == src.url)
{
src.url = "Please help to add the upstream url!";
}
2024-04-25 16:33:17 +08:00
printf ("%-14s%-18s%-50s ", mir->code, mir->abbr, src.url);
2024-08-19 11:42:31 +08:00
say (mir->name);
2024-04-25 16:33:17 +08:00
}
2023-09-02 16:49:55 +08:00
}
2024-08-16 20:54:37 +08:00
void
2024-08-17 06:46:06 +08:00
cli_print_target_features (FeatInfo f, const char *input_target_name)
2024-08-16 20:54:37 +08:00
{
2024-08-23 08:59:50 +08:00
{
char *msg = CliOpt_InEnglish ? "\nAvailable Features:\n" : "\n可用功能:\n";
say (bdgreen(msg));
}
2024-08-16 20:54:37 +08:00
2024-08-23 08:59:50 +08:00
{
char *msg = CliOpt_InEnglish ? " Get: View the current source state " : " Get: 查看当前源状态 ";
char *get_msg = xy_strjoin (3, msg, "| chsrc get ", input_target_name);
2024-08-22 16:46:54 +08:00
if (f.can_get) printf (" %s%s\n", bdgreen(YesMark), purple(get_msg));
else printf (" %s%s\n", bdred(NoMark), get_msg);br();
2024-08-23 08:59:50 +08:00
}
2024-08-17 06:46:06 +08:00
2024-08-23 08:59:50 +08:00
{
char *msg = CliOpt_InEnglish ? " Reset: Reset to the default source " : " Reset: 重置回默认源 ";
char *reset_msg = xy_strjoin (3, msg, "| chsrc reset ", input_target_name);
2024-08-22 16:46:54 +08:00
if (f.can_reset) printf (" %s%s\n", bdgreen(YesMark), purple(reset_msg));
else printf (" %s%s\n", bdred(NoMark), reset_msg);br();
2024-08-23 08:59:50 +08:00
}
2024-08-17 06:46:06 +08:00
2024-08-23 08:59:50 +08:00
{
char *msg = CliOpt_InEnglish ? " UserDefine: using user-defined source URL " : " UserDefine: 用户自定义换源URL ";
char *user_define_msg = xy_strjoin (5, msg, "| chsrc set ", input_target_name, " https://user-define-url.org/", input_target_name);
2024-08-22 16:46:54 +08:00
if (f.can_user_define) printf (" %s%s\n", bdgreen(YesMark), purple(user_define_msg));
else printf (" %s%s\n", bdred(NoMark), user_define_msg);br();
2024-08-23 08:59:50 +08:00
}
2024-08-17 06:46:06 +08:00
2024-08-23 08:59:50 +08:00
{
char *msg = CliOpt_InEnglish ? " Locally: Change source only for this project " : " Locally: 仅对本项目换源 ";
char *locally_msg = xy_strjoin (3, msg, "| chsrc set -local ", input_target_name);
2024-08-17 06:46:06 +08:00
2024-08-17 06:50:20 +08:00
switch (f.stcan_locally)
2024-08-23 08:59:50 +08:00
{
case CanNot:
printf (" %s%s\n", bdred(NoMark), locally_msg);br();
break;
case CanFully:
printf (" %s%s\n", bdgreen(YesMark), purple(locally_msg));br();
break;
case CanSemi:
printf (" %s%s\n\n %s\n", bdgreen(SemiYesMark), purple(locally_msg), f.locally);br();
break;
default:
xy_unreach;
}
2024-08-17 06:46:06 +08:00
}
2024-08-16 20:54:37 +08:00
2024-08-23 08:59:50 +08:00
{
char *msg = CliOpt_InEnglish ? " English: Output in English " : " English: 英文输出 ";
char *english_msg = xy_strjoin (3, msg, "| chsrc set -en ", input_target_name);
if (f.can_english) printf (" %s%s\n", bdgreen(YesMark), purple(english_msg));
else printf (" %s%s\n", bdred(NoMark), english_msg);br();
}
2024-08-16 20:54:37 +08:00
if (f.note)
{
2024-08-23 08:59:50 +08:00
char *msg = CliOpt_InEnglish ? "NOTE: " : "备注: ";
printf ("%s%s\n", bdyellow (msg), bdyellow (f.note));
2024-08-16 20:54:37 +08:00
}
}
2023-09-02 16:49:55 +08:00
2023-09-06 17:06:09 +08:00
void
2024-06-05 09:24:39 +08:00
cli_print_version ()
2023-08-28 22:21:33 +08:00
{
2024-08-19 11:28:51 +08:00
say ("chsrc " Chsrc_Version);
say ("Copyright (C) 2024 Aoran Zeng, Heng Guo");
say ("License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>");
say ("This is free software: you are free to change and redistribute it.");
say ("There is NO WARRANTY, to the extent permitted by law.");
br();
2024-09-10 19:23:55 +08:00
say ("Written by Aoran Zeng, Heng Guo and contributors. (See chsrc-main.c)");
2024-06-05 09:24:39 +08:00
}
void
cli_print_help ()
{
2024-08-19 11:28:51 +08:00
say (xy_strjoin (3, "chsrc: Change Source (GPLv3+) ",
2024-08-19 11:53:10 +08:00
purple (Chsrc_Banner_Version), " by RubyMetric"));
2024-08-17 07:21:47 +08:00
br();
2024-08-22 22:26:26 +08:00
if (CliOpt_InEnglish)
{
for (int i=0; i<xy_arylen (Chsrc_Usage_English); i++)
say (Chsrc_Usage_English[i]);
}
else
2024-04-25 16:33:17 +08:00
{
2024-08-22 22:26:26 +08:00
for (int i=0; i<xy_arylen (Chsrc_Usage); i++)
say (Chsrc_Usage[i]);
2024-04-25 16:33:17 +08:00
}
2023-08-28 22:21:33 +08:00
}
2024-06-08 13:14:14 +08:00
void
cli_print_issues ()
{
2024-08-19 11:42:31 +08:00
say (
2024-09-04 12:28:59 +08:00
"We accept issues both sides on Gitee and Github\n\n"
2024-06-08 13:14:14 +08:00
"- https://gitee.com/RubyMetric/chsrc/issues\n"
2024-08-17 07:27:30 +08:00
"- https://github.com/RubyMetric/chsrc/issues\n"
2024-06-08 13:14:14 +08:00
);
2024-06-08 13:26:52 +08:00
2024-09-04 12:28:59 +08:00
say ("Latest Mirror site status wiki:\n\n"
"- https://github.com/RubyMetric/chsrc/wiki\n");
2024-08-17 07:27:30 +08:00
/*
2024-06-14 01:02:23 +08:00
if (chsrc_check_program ("gh"))
2024-06-08 13:26:52 +08:00
{
2024-06-14 01:02:23 +08:00
char *cmd = xy_str_to_quietcmd ("gh browse --repo RubyMetric/chsrc");
system (cmd);
2024-06-08 13:26:52 +08:00
}
2024-08-17 07:27:30 +08:00
*/
2024-06-08 13:14:14 +08:00
}
2023-08-28 22:21:33 +08:00
2023-09-01 17:17:45 +08:00
/**
* targets列表`input`target匹配
*
2024-08-22 22:26:26 +08:00
* @param[out] target_info targets列表中最后的target_info信息
2023-09-01 17:17:45 +08:00
*
* @return truefalse
*/
bool
2024-04-25 16:33:17 +08:00
iterate_targets_ (const char ***array, size_t size, const char *input, const char ***target_info)
2023-09-01 17:17:45 +08:00
{
int matched = 0;
2024-04-25 16:33:17 +08:00
const char **target = NULL;
2023-09-01 17:17:45 +08:00
int k = 0;
2024-04-25 16:33:17 +08:00
const char *alias = NULL;
2023-09-01 17:17:45 +08:00
2024-04-25 16:33:17 +08:00
for (int i=0; i<size; i++)
{
target = array[i];
2023-09-01 17:17:45 +08:00
alias = target[k];
2024-04-25 16:33:17 +08:00
while (NULL!=alias)
{
2024-08-22 22:26:26 +08:00
if (xy_streql (input, alias))
2024-04-25 16:33:17 +08:00
{
matched = 1; break;
}
k++;
alias = target[k];
}
if (!matched) k = 0;
if (matched) break;
2023-09-01 17:17:45 +08:00
}
2024-04-25 16:33:17 +08:00
if (!matched)
{
*target_info = NULL;
return false;
}
2023-09-01 17:17:45 +08:00
2024-08-22 22:26:26 +08:00
do
{
k++;
alias = target[k];
}
while (NULL!=alias);
2023-09-02 19:38:32 +08:00
*target_info = target + k + 1;
2023-09-01 17:17:45 +08:00
return true;
}
2023-09-02 19:38:32 +08:00
#define iterate_targets(ary, input, target) iterate_targets_(ary, xy_arylen(ary), input, target)
2023-09-01 17:17:45 +08:00
2023-10-04 18:48:35 +08:00
typedef enum {
TargetOp_Get_Source = 1,
TargetOp_Set_Source,
TargetOp_Reset_Source,
2024-08-18 10:03:00 +08:00
TargetOp_Measure_Source,
TargetOp_List_Config
2023-10-04 18:48:35 +08:00
} TargetOp;
2023-09-01 17:17:45 +08:00
/**
* target`code`
*
2023-09-05 14:17:31 +08:00
* @param input
* @param code target要执行的操作
* @param option NULL
2023-09-01 17:17:45 +08:00
*
* @return truefalse
*/
bool
2024-04-25 16:33:17 +08:00
get_target (const char *input, TargetOp code, char *option)
2023-09-01 17:17:45 +08:00
{
2024-04-25 16:33:17 +08:00
const char **target_tmp = NULL;
2023-09-01 17:17:45 +08:00
2023-09-02 19:38:32 +08:00
bool matched = iterate_targets(pl_packagers, input, &target_tmp);
if (!matched) matched = iterate_targets(os_systems, input, &target_tmp);
if (!matched) matched = iterate_targets(wr_softwares, input, &target_tmp);
2023-09-01 17:17:45 +08:00
2024-08-16 20:54:37 +08:00
if (!matched) return false;
2023-09-01 17:17:45 +08:00
2024-04-25 16:33:17 +08:00
TargetInfo *target = (TargetInfo*) *target_tmp;
2023-09-02 19:38:32 +08:00
2024-06-05 12:50:43 +08:00
if (TargetOp_Set_Source==code)
2024-04-25 16:33:17 +08:00
{
if (target->setfn) target->setfn(option);
2024-06-08 13:26:52 +08:00
else chsrc_error (xy_strjoin (3, "暂未对 ", input, " 实现set功能,邀您帮助: chsrc issue"));
2024-04-25 16:33:17 +08:00
}
else if (TargetOp_Reset_Source==code)
{
if (target->resetfn) target->resetfn(option);
2024-06-08 13:26:52 +08:00
else chsrc_error (xy_strjoin (3, "暂未对 ", input, " 实现reset功能,邀您帮助: chsrc issue"));
}
2024-06-05 12:50:43 +08:00
else if (TargetOp_Get_Source==code)
2024-04-25 16:33:17 +08:00
{
if (target->getfn) target->getfn("");
2024-06-08 13:26:52 +08:00
else chsrc_error (xy_strjoin (3, "暂未对 ", input, " 实现get功能,邀您帮助: chsrc issue"));
2024-04-25 16:33:17 +08:00
}
2024-08-18 10:03:00 +08:00
else if (TargetOp_List_Config==code)
2024-04-25 16:33:17 +08:00
{
2024-08-23 08:59:50 +08:00
{
char *msg = CliOpt_InEnglish ? "To specify a source, use chsrc set " : "指定使用某源,请使用 chsrc set ";
say (bdblue(xy_strjoin (3, msg, input, " <code>\n")));
}
{
char *msg = CliOpt_InEnglish ? "Available Sources: \n" : "可用源: \n";
say (bdgreen(msg));
}
{
char *msg1 = CliOpt_InEnglish ? "Mirror abbr" : "镜像站简写";
char *msg2 = CliOpt_InEnglish ? "Source URL" : "换源URL";
2024-08-23 09:23:32 +08:00
char *msg3 = CliOpt_InEnglish ? "Mirror Name" : "镜像站";
2024-08-23 08:59:50 +08:00
char *format = CliOpt_InEnglish ? " %-13s%-33s%-38s%s\n" : " %-13s%-36s%-46s%s\n";
printf (format, "code", msg1, msg2, msg3);
say ("--------- -------------- ----------------------------------------------- ---------------------");
}
2024-08-16 20:54:37 +08:00
cli_print_target_available_sources (target->sources, target->sources_n);
2024-08-23 08:59:50 +08:00
2024-08-16 20:54:37 +08:00
if (target->featfn)
{
FeatInfo fi = target->featfn("");
2024-08-17 06:46:06 +08:00
cli_print_target_features (fi, input);
2024-08-16 20:54:37 +08:00
}
2024-04-25 16:33:17 +08:00
}
2024-08-18 10:03:00 +08:00
else if (TargetOp_Measure_Source==code)
2024-04-25 16:33:17 +08:00
{
2024-09-04 08:22:39 +08:00
select_mirror_autoly (target->sources, target->sources_n, input);
2024-04-25 16:33:17 +08:00
return true;
2023-09-04 19:19:30 +08:00
}
2023-09-01 17:17:45 +08:00
return true;
}
2023-08-28 22:21:33 +08:00
int
2023-08-29 15:54:21 +08:00
main (int argc, char const *argv[])
2023-08-28 22:21:33 +08:00
{
2024-04-25 16:33:17 +08:00
xy_useutf8 (); argc -= 1;
2023-08-29 21:58:51 +08:00
2024-08-16 20:54:37 +08:00
if (0==argc)
2024-04-25 16:33:17 +08:00
{
2024-06-07 20:24:00 +08:00
cli_print_help ();
return 0;
2024-04-25 16:33:17 +08:00
}
2023-08-28 22:21:33 +08:00
2024-04-25 16:33:17 +08:00
const char *command = argv[1];
2024-06-05 09:18:48 +08:00
// chsrc set target mirror
// 1 2 3
int cli_arg_Target_pos = 2;
int cli_arg_Mirror_pos = cli_arg_Target_pos + 1;
const char *target = NULL;
2024-08-22 22:26:26 +08:00
/**
* (1)
* chsrc set -local -en target mirror
* 1 2 3 4 5
* argc = 5
*
* (2) i必须还是从1开始
* chsrc -en -h
* 1 2
*
* argc = 2
*/
/* 从第一个参数遍历到最后一个参数 */
for (int i=1; i<=argc; i++)
2024-06-05 09:18:48 +08:00
{
if (xy_str_start_with (argv[i], "-"))
{
if (xy_streql (argv[i], "-ipv6"))
{
2024-08-09 01:49:14 +08:00
CliOpt_IPv6 = true;
2024-06-05 09:18:48 +08:00
}
else if (xy_streql (argv[i], "-local"))
{
2024-08-09 01:49:14 +08:00
CliOpt_Locally = true;
2024-06-05 09:18:48 +08:00
}
else if (xy_streql (argv[i], "-en") || xy_streql (argv[i], "-english"))
{
2024-08-09 01:49:14 +08:00
CliOpt_InEnglish = true;
2024-06-05 09:18:48 +08:00
}
2024-08-09 01:46:58 +08:00
else if (xy_streql (argv[i], "-dry"))
{
CliOpt_DryRun = true;
}
2024-08-23 08:09:39 +08:00
else if (xy_streql (argv[i], "-no-color") || xy_streql (argv[i], "-no-colour"))
{
CliOpt_NoColor = true;
xy_enable_color = false;
}
2024-09-26 19:51:55 +08:00
else if ( xy_streql (argv[i], "-h")
2024-08-22 22:26:26 +08:00
|| xy_streql (argv[i], "-help")
|| xy_streql (argv[i], "--help"))
{
command = "help"; /* 交到下方处理 */
}
2024-09-26 19:51:55 +08:00
else if ( xy_streql (argv[i], "-v")
2024-08-23 16:03:14 +08:00
|| xy_streql (command, "-version")
|| xy_streql (command, "--version"))
{
command = "version"; /* 交到下方处理 */
}
2024-06-05 09:18:48 +08:00
else
{
2024-08-23 12:31:27 +08:00
char *msg = CliOpt_InEnglish ? "Unknown option: " : "未识别的命令行选项 ";
chsrc_error (xy_2strjoin (msg, argv[i])); return 1;
2024-06-05 09:18:48 +08:00
}
cli_arg_Target_pos++;
cli_arg_Mirror_pos++;
}
}
2023-09-01 17:17:45 +08:00
bool matched = false;
2024-08-23 14:55:57 +08:00
if (CliOpt_DryRun)
{
char *dry_msg = CliOpt_InEnglish ? "**Enable [Dry Run] mode. " \
2024-08-23 14:55:57 +08:00
"Simulate the source changing process (skipping speed measurement). " \
"Commands only print but don't run**\n"
2024-08-23 14:55:57 +08:00
: "**开启Dry Run模式,模拟换源过程(跳过测速),命令仅打印并不运行**\n";
chsrc_log (bdyellow(dry_msg));
}
2024-08-23 14:24:31 +08:00
/* chsrc help */
2024-09-26 19:51:55 +08:00
if ( xy_streql (command, "h")
2024-08-22 22:26:26 +08:00
|| xy_streql (command, "-h")
|| xy_streql (command, "help")
|| xy_streql (command, "-help")
|| xy_streql (command, "--help"))
2024-04-25 16:33:17 +08:00
{
2024-06-05 09:18:48 +08:00
cli_print_help ();
2024-04-25 16:33:17 +08:00
return 0;
}
2023-08-28 23:10:09 +08:00
2024-06-05 09:24:39 +08:00
/* chsrc -v */
2024-09-26 19:51:55 +08:00
else if ( xy_streql (command, "-v")
2024-08-22 22:26:26 +08:00
|| xy_streql (command, "-version")
|| xy_streql (command, "--version")
|| xy_streql (command, "ver")
|| xy_streql (command, "version"))
2024-06-05 09:24:39 +08:00
{
cli_print_version ();
return 0;
}
/* chsrc list */
2024-09-26 19:51:55 +08:00
else if ( xy_streql (command, "list")
2024-08-22 22:26:26 +08:00
|| xy_streql (command, "l")
|| xy_streql (command, "ls"))
2024-04-25 16:33:17 +08:00
{
2024-06-05 09:18:48 +08:00
if (argc < cli_arg_Target_pos)
2024-04-25 16:33:17 +08:00
{
2024-08-17 06:46:06 +08:00
cli_print_available_mirrors ();
2024-08-17 07:21:47 +08:00
br();
2024-08-17 06:46:06 +08:00
cli_print_supported_targets ();
2024-04-25 16:33:17 +08:00
}
else
{
2024-06-05 09:18:48 +08:00
target = argv[cli_arg_Target_pos];
2024-07-31 12:38:52 +08:00
if (xy_streql (target, "mirrors") || xy_streql (target, "mirror"))
2024-04-25 16:33:17 +08:00
{
2024-08-17 06:46:06 +08:00
cli_print_available_mirrors (); return 0;
2024-04-25 16:33:17 +08:00
}
2024-07-31 12:38:52 +08:00
else if (xy_streql (target, "targets") || xy_streql (target, "target"))
2024-04-25 16:33:17 +08:00
{
2024-08-17 06:46:06 +08:00
cli_print_supported_targets (); return 0;
2024-04-25 16:33:17 +08:00
}
2024-07-31 12:38:52 +08:00
else if (xy_streql (target, "os"))
2024-04-25 16:33:17 +08:00
{
2024-08-17 06:46:06 +08:00
cli_print_supported_os (); return 0;
2024-04-25 16:33:17 +08:00
}
2024-07-31 12:38:52 +08:00
else if (xy_streql (target, "lang") || xy_streql (target, "pl") || xy_streql (target, "language"))
2024-04-25 16:33:17 +08:00
{
2024-08-17 06:46:06 +08:00
cli_print_supported_pl(); return 0;
2024-04-25 16:33:17 +08:00
}
2024-07-31 12:38:52 +08:00
else if (xy_streql (target, "ware") || xy_streql (target, "software"))
2024-04-25 16:33:17 +08:00
{
2024-08-17 06:46:06 +08:00
cli_print_supported_wr (); return 0;
2024-04-25 16:33:17 +08:00
}
2024-08-18 10:03:00 +08:00
matched = get_target (target, TargetOp_List_Config, NULL);
2024-04-25 16:33:17 +08:00
if (!matched) goto not_matched;
}
return 0;
}
2024-08-23 12:31:27 +08:00
#define MSG_EN_USE_LIST_TARGETS "Use `chsrc list targets` to see all supported targets"
#define MSG_CN_USE_LIST_TARGETS "使用 chsrc list targets 查看所有支持的目标"
2024-08-18 10:03:00 +08:00
/* chsrc measure */
2024-09-26 19:51:55 +08:00
else if ( xy_streql (command, "measure")
2024-08-22 22:26:26 +08:00
|| xy_streql (command, "mea")
|| xy_streql (command, "m")
|| xy_streql (command, "cesu")
|| xy_streql (command, "ce")
|| xy_streql (command, "c"))
2024-04-25 16:33:17 +08:00
{
2024-06-05 09:18:48 +08:00
if (argc < cli_arg_Target_pos)
2024-04-25 16:33:17 +08:00
{
2024-08-23 12:31:27 +08:00
char *msg = CliOpt_InEnglish ? "Please provide the target name you want to measure. " MSG_EN_USE_LIST_TARGETS
: "请您提供想要测速源的目标名。" MSG_CN_USE_LIST_TARGETS;
chsrc_error (msg);
2024-04-25 16:33:17 +08:00
return 1;
}
ProgMode_CMD_Measure = true;
2024-06-05 09:18:48 +08:00
target = argv[cli_arg_Target_pos];
2024-08-18 10:03:00 +08:00
matched = get_target (target, TargetOp_Measure_Source, NULL);
2024-04-25 16:33:17 +08:00
if (!matched) goto not_matched;
return 0;
}
/* chsrc get */
2024-09-26 19:51:55 +08:00
else if ( xy_streql (command, "get")
2024-08-22 22:26:26 +08:00
|| xy_streql (command, "g"))
2024-04-25 16:33:17 +08:00
{
2024-06-05 09:18:48 +08:00
if (argc < cli_arg_Target_pos)
2024-04-25 16:33:17 +08:00
{
2024-08-23 12:31:27 +08:00
char *msg = CliOpt_InEnglish ? "Please provide the target name you want to view the source. " MSG_EN_USE_LIST_TARGETS
: "请您提供想要查看源的目标名。" MSG_CN_USE_LIST_TARGETS;
chsrc_error (msg);
2024-04-25 16:33:17 +08:00
return 1;
}
2024-06-05 09:18:48 +08:00
target = argv[cli_arg_Target_pos];
2024-06-05 12:50:43 +08:00
matched = get_target (target, TargetOp_Get_Source, NULL);
2024-04-25 16:33:17 +08:00
if (!matched) goto not_matched;
return 0;
}
/* chsrc set */
2024-09-26 19:51:55 +08:00
else if ( xy_streql (command, "set")
2024-08-22 22:26:26 +08:00
|| xy_streql (command, "s"))
2024-04-25 16:33:17 +08:00
{
2024-06-05 09:18:48 +08:00
if (argc < cli_arg_Target_pos)
2024-04-25 16:33:17 +08:00
{
2024-08-23 12:31:27 +08:00
char *msg = CliOpt_InEnglish ? "Please provide the target name you want to set the source. " MSG_EN_USE_LIST_TARGETS
: "请您提供想要设置源的目标名。" MSG_CN_USE_LIST_TARGETS;
chsrc_error (msg);
2024-04-25 16:33:17 +08:00
return 1;
}
2023-09-03 17:57:45 +08:00
2024-06-05 09:18:48 +08:00
target = argv[cli_arg_Target_pos];
char *mirrorCode_or_url = NULL;
2024-07-31 12:38:52 +08:00
if (argc >= cli_arg_Mirror_pos)
{
mirrorCode_or_url = xy_strdup (argv[cli_arg_Mirror_pos]);
}
2024-06-05 12:50:43 +08:00
matched = get_target (target, TargetOp_Set_Source, mirrorCode_or_url);
2024-04-25 16:33:17 +08:00
if (!matched) goto not_matched;
return 0;
2023-09-03 17:57:45 +08:00
}
/* chsrc reset */
2024-09-26 19:51:55 +08:00
else if ( xy_streql (command, "reset")
2024-08-22 22:26:26 +08:00
|| xy_streql (command, "rest")
|| xy_streql (command, "r"))
{
if (argc < cli_arg_Target_pos)
{
2024-08-23 12:31:27 +08:00
char *msg = CliOpt_InEnglish ? "Please provide the target name you want to reset the source. " MSG_EN_USE_LIST_TARGETS
: "请您提供想要重置源的目标名。" MSG_CN_USE_LIST_TARGETS;
chsrc_error (msg);
return 1;
}
2024-09-04 17:03:00 +08:00
ProgMode_CMD_Reset = true;
target = argv[cli_arg_Target_pos];
matched = get_target (target, TargetOp_Reset_Source, NULL);
if (!matched) goto not_matched;
return 0;
}
2024-06-08 13:14:14 +08:00
/* chsrc issue */
2024-09-26 19:51:55 +08:00
else if ( xy_streql (command, "issue")
2024-08-22 22:26:26 +08:00
|| xy_streql (command, "issues")
|| xy_streql (command, "isue")
|| xy_streql (command, "i"))
2024-06-08 13:14:14 +08:00
{
cli_print_issues ();
return 0;
}
/* 不支持的命令 */
else
2024-04-25 16:33:17 +08:00
{
2024-08-23 12:31:27 +08:00
char *msg1 = CliOpt_InEnglish ? "Unsupported command `" : "不支持的命令 ";
char *msg2 = CliOpt_InEnglish ? "`. Use `chsrc help` to view usage" : ". 请使用 chsrc help 查看使用方式";
chsrc_error (xy_strjoin (3, msg1, command, msg2));
2024-04-25 16:33:17 +08:00
return 1;
}
2023-09-01 17:17:45 +08:00
not_matched:
2024-04-25 16:33:17 +08:00
if (!matched)
{
2024-08-23 12:31:27 +08:00
char *msg = CliOpt_InEnglish ? "Unsupported target. " MSG_EN_USE_LIST_TARGETS
: "暂不支持的换源目标。" MSG_CN_USE_LIST_TARGETS;
chsrc_error (msg);
2024-04-25 16:33:17 +08:00
return 1;
}
2023-08-28 22:21:33 +08:00
}