golang轻量级命令行界面框架插件库ukautz/clif的使用

Golang轻量级命令行界面框架插件库ukautz/clif的使用

ukautz/clif是一个用于快速开发命令行应用程序的Go框架。

安装

$ go get gopkg.in/ukautz/clif.v1

快速开始

基本示例

package main

import "gopkg.in/ukautz/clif.v1"

func main() {
    clif.New("My App", "1.0.0", "An example application").
        New("hello", "The obligatory hello world", func(out clif.Output) {
            out.Printf("Hello World\n")
        }).
        Run()
}

命令

命令必须有唯一的名称,并且可以有额外的参数和选项。

cmd1 := clif.NewCommand("name", "A description", callBackFunction)
cmd2 := clif.NewCommand("other", "Another description", callBackFunction2)

回调函数

回调函数可以包含任意参数。CLIF使用内置的依赖注入容器。

// 定义类型
type MyFoo struct {
    X int
}

func main() {
    // 初始化CLI
    cli := clif.New("My App", "1.0.0", "An example application")

    // 注册对象实例
    foo := &MyFoo{X: 123}
    cli.Register(foo)

    // 创建使用注册实例的回调命令
    cli.NewCommand("foo", "Call foo", func (foo *MyFoo) {
        // 使用foo做一些事情
    })

    cli.Run()
}

参数和选项

  • 参数:位于命令名称之后,通过位置识别
  • 选项:没有固定位置,通过--opt-name-O识别

参数示例

cmd := clif.NewCommand("hello", "A description", callBackFunction)
    .NewArgument("name", "Name for greeting", "", true, false)

arg := cmd.NewAgument("other", "Something ..", "default", false, true)
cmd.AddArgument(arg)

选项示例

cmd := clif.NewCommand("hello", "A description", callBackFunction)
    .NewOption("name", "n", "Name for greeting", "", true, false)

arg := cmd.NewOption("other", "O", "Something ..", "default", false, true)
cmd.AddOption(arg)

输入和输出

输入(Input)

func callbackFunctionI(in clif.Input) {
    // 任何输入都可以
    foo := in.Ask("What is a foo", nil)

    // 验证输入
    name := in.Ask("Who are you? ", func(v string) error {
        if len(v) > 0 {
            return nil
        } else {
            return fmt.Errorf("Didn't catch that")
        }
    })

    // 正则验证简写
    count := in.AskRegex("How many? ", regexp.MustCompile(`^[0-9]+$`))
}

输出(Output)

表格输出

var (
    headers := []string{"Name", "Age", "Force"}
    rows = [][]string{
        {"<important>Yoda<reset>", "Very, very old", "Like the uber guy"},
        {"<important>Luke Skywalker<reset>", "Not that old", "A bit, but not that much"},
    }
)

func callbackFunction(out clif.Output) {
    table := out.Table(headers)
    table.AddRows(rows)
    fmt.Println(table.Render())
}

进度条

func cmdProgress(out clif.Output) error {
    pbs := out.ProgressBars()
    pb, _ := pbs.Init("default", 200)
    pbs.Start()
    var wg sync.WaitGroup
    wg.Add(1)
    go func(b clif.ProgressBar) {
        defer wg.Done()
        for i := 0; i < 200; i++ {
            b.Increment()
            <-time.After(time.Millisecond * 100)
        }
    }(pb)
    wg.Wait()
    <-pbs.Finish()
}

完整示例

package main

import (
    "gopkg.in/ukautz/clif.v1"
    "fmt"
    "time"
    "sync"
)

func main() {
    cli := clif.New("My CLI", "1.0.0", "A demo CLI application")

    // 添加hello命令
    cli.New("hello", "Say hello", func(out clif.Output) {
        out.Printf("<success>Hello World!</success>\n")
    })

    // 添加带参数的命令
    cli.New("greet", "Greet someone", func(c *clif.Command) {
        name := c.Argument("name").String()
        fmt.Printf("Hello, %s!\n", name)
    }).NewArgument("name", "Name to greet", "", true, false)

    // 添加进度条演示命令
    cli.New("progress", "Show progress bar", func(out clif.Output) {
        pbs := out.ProgressBars()
        pb, _ := pbs.Init("Processing", 100)
        pbs.Start()
        
        var wg sync.WaitGroup
        wg.Add(1)
        go func() {
            defer wg.Done()
            for i := 0; i < 100; i++ {
                pb.Increment()
                time.Sleep(50 * time.Millisecond)
            }
        }()
        wg.Wait()
        <-pbs.Finish()
    })

    cli.Run()
}

