Giter VIP home page Giter VIP logo

clop's Introduction

简介

if/else 工程师,个人兴趣=研究协议

开发环境

vscode + vim 模式

语言 go为主力,正在学习rust。

开源项目

协议

websocket

quickws 满足高tps场景的websocket协议库,包含客户端,服务端, 5800h cpu tps可以到47-48w/s

greatws 针对海量websocket链接特别优化,基于kqueue和epoll, 100w websocket连接,只需500-700MB内存(早期阶段)

http

httparser 高性能http 1.1解析器,为你的异步io库插上http1.1解析的翅膀, 每秒可以处理630.15MB/s流量

TODO

。。。

util包

gout restful api和 http benchmark lib

clop 命令行解析器,只要会写struct,定义tag,轻松实现gnu 风格命令行

pcurl 解析curl命令库,生成*http.Request,让你的应用瞬间秒懂curl。

timer 基于5级时间轮实现的定时器,性能可观,fast, fast, fast

pcopy 高性能深度拷贝库。相比上个版本提升4-10倍性能

brouter 高性能http router库,API风格类似httprouter,比1.3.0的httprouter快50-60%的样子,比开发版本的httprouter慢一点,大约是 92-95%的性能

clop's People

Contributors

greyh4t avatar guonaihong avatar wangxin008 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

clop's Issues

实现args功能

在shell里面,没有被当成命令行选项的参数,一般另有用途,clop提供args tag,用于保存下面的r.go pool.c会存放至cat.Args变量里。

cat -n r.go -T pool.c

clop用法

 type cat struct {
        NumberNonblank bool `clop:"-b;--number-nonblank"
                            usage:"number nonempty output lines, overrides"`

        ShowEnds bool `clop:"-E;--show-ends"
                            usage:"display $ at end of each line"`

        Number bool `clop:"-n;--number"
                            usage:"number all output lines"`

        SqueezeBlank bool `clop:"-s;--squeeze-blank"
                            usage:"suppress repeated empty output lines"`

        ShowTab bool `clop:"-T;--show-tabs"
                            usage:"display TAB characters as ^I"`

        ShowNonprinting bool `clop:"-v;--show-nonprinting"
                            usage:"use ^ and M- notation, except for LFD and TAB" `

        Args []string `clop:"args"`
    }   

c := cat{}
clop.Bind(&c)

about,version,usage信息补全

about,version,usage信息补全

v0.0.1
a quick start example
Usage:
     [Flags] [Options] <input> <CLOP-FORMAT> <files> 
  • TODO 测试About和Versions可以支持的类型
    不支持空结构体。

子母命令支持

伪代码如下:

package main

import (
    "fmt"
    "github.com/guonaihong/clop"
)

type add struct {
    All   bool `clop:"-A; --all" usage:"add changes from all tracked and untracked files"`
    Force bool `clop:"-f; --force" usage:"allow adding otherwise ignored files"`
}

type mv struct {
    Force bool `clop:"-f; --force" usage:"allow adding otherwise ignored files"`
}

type git struct {
    Add add `clop:"subcommand=add" usage:"Add file contents to the index"`
    Mv  mv  `clop:"subcommand=mv" usage:"Move or rename a file, a directory, or a symlink"`
}

func main() {
    g := git{}
    err := clop.Bind(&g)
    fmt.Printf("err = %v, %#v\n", err, g)
    fmt.Printf("mv(%t) add(%t)\n", clop.IsSetSubcommand("mv"), clop.IsSetSubcommand("add"))
}

todo
完善提示信息
fix测试代码

省略clop tag,取首字母为短远项,取全部字段为长选项

伪代码如下
如果不传递clop tag,在命令行里面,这个结构体成员变量,首字母(小写) == 短选项,成员变量名等于长选项,单个字母的只有短选项。

type log struct{
    Level `usage:"log level"`
   // Level `clop:"-l; --level" usage:"log level"`
}

增加short, long, $from_var_name模板用法

新增feature

比如

type client struct {
	HotWorld   bool `clop:"-h;--hot-world" usage:"hot world"`
	Grammar    bool `clop:"-g;--grammar" usage:"grammar"`
	SmallModel bool `clop:"-s;--small-model" usage:"small model"`
}

可以写成,如下,效果是一样的。

type client struct {
	HotWorld   bool `clop:"short;long" usage:"$from_var_name"`
	Grammar    bool `clop:"short;long" usage:"$from_var_name"`
	SmallModel bool `clop:"short;long" usage:"$from_var_name"`
}

