| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- // Copyright 2015 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- package main
- //go:generate gomobile help documentation doc.go
- import (
- "bufio"
- "bytes"
- "flag"
- "fmt"
- "html/template"
- "io"
- "log"
- "os"
- "os/exec"
- "unicode"
- "unicode/utf8"
- )
- var (
- gomobileName = "gomobile"
- goVersion string
- )
- const minimumGoMinorVersion = 18
- func printUsage(w io.Writer) {
- bufw := bufio.NewWriter(w)
- if err := usageTmpl.Execute(bufw, commands); err != nil {
- panic(err)
- }
- bufw.Flush()
- }
- func main() {
- gomobileName = os.Args[0]
- flag.Usage = func() {
- printUsage(os.Stderr)
- os.Exit(2)
- }
- flag.Parse()
- log.SetFlags(0)
- args := flag.Args()
- if len(args) < 1 {
- flag.Usage()
- }
- if args[0] == "help" {
- if len(args) == 3 && args[1] == "documentation" {
- helpDocumentation(args[2])
- return
- }
- help(args[1:])
- return
- }
- if _, err := ensureGoVersion(); err != nil {
- fmt.Fprintf(os.Stderr, "%s: %v\n", gomobileName, err)
- os.Exit(1)
- }
- for _, cmd := range commands {
- if cmd.Name == args[0] {
- cmd.flag.Usage = func() {
- cmd.usage()
- os.Exit(1)
- }
- cmd.flag.Parse(args[1:])
- if err := cmd.run(cmd); err != nil {
- msg := err.Error()
- if msg != "" {
- fmt.Fprintf(os.Stderr, "%s: %v\n", os.Args[0], err)
- }
- os.Exit(1)
- }
- return
- }
- }
- fmt.Fprintf(os.Stderr, "%s: unknown subcommand %q\nRun 'gomobile help' for usage.\n", os.Args[0], args[0])
- os.Exit(2)
- }
- func ensureGoVersion() (string, error) {
- if goVersion != "" {
- return goVersion, nil
- }
- goVersionOut, err := exec.Command("go", "version").CombinedOutput()
- if err != nil {
- return "", fmt.Errorf("'go version' failed: %v, %s", err, goVersionOut)
- }
- var minor int
- if _, err := fmt.Sscanf(string(goVersionOut), "go version go1.%d", &minor); err != nil {
- // Ignore unknown versions; it's probably a devel version.
- return "", nil
- }
- goVersion = fmt.Sprintf("go1.%d", minor)
- if minor < minimumGoMinorVersion {
- return "", fmt.Errorf("Go 1.%d or newer is required", minimumGoMinorVersion)
- }
- return goVersion, nil
- }
- func help(args []string) {
- if len(args) == 0 {
- printUsage(os.Stdout)
- return // succeeded at helping
- }
- if len(args) != 1 {
- fmt.Fprintf(os.Stderr, "usage: %s help command\n\nToo many arguments given.\n", gomobileName)
- os.Exit(2) // failed to help
- }
- arg := args[0]
- for _, cmd := range commands {
- if cmd.Name == arg {
- cmd.usage()
- return // succeeded at helping
- }
- }
- fmt.Fprintf(os.Stderr, "Unknown help topic %#q. Run '%s help'.\n", arg, gomobileName)
- os.Exit(2)
- }
- const documentationHeader = `// Copyright 2015 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- // Code generated by 'gomobile help documentation doc.go'. DO NOT EDIT.
- `
- func helpDocumentation(path string) {
- w := new(bytes.Buffer)
- w.WriteString(documentationHeader)
- w.WriteString("\n/*\n")
- if err := usageTmpl.Execute(w, commands); err != nil {
- log.Fatal(err)
- }
- for _, cmd := range commands {
- r, rlen := utf8.DecodeRuneInString(cmd.Short)
- w.WriteString("\n\n")
- w.WriteRune(unicode.ToUpper(r))
- w.WriteString(cmd.Short[rlen:])
- w.WriteString("\n\nUsage:\n\n\tgomobile " + cmd.Name)
- if cmd.Usage != "" {
- w.WriteRune(' ')
- w.WriteString(cmd.Usage)
- }
- w.WriteRune('\n')
- w.WriteString(cmd.Long)
- }
- w.WriteString("*/\npackage main // import \"golang.org/x/mobile/cmd/gomobile\"\n")
- if err := os.WriteFile(path, w.Bytes(), 0666); err != nil {
- log.Fatal(err)
- }
- }
- var commands = []*command{
- // TODO(crawshaw): cmdRun
- cmdBind,
- cmdBuild,
- cmdClean,
- cmdInit,
- cmdInstall,
- cmdVersion,
- }
- type command struct {
- run func(*command) error
- flag flag.FlagSet
- Name string
- Usage string
- Short string
- Long string
- }
- func (cmd *command) usage() {
- fmt.Fprintf(os.Stdout, "usage: %s %s %s\n%s", gomobileName, cmd.Name, cmd.Usage, cmd.Long)
- }
- var usageTmpl = template.Must(template.New("usage").Parse(
- `Gomobile is a tool for building and running mobile apps written in Go.
- To install:
- $ go install golang.org/x/mobile/cmd/gomobile@latest
- $ gomobile init
- At least Go 1.16 is required.
- For detailed instructions, see https://golang.org/wiki/Mobile.
- Usage:
- gomobile command [arguments]
- Commands:
- {{range .}}
- {{.Name | printf "%-11s"}} {{.Short}}{{end}}
- Use 'gomobile help [command]' for more information about that command.
- `))
|