这个示例展示了ukautz/clif框架的基本用法,包括创建命令、处理参数、使用输出格式化和进度条等功能。


更多关于golang轻量级命令行界面框架插件库ukautz/clif的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang轻量级命令行界面框架插件库ukautz/clif的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


ukautz/clif - Golang轻量级命令行界面框架

ukautz/clif 是一个轻量级的 Go 语言命令行界面(CLI)框架,它提供了简单易用的 API 来构建命令行应用程序。下面我将详细介绍它的主要功能和使用方法。

主要特性

  1. 简单易用的 API
  2. 支持命令、选项和参数
  3. 自动生成帮助信息
  4. 支持子命令
  5. 轻量级,无外部依赖

安装

go get github.com/ukautz/clif

基本使用示例

1. 创建简单命令

package main

import (
	"fmt"
	"github.com/ukautz/clif"
)

func main() {
	// 创建新的 CLI 应用
	cli := clif.New("My CLI App", "1.0.0", "A simple CLI application example")
	
	// 添加一个命令
	cli.Add(clif.NewCommand("greet", "Greet someone", func(c *clif.Command) {
		// 添加命令参数
		c.AddArgument(clif.NewArgument("name", "Name to greet", "", true, false))
		
		// 添加命令选项
		c.AddOption(clif.NewOption("shout", "s", "Shout the greeting", false, false))
		
		// 命令执行逻辑
		c.SetFunc(func(in clif.Input, out clif.Output) {
			name := in.Argument("name").String()
			greeting := fmt.Sprintf("Hello, %s!", name)
			
			if in.Option("shout").Bool() {
				greeting = fmt.Sprintf("HELLO, %s!!!", name)
			}
			
			out.Printf(greeting + "\n")
		})
	}))
	
	// 运行 CLI 应用
	cli.Run()
}

2. 使用子命令

package main

import (
	"fmt"
	"github.com/ukautz/clif"
)

func main() {
	cli := clif.New("File Manager", "1.0.0", "A simple file manager CLI")
	
	// 创建父命令
	fileCmd := clif.NewCommand("file", "File operations", nil)
	
	// 添加子命令 - 创建文件
	createCmd := clif.NewCommand("create", "Create a file", func(c *clif.Command) {
		c.AddArgument(clif.NewArgument("filename", "Name of file to create", "", true, false))
		c.SetFunc(func(in clif.Input, out clif.Output) {
			filename := in.Argument("filename").String()
			out.Printf("Creating file: %s\n", filename)
			// 实际创建文件逻辑...
		})
	})
	
	// 添加子命令 - 删除文件
	deleteCmd := clif.NewCommand("delete", "Delete a file", func(c *clif.Command) {
		c.AddArgument(clif.NewArgument("filename", "Name of file to delete", "", true, false))
		c.SetFunc(func(in clif.Input, out clif.Output) {
			filename := in.Argument("filename").String()
			out.Printf("Deleting file: %s\n", filename)
			// 实际删除文件逻辑...
		})
	})
	
	// 将子命令添加到父命令
	fileCmd.Add(createCmd, deleteCmd)
	
	// 将父命令添加到CLI
	cli.Add(fileCmd)
	
	cli.Run()
}

3. 使用默认命令

package main

import (
	"fmt"
	"github.com/ukautz/clif"
)