出发点

有模板代码的feature,可以使用vim的列模式,快速实现命令行选项。

修改

$from_var_name 暂且不实现。

必选项标记支持

加上这个选项,这个命令行选项,必须传入。

package main

import (
	"github.com/guonaihong/clop"
)

type gurl struct {
	Url  string `clop:"-u; --url" usage:"url" valid:"required"`
	Text string `clop:"-t; --text" usage:"text" valid:"required"`
}

func main() {

	g := gurl{}
	clop.Bind(&g)
	//fmt.Printf("%s\n", err)
}

支持导入flag库的调用方式

思路

通过ast包, 遍历go的代码, 然后生成clop 结构体数据.
直接使用正则表达式做
还是使用ast包做, 正则表达式容易做出效果, 但是最后收敛问题需要花费太多的时间

设计总目标

设计总目标

  • 极致压榨基于struct的方式(暂时不考虑回调函数和链式的做法)
  • 支持posix规范
  • 以gnu 110多个命令+curl+git作为最终测试验收标准

扩展设计args行为

思路笔记

  • 是否有必要支持多args参数?
    #3 第一版本的args设计里面,只支持一个args参数。最后想了要,有必要,如果支持多args,可以更方便地bind变量,这里面加个约束。slice的args参数只能放到最后一个,不支持两个复合类型的args的变量。

需要验收通过的

TODO 和错误处理一起
加上args是可选参数还是必选参数?

  • slice args+basetype行为=报错
  • basetype...+slice args行为=正确。
  • slice args+slice args 行为=报错。
  • slice选项+slice args = slice选项得到大部分参数,slice args 得到最后一个参数

只有环境变量,没有命令行选项的在help如何体现?

package main

import (
	"fmt"
	"github.com/guonaihong/clop"
)

type env struct {
	OmpNumThread string `clop:"env=omp_num_thread" usage:"omp num thread"`
	Path         string `clop:"env=XPATH" usage:"xpath"`
	Max          int    `clop:"env=MAX" usage:"max thread"`
}

func main() {
	e := env{}
	clop.Bind(&e)
	fmt.Printf("%#v\n", e)
}

输出


Usage:
    ./use_env <omp_num_thread> <XPATH> <MAX> 
Args:
    <omp_num_thread>    omp num thread [env: omp_num_thread=]
    <XPATH>             xpath [env: XPATH=]
    <MAX>               max thread [env: MAX=]

需要通过的case

args

  • slice args+basetype行为=报错
  • basetype...+slice args行为=正确。
  • slice args+slice args 行为=报错。
  • slice选项+slice args = slice选项得到大部分参数,slice args 得到最后一个参数

v0.0.1版本计划

开发周期

2020-3-30

功能规划

#2 完成一个最简单的解析器
#3 实现收集args参数功能
#7 实现--help输出帮助信息
#14 扩展解析器,在处理slice变量时--新增贪婪模式
#11 支持环境变量
#20 about,version,usage信息补全
#19 子命令支持
#21 一个最精简的readme.md
#22 新增Usage接口
#23 help 信息里面的Usage 如设置Subcommand要显示出来
#24 help显示里面的每个子命令都要显示procName
#10 必选项标记支持
#25 测试valid里面tag写错的情况
#9 默认值支持
#8 未注册选项行为
#12 注册重复选项报错
#17 对于长选项是只能使用两个减号,短选项只能使用一个减号
#16 省略clop tag,取首字母为短远项,取全部字段为长选项
#5 长选项支持=等于号
#28 bugfix,数据校验和子命令结合报错
#15 只有环境变量,没有命令行选项的在help如何体现?
#30 增加ci/cd

已完成

  • #2 完成一个最简单的解析器
  • #3 实现收集args参数功能
  • #7 实现--help输出帮助信息
  • #14 扩展解析器,在处理slice变量时--新增贪婪模式
  • #11 支持环境变量
  • #20 about,version,usage信息补全
  • #19 子命令支持
  • #21 一个最精简的readme.md
  • #22 新增Usage接口
  • #23 help 信息里面的Usage 如设置Subcommand要显示出来
  • #24 help显示里面的每个子命令都要显示procName
  • #10 必选项标记支持
  • #25 测试valid里面tag写错的情况
  • #9 默认值支持
  • #8 未注册选项行为
  • #12 注册重复选项报错
  • #17 对于长选项是只能使用两个减号,短选项只能使用一个减号
  • #16 省略clop tag,取首字母为短远项,取全部字段为长选项
  • #5 短,长选项都支持=等于号
  • #28 bugfix,数据校验和子命令结合报错
  • #15 只有环境变量,没有命令行选项的在help如何体现?
  • #30 增加ci/cd

