Browse Source

initialize

pull/103/head
Unknown 12 years ago
parent
commit
feddadaeee
  1. 2
      LICENSE
  2. 277
      gpm.go
  3. 5
      i18n/gpm.toml
  4. 18
      i18n/usage_en-US.tpl

2
LICENSE

@ -1,4 +1,4 @@
Copyright (c) 2013 GPMGo members.
Copyright (c) 2013 GPMGo Members. All rights reserved.
MIT +no-false-attribs License

277
gpm.go

@ -0,0 +1,277 @@
// Copyright (c) 2013 GPMGo Members. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
// gpm(Go Package Manager) is a Go package manage tool for search, install, update and share packages in Go.
package main
import (
"bytes"
"flag"
"fmt"
"go/build"
"io"
"log"
"os"
"path/filepath"
"runtime"
"strings"
"sync"
"text/template"
"unicode"
"unicode/utf8"
"github.com/BurntSushi/toml"
)
var (
config tomlConfig
)
type tomlConfig struct {
Title, Version string
Lang string `toml:"user_language"`
}
// A Command is an implementation of a go command
// like go build or go fix.
type Command struct {
// Run runs the command.
// The args are the arguments after the command name.
Run func(cmd *Command, args []string)
// UsageLine is the one-line usage message.
// The first word in the line is taken to be the command name.
UsageLine string
// Short is the short description shown in the 'go help' output.
Short string
// Long is the long message shown in the 'go help <this-command>' output.
Long string
// Flag is a set of flags specific to this command.
Flag flag.FlagSet
// CustomFlags indicates that the command will do its own
// flag parsing.
CustomFlags bool
}
// Name returns the command's name: the first word in the usage line.
func (c *Command) Name() string {
name := c.UsageLine
i := strings.Index(name, " ")
if i >= 0 {
name = name[:i]
}
return name
}
func (c *Command) Usage() {
fmt.Fprintf(os.Stderr, "usage: %s\n\n", c.UsageLine)
fmt.Fprintf(os.Stderr, "%s\n", strings.TrimSpace(c.Long))
os.Exit(2)
}
// Runnable reports whether the command can be run; otherwise
// it is a documentation pseudo-command such as importpath.
func (c *Command) Runnable() bool {
return c.Run != nil
}
// Commands lists the available commands and help topics.
// The order here is the order in which they are printed by 'go help'.
var commands = []*Command{}
var exitStatus = 0
var exitMu sync.Mutex
func setExitStatus(n int) {
exitMu.Lock()
if exitStatus < n {
exitStatus = n
}
exitMu.Unlock()
}
func main() {
// Load configuration.
if _, err := toml.DecodeFile("i18n/gpm.toml", &config); err != nil {
fmt.Println(err)
return
}
// Load usage template by language.
f, err := os.Open("i18n/usage_" + config.Lang + ".tpl")
if err != nil {
fmt.Println(err)
return
}
defer f.Close()
// Read usage.
fi, _ := f.Stat()
usageBytes := make([]byte, fi.Size())
f.Read(usageBytes)
usageTemplate = string(usageBytes)
// Initialization.
flag.Usage = usage
flag.Parse()
log.SetFlags(0)
args := flag.Args()
if len(args) < 1 {
usage()
}
if args[0] == "help" {
help(args[1:])
return
}
// Diagnose common mistake: GOPATH==GOROOT.
// This setting is equivalent to not setting GOPATH at all,
// which is not what most people want when they do it.
if gopath := os.Getenv("GOPATH"); gopath == runtime.GOROOT() {
fmt.Fprintf(os.Stderr, "warning: GOPATH set to GOROOT (%s) has no effect\n", gopath)
} else {
for _, p := range filepath.SplitList(gopath) {
// Note: using HasPrefix instead of Contains because a ~ can appear
// in the middle of directory elements, such as /tmp/git-1.8.2~rc3
// or C:\PROGRA~1. Only ~ as a path prefix has meaning to the shell.
if strings.HasPrefix(p, "~") {
fmt.Fprintf(os.Stderr, "go: GOPATH entry cannot start with shell metacharacter '~': %q\n", p)
os.Exit(2)
}
if build.IsLocalImport(p) {
fmt.Fprintf(os.Stderr, "go: GOPATH entry is relative; must be absolute path: %q.\nRun 'go help gopath' for usage.\n", p)
os.Exit(2)
}
}
}
for _, cmd := range commands {
if cmd.Name() == args[0] && cmd.Run != nil {
cmd.Flag.Usage = func() { cmd.Usage() }
if cmd.CustomFlags {
args = args[1:]
} else {
cmd.Flag.Parse(args[1:])
args = cmd.Flag.Args()
}
cmd.Run(cmd, args)
exit()
return
}
}
fmt.Fprintf(os.Stderr, "go: unknown subcommand %q\nRun 'go help' for usage.\n", args[0])
setExitStatus(2)
exit()
}
var usageTemplate string
var helpTemplate = `{{if .Runnable}}usage: go {{.UsageLine}}
{{end}}{{.Long | trim}}
`
var documentationTemplate = `// Copyright 2011 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 THIS FILE. GENERATED BY mkdoc.sh.
// Edit the documentation in other files and rerun mkdoc.sh to generate this one.
/*
{{range .}}{{if .Short}}{{.Short | capitalize}}
{{end}}{{if .Runnable}}Usage:
go {{.UsageLine}}
{{end}}{{.Long | trim}}
{{end}}*/
package main
// NOTE: cmdDoc is in fmt.go.
`
// tmpl executes the given template text on data, writing the result to w.
func tmpl(w io.Writer, text string, data interface{}) {
t := template.New("top")
t.Funcs(template.FuncMap{"trim": strings.TrimSpace, "capitalize": capitalize})
template.Must(t.Parse(text))
if err := t.Execute(w, data); err != nil {
panic(err)
}
}
func capitalize(s string) string {
if s == "" {
return s
}
r, n := utf8.DecodeRuneInString(s)
return string(unicode.ToTitle(r)) + s[n:]
}
func printUsage(w io.Writer) {
tmpl(w, usageTemplate, commands)
}
func usage() {
printUsage(os.Stderr)
os.Exit(2)
}
// help implements the 'help' command.
func help(args []string) {
if len(args) == 0 {
printUsage(os.Stdout)
// not exit 2: succeeded at 'gpm help'.
return
}
if len(args) != 1 {
fmt.Fprintf(os.Stderr, "usage: gpm help command\n\nToo many arguments given.\n")
os.Exit(2) // failed at 'gpm help'
}
arg := args[0]
// 'go help documentation' generates doc.go.
if arg == "documentation" {
buf := new(bytes.Buffer)
printUsage(buf)
usage := &Command{Long: buf.String()}
tmpl(os.Stdout, documentationTemplate, append([]*Command{usage}, commands...))
return
}
for _, cmd := range commands {
if cmd.Name() == arg {
tmpl(os.Stdout, helpTemplate, cmd)
// not exit 2: succeeded at 'go help cmd'.
return
}
}
fmt.Fprintf(os.Stderr, "Unknown help topic %#q. Run 'gpm help'.\n", arg)
os.Exit(2) // failed at 'go help cmd'
}
var atexitFuncs []func()
func atexit(f func()) {
atexitFuncs = append(atexitFuncs, f)
}
func exit() {
for _, f := range atexitFuncs {
f()
}
os.Exit(exitStatus)
}

5
i18n/gpm.toml

@ -0,0 +1,5 @@
# This is a configuration file for gpm with toml format.
title = "gpm(Go Package Manager)"
version = "v0.0.0 Build 0516"
user_language = "en-US"

18
i18n/usage_en-US.tpl

@ -0,0 +1,18 @@
gpm is a Go package manage tool for search, install, update and share packages.
Usage:
gpm command [arguments]
The commands are:
{{range .}}{{if .Runnable}}
{{.Name | printf "%-11s"}} {{.Short}}{{end}}{{end}}
Use "gpm help [command]" for more information about a command.
Additional help topics:
{{range .}}{{if not .Runnable}}
{{.Name | printf "%-11s"}} {{.Short}}{{end}}{{end}}
Use "gpm help [topic]" for more information about that topic.
Loading…
Cancel
Save