2
0
mirror of synced 2025-02-24 15:28:28 +00:00
mobile/cmd/gomobile/main.go
Hana Kim 6837d85185 cmd/gomobile: introduce the 'clean' command
The command deletes all files under $GOPATH/pkg/gomobile dir
that keeps downloaded files and precompiled objects during the
last gomobile init run.

'gomobile clean' will be suggested in case of gomobile init
failures due to downloaded file hash mismatch.

For golang/go#15973

Change-Id: Ie9d3cfa7aef9d68931fd68f7b58d1a18c9d4b3b8
Reviewed-on: https://go-review.googlesource.com/24074
Reviewed-by: David Crawshaw <crawshaw@golang.org>
2016-06-14 16:05:07 +00:00

217 lines
4.4 KiB
Go

// 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"
"errors"
"flag"
"fmt"
"html/template"
"io"
"io/ioutil"
"log"
"os"
"os/exec"
"unicode"
"unicode/utf8"
)
var (
gomobileName = "gomobile"
goVersionOut = []byte(nil)
goVersion = go1_5
)
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 := determineGoVersion(); 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)
}
type goToolVersion int
const (
go1_5 goToolVersion = iota
go1_6
)
func determineGoVersion() error {
gobin, err := exec.LookPath("go")
if err != nil {
return errors.New("go not found")
}
goVersionOut, err = exec.Command(gobin, "version").CombinedOutput()
if err != nil {
return fmt.Errorf("'go version' failed: %v, %s", err, goVersionOut)
}
switch {
case bytes.HasPrefix(goVersionOut, []byte("go version go1.4")):
return errors.New("Go 1.5 or newer is required")
case bytes.HasPrefix(goVersionOut, []byte("go version go1.5")):
goVersion = go1_5
default:
goVersion = go1_6 // assume developers are working at tip
}
return 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.
// DO NOT EDIT. GENERATED BY 'gomobile help documentation doc.go'.
`
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 := ioutil.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 get golang.org/x/mobile/cmd/gomobile
$ gomobile init
At least Go 1.5 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.
`))