Building CLI app/package in Go

huangapple go评论148阅读模式
英文:

Building CLI app/package in Go

问题

我可能在处理这个问题时有些错误(我已经阅读了《如何编写Go代码》),但这是我想要实现的内容:我想编写一个带有CLI的Go语言包,这样用户可以在自己的程序中使用该包,也可以使用我构建的CLI。

目前我有以下结构:

mypackage/
  -api/
    -account.go // api包
    -node.go    // api包
  -main.go // main包 - 这是我想要放在`bin`文件夹中的可执行代码。

这只是一个非常简单的文件结构,因为我刚刚开始这个项目,但这就是我想要实现的,而不是构建一个包含可用代码的包,然后再构建一个单独的存储库来放置我的CLI。但是,当我尝试运行main.go时,它显示undefined: Accountaccount.go中的一个结构体)。

我现在的代码内容并不重要,因为我只是想让代码能够工作。以下是我的代码。

account.go

package api

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

type Account struct {
	email         string
}

main.go

package main

import (
    "github.com/username/mypackage/api"
	"fmt"
)

func main() {
	a := api.Account{}

	fmt.Printf("%T", a)
}

如果这是完全不好的做法,我想我只会创建两个存储库,一个包含CLI,另一个包含实际的包代码(可以通过导入在开发中由其他人使用),但我真的希望它是一个多合一的存储库。

英文:

I may be going about this incorrectly (I've read How to Write Go Code), but here's what I'm trying to achieve: I want to write a golang package that also come with a CLI, so that a user can use the package in their own programs but also use the CLI that I've built with it.

So what I have so far is this structure:

mypackage/
  -api/
    -account.go // package api
    -node.go    // package api
  -main.go // package main - this is where I want
           // the executable code to be that is put in the `bin` folder.

This is a very crude file structure as I'm just starting out the project, but that's what I'm trying to achieve rather than build a package with the usable code in it and then build a separate repo with my CLI in it. But when I attempt to run main.go, it says undefined: Account (which is a struct in account.go).

The contents of my code is unimportant right now, it's very basic as I'm just trying to get the code to work. Here's what I have.

account.go

package api

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

type Account struct {
	email         string
}

main.go

package main

import (
    "github.com/username/mypackage/api"
	"fmt"
)

func main() {
	a := Account{}

	fmt.Printf("%T", a)
}

If this is completely bad practice, I suppose I'll just make 2 repos, one with the CLI and another with my actual package code (again, usable in development by others by importing), but I'd really like it to be an all-in-one repo.

答案1

得分: 3

没有一个"唯一的方法",但常见的做法是将你的顶级仓库作为你的库 - 例如 github.com/you/somelib,然后在其下面有一个 cmd 目录,其中包含你的命令行界面(包的主要部分) - 甚至可能有很多个。

例如:

yourlib/
    api.go
    api_test.go
    handler.go
    handler_test.go
    cmd/
        command-name/
            main.go // 构建一个 "command-name" 二进制文件
        other-command/
            main.go // 构建一个 "other-command" 二进制文件

你的命令行应用程序只是你的库的使用者。用户可以通过 go get github.com/you/yourlib/... 来获取它,这将在他们的 GOPATH 上安装库和二进制文件。

Go 的源代码CamlistoreBoltDB 都使用了这种方法(还有许多其他库)。

英文:

There's no "one way", but the common approach is to make your top-level repo your library - i.e. github.com/you/somelib and then have a cmd directory underneath that contains your CLI (package mains) - there may even be many.

e.g.

yourlib/
    api.go
    api_test.go
    handler.go
    handler_test.go
    cmd/
        command-name/
            main.go // Builds a "command-name" binary
        other-command/
            main.go // Builds a "other-command" binary

Your CLI apps are just consumers of your library. Users can retrieve it via go get github.com/you/yourlib/... which will install the lib and the binaries onto their GOPATH.

The Go source itself, Camlistore and BoltDB all use this approach (amongst many other libs).

huangapple
  • 本文由 发表于 2015年6月30日 04:51:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/31125352.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定