第一个小目标,完成一个最简单的解析器

完成最基本的解析器

package main

import (
    "fmt"
    "github.com/guonaihong/clop"
)

func main() {

     type cat struct {
        NumberNonblank bool `clop:"-b;--number-nonblank"
                            usage:"number nonempty output lines, overrides"`

        ShowEnds bool `clop:"-E;--show-ends"
                            usage:"display $ at end of each line"`

        Number bool `clop:"-n;--number"
                            usage:"number all output lines"`

        SqueezeBlank bool `clop:"-s;--squeeze-blank"
                            usage:"suppress repeated empty output lines"`

        ShowTab bool `clop:"-T;--show-tabs"
                            usage:"display TAB characters as ^I"`

        ShowNonprinting bool `clop:"-v;--show-nonprinting"
                            usage:"use ^ and M- notation, except for LFD and TAB" `
    }   
    c := cat{}
    clop.Bind(&c)
}

数据格式为数组时,default的数据被保留了

package main

import (
	"log"

	"github.com/guonaihong/clop"
)

type A struct {
	Name []int `clop:"-e" usage:"数组测试" valid:"required" default:"[1,2]"`
}

func main() {
	a := A{}
	err := clop.Bind(&a)
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("%+v\n", a)
}

此代码执行时,命令行输入 ./test.exe -e 3 -e 4,输出的结果是[1 2 3 4],难道不应该是[3, 4]

默认值支持

下面是伪代码

type gurl struct {
    URL string `clop:"-u; --url" usage:"url" default:"http://192.168.1.1"`
    C int `clop:"-c; -ab.c" usage:"c" default:"1"`
    Files []string `clop:"args=files" usage:"file" default:"[\"a.txt", \"b.txt\"]"`
}

数组格式参数的优化

现在添加数组格式的参数只能通过 -l 123 -l 456这种多次添加的方式实现,当数组内容比较多的时候很麻烦,是否可以支持 -l 123 456-l 123,456 这种方式呢

fix 使用slice变量,默认进入贪婪模式

  • 测试的shell命令
curl -H "h1:v1" -H "h2:v2" url
  • 定义的结构体
       type Curl struct {
               Method string   `clop:"-X; --request" usage:"Specify request command to use"`
               Header []string `clop:"-H; --header" usage:"Pass custom header(s) to server"`
               URL    string   `clop:"args=url" usage:"url"`
       }
  • 实际输出
    Header的值为 h1:v1 h2:v2 url,URL值为空
  • 需要输出
    Header的值为 h1:v1 h2:v2,URL值为url

在命令行使用重复选项报错

clop选择默认宽松的方式。(主要方便开发大量的linux命令,现有命令都是默认宽松模式)

新增once标记,如果是非slice类型变量,在命令行重复使用会报错。
伪代码如下

type D struct {
    Debug bool `clop:"-d;once" usage:"debug mod"`
}

./debug -d -d
报错

扩展解析器,在处理slice变量时--新增贪婪模式

新的解析器在处理slice类型变,需要支持多种情况,下面的-c指代选项名称

  • 第一种。
    -c "val1" -c "val2" -c "val3"
  • 第二种
    -c "val1" "val2" "val3"
  • 第三种
    -cval1 val2 val3

第2种第3种模式,只要修改结构体tag,新增greedy就行。

 type curl2 struct {
        Count []string `clop:"-c; greedy" usage:"test count"`
}   

添加subcommand的自动路由功能

如果根据IsSetSubcommand对子命令是否存在的判断结果来执行相应func,当子命令过多的时候会出现过多的冗余代码,希望内部实现关系映射,直接根据子命令做内部func的路由

未注册选项行为

$ ./unregistered -x
error: Found argument '-x' which wasn't expected, or isn't valid in this context

For more information try --help

$ ./unregistered --xx
error: Found argument '--xx' which wasn't expected, or isn't valid in this context

For more information try --help

支持环境变量

伪代码如下

   type env struct {
        Url []string `clop:"-u; --url; env=CLOP-TEST-URL" usage:"URL to work with"`
    }

e := env{}
clop.Bind(&e)

行为约束.

  • 环境变量的解析放在命令行的后面
  • 如果写了多个环境变量配置,只有最后一个才生效
  • 环境变量的值为false时,bind到结构体里面也是false

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.