为了过一个愉快的周四,我用Go做了一款命令行

我像麋鹿一样在林荫中走着,为着自己的香气而发狂;夜晚是五月正中的夜晚,清风是南国的清风; 我迷路了,我游荡着,我寻求那得不到的东西,我得到了我所没有寻求的东西。 ------ 泰戈尔

前言

每周四,在群里总是会看到一些疯狂星期四的小故事,而且个个的小故事还挺有趣,但是让我这样的人肯定是编不出来了,在想刚好在学习Go,是不是可以怎么操作一下,写个命令行来获取周四文案啥的,这样就不用自己去编了。既然有了想法那就开干

准备

源码地址,结合看最好,下面代码并不完全,大佬们有好的想法,欢迎issues,pr,也欢迎star,一起整活

  1. 了解使用Go写命令行的库
  2. 找一个生成疯狂星期四文案的接口(后期也可以做自动生成)
  3. 通过特定的命令来调用这个接口并拿到这个文案

在这里我了解到一个用Go做命令行的流行库cobra,据官方说这个被用在了很多大型项目,像Kubernetes, Hugo, GitHub CLI等等

找到的免费生成疯狂星期四文案的接口https://api.jixs.cc/api/wenan-fkxqs/index.php

实现

首先量化需求,既然已接口的形式的话,其实无非就是调用接口,拿到返回值了,只是把这个步骤放在了用户命令有对应操作之后执行,明确需求了,就可以开始写代码了

  1. 使用Go调用这个API,拿到返回值并返回
Go 复制代码
package cmd

import (
	"io"
	"log"
	"net/http"
)

// Fetch 发起请求
func Fetch() string {
	client := &http.Client{}
	req, _ := http.NewRequest("GET", "https://api.jixs.cc/api/wenan-fkxqs/index.php", nil)
	res, err := client.Do(req)
	if err != nil {
		log.Fatal("Http get error is ", err)
	}
	if res.StatusCode != http.StatusOK {
		log.Fatal("Http status code is ", res.StatusCode)
	}
	defer func(Body io.ReadCloser) {
		err := Body.Close()
		if err != nil {
			log.Fatal(err)
		}
	}(res.Body)
	bytes, err := io.ReadAll(res.Body)
	if err != nil {
		return ""
	}
	return string(bytes)
}
  1. 使用Cobra做一个特定命令行
Go 复制代码
package cmd

import (
	"fmt"
	"github.com/spf13/cobra"
	"os"
)

var ThursdayCmd = &cobra.Command{
	Use:   "Thursday [文案]",
	Short: "crazy Thursday",
	Long:  `crazy Thursday`,
	Run: func(cmd *cobra.Command, args []string) {
		res := Fetch()
		Print(res)
		fmt.Println(res)
	},
}

var rootCmd = &cobra.Command{
	Use: "ct",
}

func Execute() {
	rootCmd.AddCommand(ThursdayCmd)
	rootCmd.SetHelpCommand(ThursdayCmd)
	if err := rootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

这样当我们执行 go run main.go Thursday 后会在控制台打印出获取到的文案

但是我使用 GoLand 在这一步有点问题,就是当文案特别长的时候,他在控制台还是会强行显示一行,无法复制到全部,所以这时想起一种解决方法,那就是将文案存入一个txt文件中,这样就可以啦。

  1. 生成文件夹,将结果存入
Go 复制代码
package cmd

import (
	"fmt"
	"log"
	"os"
)

func Print(res string) {
	// 创建文件
	file, err := os.Create("./output/output.txt")
	if err != nil {
		fmt.Println("无法创建文件:", err)
		return
	}
	defer func(file *os.File) {
		err := file.Close()
		if err != nil {
			log.Fatal(err)
		}
	}(file)

	// 将内容写入文件
	_, err = file.WriteString(res)
	if err != nil {
		fmt.Println("无法写入文件:", err)
		return
	}

	fmt.Println("内容已成功写入文件 output.txt")
}

到此基本上就完成了,算是一个练习的小demo吧,可以拿着这个去和群友欢乐对线吧!

效果

相关推荐
孔令飞12 小时前
企业智能化升级:智能体平台设计和实现
云原生·go·ai编程
学长毕设12 小时前
基于SpringBoot的野生动物公益保护平台设计与实现-附源码
java·spring boot·后端
梦里寻码12 小时前
我用 NestJS + Vue3 写了一套完整的研发管理系统(58 表 / 229 API / 130 项断言,全开源
前端·后端·算法
鶴哥只手遮天12 小时前
《Redis 8.10.3 深度剖析》系列 ·第 10 章 Hash 一:`listpack`、`hashtable` 与 `LISTPACK_EX`
redis·后端·开源
johnjincaaaa12 小时前
WebAssembly 逆向实战:从 0 搞懂猿人学第 15 题
后端
Gopher_HBo13 小时前
Go CPU 剖析:四角色白话机制 + 实测实验
后端
猿人谷13 小时前
Surrogate Model:让进化算法学会“预测”,为什么它正在成为智能优化的重要技术?
后端·算法·架构
the局外人13 小时前
LangChain ToolRuntime 入门:context、state 与 store 的实际用法
后端·langchain·agent
回家路上绕了弯13 小时前
当 AI 越来越能干,我们如何理解自己的价值?
后端
陈随易14 小时前
Node.js 2026上半年都有哪些性能提升?
前端·后端·程序员