func main() {
	cli := clif.New("Calculator", "1.0.0", "A simple calculator")
	
	// 设置默认命令(当没有指定命令时执行)
	cli.SetDefault(func(in clif.Input, out clif.Output) {
		out.Printf("Welcome to Calculator CLI!\n")
		out.Printf("Use 'add', 'subtract', 'multiply' or 'divide' commands.\n")
	})
	
	// 添加计算命令
	cli.Add(clif.NewCommand("add", "Add two numbers", func(c *clif.Command) {
		c.AddArgument(clif.NewArgument("a", "First number", "", true, false))
		c.AddArgument(clif.NewArgument("b", "Second number", "", true, false))
		c.SetFunc(func(in clif.Input, out clif.Output) {
			a := in.Argument("a").Int()
			b := in.Argument("b").Int()
			out.Printf("Result: %d\n", a + b)
		})
	}))
	
	cli.Run()
}

4. 使用选项和参数验证

package main

import (
	"fmt"
	"github.com/ukautz/clif"
	"strconv"
)

func main() {
	cli := clif.New("User Manager", "1.0.0", "Manage user accounts")
	
	cli.Add(clif.NewCommand("create-user", "Create a new user", func(c *clif.Command) {
		// 必需参数
		c.AddArgument(clif.NewArgument("username", "Username for new user", "", true, false))
		
		// 可选参数
		c.AddArgument(clif.NewArgument("age", "User's age", "18", false, false))
		
		// 选项
		c.AddOption(clif.NewOption("admin", "a", "Make user an admin", false, false))
		
		// 自定义验证器
		c.AddValidator("age", func(name, value string) error {
			if _, err := strconv.Atoi(value); err != nil {
				return fmt.Errorf("age must be a number")
			}
			return nil
		})
		
		c.SetFunc(func(in clif.Input, out clif.Output) {
			username := in.Argument("username").String()
			age := in.Argument("age").Int()
			isAdmin := in.Option("admin").Bool()
			
			out.Printf("Creating user:\n")
			out.Printf("  Username: %s\n", username)
			out.Printf("  Age: %d\n", age)
			out.Printf("  Admin: %v\n", isAdmin)
		})
	}))
	
	cli.Run()
}

高级功能

1. 自定义输出格式化

package main

import (
	"github.com/ukautz/clif"
)

func main() {
	cli := clif.New("Formatter Demo", "1.0.0", "Demonstrates output formatting")
	
	// 自定义格式化输出
	formatter := clif.NewDefaultFormatter()
	formatter.AddStyle("warning", clif.Style{Color: "yellow", Options: []string{"bold"}})
	
	cli.SetOutput(clif.NewOutput(formatter))
	
	cli.Add(clif.NewCommand("demo", "Demo formatting", func(c *clif.Command) {
		c.SetFunc(func(in clif.Input, out clif.Output) {
			out.Printf("<warning>This is a warning message!</warning>\n")
			out.Printf("Normal message\n")
		})
	}))
	
	cli.Run()
}

2. 使用钩子(Hooks)

package main

import (
	"fmt"
	"github.com/ukautz/clif"
)

func main() {
	cli := clif.New("Hook Demo", "1.0.0", "Demonstrates command hooks")
	
	cli.Add(clif.NewCommand("demo", "Demo hooks", func(c *clif.Command) {
		// 前置钩子
		c.AddBefore(func(in clif.Input, out clif.Output) error {
			out.Printf("This runs BEFORE the command\n")
			return nil
		})
		
		// 后置钩子
		c.AddAfter(func(in clif.Input, out clif.Output) error {
			out.Printf("This runs AFTER the command\n")
			return nil
		})
		
		c.SetFunc(func(in clif.Input, out clif.Output) {
			out.Printf("This is the main command logic\n")
		})
	}))
	
	cli.Run()
}

总结

ukautz/clif 是一个简单但功能齐全的 Go 语言 CLI 框架,适合需要轻量级解决方案的项目。它提供了:

  1. 清晰的命令、参数和选项定义
  2. 自动生成的帮助信息
  3. 子命令支持
  4. 输入验证
  5. 自定义输出格式化
  6. 命令钩子

对于更复杂的 CLI 应用,你可能需要考虑更成熟的框架如 Cobra,但对于大多数简单到中等复杂度的 CLI 工具,ukautz/clif 提供了一个很好的平衡点。

回到顶部