{"id":18879323,"url":"https://github.com/jdk-plus/cli-plus","last_synced_at":"2025-06-14T19:03:57.675Z","repository":{"id":41204783,"uuid":"508732932","full_name":"JDK-Plus/cli-plus","owner":"JDK-Plus","description":"A framework for writing command-line instruction sets using java, https://jdk.plus/cli-plus/","archived":false,"fork":false,"pushed_at":"2023-04-10T06:48:29.000Z","size":1167,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-31T06:22:30.161Z","etag":null,"topics":["cli","command-line","java"],"latest_commit_sha":null,"homepage":"https://jdk.plus/cli-plus/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JDK-Plus.png","metadata":{"files":{"readme":"README-CN.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-29T14:47:48.000Z","updated_at":"2022-11-17T08:47:09.000Z","dependencies_parsed_at":"2024-11-08T06:35:24.460Z","dependency_job_id":"36d5651b-f593-43cb-8668-94ff73fc1b9d","html_url":"https://github.com/JDK-Plus/cli-plus","commit_stats":{"total_commits":25,"total_committers":2,"mean_commits":12.5,"dds":"0.16000000000000003","last_synced_commit":"502a3eb15d040208481cc46ad3fe22cb5b18a40a"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/JDK-Plus/cli-plus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JDK-Plus%2Fcli-plus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JDK-Plus%2Fcli-plus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JDK-Plus%2Fcli-plus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JDK-Plus%2Fcli-plus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JDK-Plus","download_url":"https://codeload.github.com/JDK-Plus/cli-plus/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JDK-Plus%2Fcli-plus/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259868250,"owners_count":22924230,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","command-line","java"],"created_at":"2024-11-08T06:35:18.496Z","updated_at":"2025-06-14T19:03:57.648Z","avatar_url":"https://github.com/JDK-Plus.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003cimg align=\"center\" src=\"https://jdk.plus/img/cli-plus-logo.gif\" alt=\"drawing\" style=\"width:100%;\"/\u003e\n\u003c/p\u003e\n\u003ch3 align=\"center\"\u003eCli-Plus - 使用Java编写命令行指令\u003c/h3\u003e\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/JDK-Plus/cli-plus/blob/master/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/JDK-Plus/cli-plus.svg\" /\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/JDK-Plus/cli-plus/releases\"\u003e\u003cimg src=\"https://img.shields.io/github/release/JDK-Plus/cli-plus.svg\" /\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/JDK-Plus/cli-plus/stargazers\"\u003e\u003cimg src=\"https://img.shields.io/github/stars/JDK-Plus/cli-plus.svg\" /\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/JDK-Plus/cli-plus/network/members\"\u003e\u003cimg src=\"https://img.shields.io/github/forks/JDK-Plus/cli-plus.svg\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003eCli-Plus是一款开源的使用Java编写命令行指令的框架，它具有简单、高效、易用等特点。\u003c/p\u003e\n\n\n\n# 简介\n这是一款使用java编写命令行指令集的框架。\n\n详细的使用说明请参见: https://jdk.plus/pages/2ba02f/\n\n- [English](README.md)\n\n## 如何引入\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eplus.jdk\u003c/groupId\u003e\n    \u003cartifactId\u003ecli-plus\u003c/artifactId\u003e\n    \u003cversion\u003e1.1.5\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## 一些有趣的组件\n\n![](./asset/cli-weight.gif)\n\n**通过代码执行查看效果**\n\n```bash\n(base) ➜  cli-plus git:(master) ✗ mvn -Dtest=plus.jdk.cli.weight.ProgressBarTest#testProgressBar test -q\nProcessing [========================================\u003e] 100% 128/128\n(base) ➜  cli-plus git:(master) ✗ mvn -Dtest=plus.jdk.cli.weight.TablePrinterTest#printTable test  -q\n+----+----------------+------+--------+\n| id | 姓名           | 年龄 | 性别   |\n+----+----------------+------+--------+\n| 1  | 张三💅         | 30   | 男     |\n| 2  | 李四           | 89   | 男     |\n| 3  | 王老五         | 30   | 男👵👲 |\n| 4  | chang kai shen | 30   | 女     |\n| 4  | p-moon ☺️☺️    | 30   | 未知 |\n+----+----------------+------+--------+\n```\n\n## 定义指令并指定参数\n\n**如何定义一个指令：**\n\n```java\npackage plus.jdk.cli.command;\n\nimport plus.jdk.cli.JCommandLinePlus;\nimport plus.jdk.cli.annotation.CommandLinePlus;\nimport plus.jdk.cli.annotation.CommandParameter;\nimport plus.jdk.cli.annotation.SubInstruction;\n\nimport java.util.List;\nimport java.util.Set;\n\n@CommandLinePlus(description = \"这是一个测试指令\")\npublic class TestJCommand extends JCommandLinePlus {\n\n    /**\n     * 你可以使用required参数指定该项必须输入， 调用已经实现的validate() 函数去对参数做出校验\n     */\n    @CommandParameter(name = \"u\", longName = \"uid\", needArgs = true, description = \"用户id\", required = true)\n    private Long uid;\n\n    @CommandParameter(name = \"p\", longName = \"phone\", needArgs = true, description = \"用户手机号\")\n    private String phone;\n\n    /**\n     * 对于简单类型，你可以使用, -\u003cname\u003e 或 --\u003clongName\u003e 指定参数，例如：-e xxx@jdk.plus, 或 --email xxx@jdk.plus\n     */\n    @CommandParameter(name = \"e\", longName = \"email\", needArgs = true, description = \"用户邮箱\")\n    private String email;\n\n    /**\n     * 你可以使用多个选项来指定列表,例如 : -d d1 -d d2 --data d3\n     */\n    @CommandParameter(name = \"d\", longName = \"data\", needArgs = true, description = \"参数列表\")\n    private List\u003cString\u003e dataList;\n\n    /**\n     * 你可以使用多个选项来指定列表,例如 : -s d1 -s d2 --set d3\n     */\n    @CommandParameter(name = \"s\", longName = \"set\", needArgs = true, description = \"参数集合\")\n    private Set\u003cString\u003e dataSet;\n\n    /**\n     * 针对不需要参数的选项，你可以使用Boolean类型来接收，例如指定 -h 或 --help, 该值会被赋值为true,否则为false\n     */\n    @CommandParameter(name = \"h\", longName = \"help\", needArgs = false, description = \"展示帮助信息\")\n    private Boolean help;\n\n    /**\n     * 可以使用 @SubInstruction 注解来定义子指令, 但凡指令中指定了要求执行子指令，那么将直接执行子指令中的逻辑，不再执行当前指令中的任务\n     */\n    @SubInstruction\n    @CommandParameter(name = \"sub\", longName = \"subInstruction\", needArgs = false, description = \"子指令\")\n    private TestSubInstruction subInstruction;\n\n    @Override\n    public void doInCommand() throws Exception {\n        if(help) { // 若指定 -h 或 --help 选项，则展示帮助信息\n            showUsage();\n            return;\n        }\n\n        validate();\n\n        // to do something according to Input parameters\n        // which has been assigned to a member variable\n    }\n\n    public static void main(String[] args) throws Exception {\n        TestJCommand testCommand = new TestJCommand();\n        testCommand.run(args);\n    }\n}\n```\n\n**执行**\n\n```bash\njava -jar xxx.jar -u 123567 -p \"p2data ss\" --email xxx@jdk.plus -h -s s1 -s s2 --set s3 -d d1 -d d2 --data d3\n```\n\n**按照上文所述的参数传递，执行的效果如下**\n\n![](src/main/resources/cli-plus-use.png)\n\n**配置文件**\n\n你需要在你的工程`resources`目录下指定`cli-plus.properties`。\n\n\u003e 当然，不指定也是可以的，会使用我们提供的默认配置\n\n```bash\nplus.jdk.help.header.welcome=Welcome to use cli-plus\nplus.jdk.help.header.description=The command options are described below:\nplus.jdk.help.footer.description=usage: xxx-tool -cn xx -e \"ls /root\"\nplus.jdk.help.footer.contact=mail: moon@jdk.plus\n```\n\n**如何展示指令以及子指令的帮助信息**\n\n调用封装好的`showUsage`方法可以生成帮助信息并打印，示例如下：\n\n![](https://github.com/JDK-Plus/cli-plus/blob/master/src/main/resources/demo.png)\n\n\u003e 当然，如果你对这个样式不满意，你可以重写`showUsage`方法来自定义你的指令集的帮助信息\n\n## 关于指令的shell封装\n\n```shell\n#!/bin/bash\n\n# 指定运行时的JAVA_HOME\n#JAVA_HOME=${HOME}/.biz-tools/java-se-8u41-ri\n#PATH=${JAVA_HOME}/bin:$PATH\n\nif ! which java \u003e /dev/null ; then\n    echo \"jdk 未安装, 请安装1.8以上版本\"\n    exit\nfi\n\nJAVA_VERSION=$(java -version 2\u003e\u00261 | sed '1!d' | sed -e 's/\"//g' | awk '{print $3}')\n\nif [[ ! \"${JAVA_VERSION}\" =~ ^1.8.0.* ]]; then\n    echo \"jdk版本必须大于等于1.8，请检查环境配置\"\n    exit\nfi\n\nTOOLS_JAR=$(dirname \"$0\")/tools.jar\n\n# shellcheck disable=SC2046\njava -jar \"${TOOLS_JAR}\" \"$@\" -c $(dirname \"$0\")/conf/config.properties\n```\n## 如何读取你的配置\n\n我们封装了`initializationConfig`函数来帮你读取配置,该函数可以配合`PropertiesValue`注解使用，将配置内容转为实体类的配置。\n\n**定义实体类**\n\n```java\npackage plus.jdk.cli.model;\n\nimport lombok.Data;\nimport plus.jdk.cli.annotation.PropertiesValue;\n\n@Data\npublic class CliHelpModel {\n\n    /**\n     * header欢迎使用的标题\n     */\n    @PropertiesValue(\"plus.jdk.help.header.welcome\")\n    private String headerWelcome;\n\n    /**\n     * 想要展示的banner信息\n     * 你可以使用 resource 和 path参数指定要输出的banner位置\n     */\n    @PropertiesValue(value = \"plus.jdk.help.header.banner\", resource = true, path = \"banner/banner.txt\")\n    private String banner;\n\n    /**\n     * header描述信息\n     */\n    @PropertiesValue(\"plus.jdk.help.header.description\")\n    private String headerDesc;\n\n    /**\n     * 底部描述信息\n     */\n    @PropertiesValue(\"plus.jdk.help.footer.description\")\n    private String footerDesc;\n\n    /**\n     * 联系信息\n     */\n    @PropertiesValue(\"plus.jdk.help.footer.contact\")\n    private String footerContact;\n}\n```\n\n如你所见，配置中的内容就会根据的你的注解修饰将值赋给该实体类的成员变量\n\n**读取配置：**\n\n```java\nimport static plus.jdk.cli.common.PropertiesUtil.initializationConfig;\n//...\nCliHelpModel cliHelpModel = initializationConfig(CliHelpModel.class, \"cli-plus.properties\", true);\n//...\n```\n\n## 添加对特殊类型的支持\n\n如果你的输入参数需要指定一些自定义类型(目前仅支持 `Boolean`、`Long`、`String`、`Integer`四种)。\n\n### 自定义自己的类型适配器\n\n你可以通过实现`ITypeAdapter`接口来自定义相关序列化的功能。示例如下,下面是一个关于`Long`类型序列化实现的示例：\n\n```java\npackage plus.jdk.cli.type.adapter;\n\nimport com.google.gson.TypeAdapter;\n\npublic class LongTypeAdapter implements ITypeAdapter\u003cLong\u003e {\n    @Override\n    public Long deserialize(String dataStr) {\n        if(dataStr == null) {\n            return null;\n        }\n        return Long.parseLong(dataStr);\n    }\n\n    @Override\n    public String serialize(Long data) {\n        if(data == null) {\n            return null;\n        }\n        return String.valueOf(data);\n    }\n}\n```\n\n### 注册实现的适配器\n\n```java\n@CommandLinePlus(description = \"这是一个测试指令\")\npublic class TestJCommand extends JCommandLinePlus {\n    \n    // ...\n    \n    public static void main(String[] args) throws Exception {\n        TestJCommand testCommand = new TestJCommand();\n        // 在完成调用前注册自己实现的适配器组件\n        Options.registerTypeAdapter(Long.class, new LongTypeAdapter()); \n        testCommand.run(args);\n    }\n}\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjdk-plus%2Fcli-plus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjdk-plus%2Fcli-plus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjdk-plus%2Fcli-plus/lists"}