用 go 写了个查看 html 文档的命令行工具

dart 和 rust 的语言都有文档生成功能,可以从注释中生成 html 格式的文档。但是很不巧的是,它们都没有提供 http 访问的工具。本地开发时只能对着 index.html 干瞪眼。虽说借助 docker 也能启动一个文档服务器,比如 docker run -it --rm -p 80:80 -v ./doc/api/:/usr/share/nginx/html nginx 。但敲这么长的命令确实有点考验记忆力。所以我写个脚本美滋滋 开发了个轮子,用于查看 html 文档(文档链接)。

其实 go 写这个超简单的,下面这行代码一行就能搞定。

go 复制代码
_ = http.ListenAndServe(":9090", http.FileServer(http.Dir("doc/api")))

但要将其写成工具的话,考虑的事情就多了。返回的 error 要处理;端口和本地目录要写成活的;要打印实际监听的端口(传入 ":0" 代表随机选择端口监听所以不能直接打印传入的参数)......最后就写成了这样。

go 复制代码
var (
	addr string // serve address
	dir  string // root path
)

func init() {
	flag.StringVar(&addr, "addr", "localhost:9090", "serve address")
	flag.StringVar(&dir, "dir", ".", "root path")
}

func main() {
	flag.Parse() // 标准库 flag 包自带 -h 和 --help 适配,不用单独写。

	l, err := net.Listen("tcp", addr)
	if err != nil {
		log.Fatal(err)
	}
	defer l.Close()

	ctx := context.Background()
	ctx, stop := signal.NotifyContext(ctx, os.Interrupt)
	defer stop()

	s := http.Server{
		Handler: http.FileServer(http.Dir(dir)),
	}

	var wg sync.WaitGroup // 虽然有点画蛇添足,但加了个 kill 适配。这种写法可以作为其他项目的参考。
	wg.Add(1)
	go func() {
		defer wg.Done()
    log.Printf("Serve at http://%s\n", l.Addr()) // 打印的是实际监听的端口,避免 ":0" 的问题
		err = s.Serve(l)
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()
		<-ctx.Done()
		log.Println("Closing server...")
		s.Close()
	}()

	wg.Wait()
	if !errors.Is(err, http.ErrServerClosed) {
		log.Fatal(err)
	}
}

有了这个工具后就能在本地启动工具查看文档了,以上面的 dart 工程为例:

sh 复制代码
# 克隆工程,生成文档
git clone https://github.com/kvii/kratos-plugin.git
cd kratos-plugin
dart doc

# 下载工具,启动服务
go install github.com/kvii/doc@latest
doc

# 浏览器打开 http://127.0.0.1:9090 即可访问文档

其实各个系统都能直接从命令行打开浏览器页面,比如 mac 就是 open "http://127.0.0.1:9090"。用 exec 包可以直接执行命令行命令,再适配下系统就能实现服务启动后自动打开浏览器的功能了。没加这功能的原因有二:

  1. 有的环境里可能没有浏览器,比如 linux 服务器和 devcontainer(开发容器)。
  2. 笔者开发用 vscode,它的终端对 url 有适配。ctrl + 鼠标点击就能直接浏览器里打开终端打印的 url。
相关推荐
蒙娜丽宁2 天前
Go语言错误处理详解
ios·golang·go·xcode·go1.19
qq_172805592 天前
GO Govaluate
开发语言·后端·golang·go
littleschemer3 天前
Go缓存系统
缓存·go·cache·bigcache
程序者王大川4 天前
【GO开发】MacOS上搭建GO的基础环境-Hello World
开发语言·后端·macos·golang·go
Grassto4 天前
Gitlab 中几种不同的认证机制(Access Tokens,SSH Keys,Deploy Tokens,Deploy Keys)
go·ssh·gitlab·ci
高兴的才哥5 天前
kubevpn 教程
kubernetes·go·开发工具·telepresence·bridge to k8s
少林码僧5 天前
sqlx1.3.4版本的问题
go
蒙娜丽宁6 天前
Go语言结构体和元组全面解析
开发语言·后端·golang·go
蒙娜丽宁6 天前
深入解析Go语言的类型方法、接口与反射
java·开发语言·golang·go
三里清风_6 天前
Docker概述
运维·docker·容器·go