CLI 命令行实用程序开发实战

CLI 命令行实用程序开发实战

  • 实验内容
  • 实验过程
    • 安装Cobra
    • 初始化
    • register实现
    • login实现
    • 文件读写
  • 实验结果

go-online地址

实验内容

  • 功能需求: 设计一组命令完成 agenda 的管理,例如:
    • agenda help :列出命令说明
    • agenda register -uUserName –password pass –[email protected] :注册用户
    • agenda help register :列出 register 命令的描述
    • agenda cm … : 创建一个会议

本次的实验只需要完成两条指令即可,我们就写用户的注册和登录。

实验过程

安装Cobra

首先需要下载cobra,我们使用命令:

go get -v github.com/spf13/cobra/cobra

如果在下载的过程中遇见了如下的问题:

Fetching https://golang.org/x/text/transform?go-get=1

https fetch failed: Get https://golang.org/x/text/transform?go-get=1: dial tcp 216.239.37.1:443: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.

这是熟悉的错误,要在 $GOPATH/src/golang.org/x 目录下用 git clone 下载 sys 和 text 项目,然后使用命令

go install github.com/spf13/cobra/cobra

安装后在 $GOBIN 下出现了 cobra 可执行程序:
CLI 命令行实用程序开发实战_第1张图片

初始化

我们在工作目录下使用如下命令创建agenda应用:

cobra init --pkg-name agenda

并添加两个指令registerlogin

cobra add register
cobra add login

register实现

这一部分主要是实现用户的注册,包括用户名、密码、邮箱、电话,主要的逻辑包含以下几个方面:

  • 用户输入的四种信息不能为空

    这个逻辑比较简单,只要我们判断字符串是否为空即可:

    if (_username == "" || _password == "" || _email == "" || _phone == "") {
        return 1
    }
    
  • 用户输入的四种信息符合基本规范

    这个主要是判断四种形式的信息是否符合正则表达式即可:

    func isValid(username, password, email, phone string) bool {
        temp1 := []byte(username)
    	val1, _ := regexp.Match("[0-9a-zA-Z]+", temp1)
    	if (!val1) {
    		fmt.Println("User name need to be digit and letter")
            return false
    	}
    	
        temp2 := []byte(password)
    	val2, _ := regexp.Match("[\\w\\!@#$^&]+", temp2)
    	if (len(password) < 4) {
    		fmt.Println("The password must be more than 4 digits")
    		return false
    	}
    	if (!val2) {
    		fmt.Println("PassWord need to be digit,letter or !@#$^&*")
            return false
    	}
    
        temp3 := []byte(email)
    	val3, _ := regexp.Match("\\w*@\\w*\\.w*", temp3)
    	if (!val3) {
    		fmt.Println("email need to match the format [email protected]")
            return false
    	}
    
        temp4 := []byte(phone)
    	val4, _ := regexp.Match("\\d{11}", temp4)
    	if (!val4) {
    		fmt.Println("phone need to be 11 digits")
            return false
    	}
    	return true
    }
    
  • 用户输入的用户名不能和已有的用户名重复

    首先我们需要获取所有的用户信息,保存在store数组中,然后依次遍历查询是否重复,这里就直接写简单一些,从头找到尾:

    func isExist(username string, store []User) bool {
        for i := 0; i < len(store); i ++ {
            if (store[i].Username == username) {
                return true
            }
        }
        return false
    }
    

写好了逻辑之后,我们就将创建好的用户信息存储到json文件中:

newuser := User{Username: _username, Password: _password, Email: _email, Phone: _phone}
store = append(store, newuser)
WriteToFile(store)

register.go文件中,只需调用entity的这几个函数进行判断即可:

var registerCmd = &cobra.Command{
	Use:   "register",
	Short: "user register",
	Long: "agenda register -u [username] -w [password] -e [email] -p [phone]",
	Run: func(cmd *cobra.Command, args []string) {
		username, _ := cmd.Flags().GetString("username")
        password, _ := cmd.Flags().GetString("password")
        email, _ := cmd.Flags().GetString("email")
        phone, _ := cmd.Flags().GetString("phone")
        state := entity.Register(username, password, email, phone)
		if (state == 1) {
			fmt.Println("Cannot input null information!")
		} else if (state == 2) {
			fmt.Println("InValid information!")
		} else if (state == 3) {
			fmt.Println("This name has been used!")
		} else if (state == 0) {
			fmt.Println("User register succeed")
		}
	},
}

login实现

这一部分是判断用户输入的用户名和密码是否匹配,主要的逻辑包括:

  • 用户名是否存在

    同样地,我们只需遍历所有的用户名即可,可以重复使用register的逻辑代码。

  • 用户名和密码是否匹配

    我们遍历找到对应的用户名,如果存储的密码和输入的密码相同,则是匹配的:

    func correct(username, password string, store []User) bool {
        for i := 0; i < len(store); i ++ {
            if (store[i].Username == username) {
                if (store[i].Password == password) {
                    return true
                } else {
                    return false
                }
            }
        }
        return false
    }
    

login.go文件中也是调用entity文件中的逻辑函数:

var loginCmd = &cobra.Command{
	Use:   "login",
	Short: "A brief description of your command",
	Long: "agenda login -u [username] -w [password]",
	Run: func(cmd *cobra.Command, args []string) {
		username,_ := cmd.Flags().GetString("username")
        password,_ := cmd.Flags().GetString("password")
        state := entity.Login(username, password)
		if (state == 1) {
			fmt.Println("The user doesn't exist!")
		} else if (state == 2) {
			fmt.Println("Incorrect password!")
		} else if (state == 0) {
			fmt.Println("Login succeed")
		}
	},
}

文件读写

我们用json数据格式保存信息,放在指定的目录下,需要时进行读取即可:

func ReadFromFile() []User {
    jsondata, err := ioutil.ReadFile("./data/user.json")
	if (err != nil) {
		fmt.Println(err)
	}
    var users []User
	json.Unmarshal(jsondata, &users)
    return users
}

func WriteToFile(users []User)  {
    os.Truncate("./data/user.json", 0)
    jsondata, err := json.Marshal(users)
    if (err != nil) {
		fmt.Println(err)
	}
    ioutil.WriteFile("./data/user.json", jsondata, os.ModeAppend)
    os.Chmod("./data/user.json", 0777)
}

实验结果

我们先对用户注册进行测试,如果格式不正确则会报错:
在这里插入图片描述
在输入正确的格式后,我们可以得到如下的结果:
在这里插入图片描述
得到的数据文件如下所示:
在这里插入图片描述
登入成功之后会显示:
在这里插入图片描述
最后,我们还需要把本地的文件放在goline上,这需要修改对应的引用路径,如下所示:
在这里插入图片描述
其中工作路径可以用pwd命令查看。
最后,我们还需要在root权限下将/home文件夹递归777权限,然后就可以正常运行了:
在这里插入图片描述
在文件中已经可以看到创建的用户了:
在这里插入图片描述

你可能感兴趣的:(CLI 命令行实用程序开发实战)