All ProjectsHome
csb
csb/src/csb-optparse.go
csb-optparse.go Raw
package main

import (
	"fmt"
	"io/ioutil"
	"math/rand"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/docopt/docopt-go"
)

func randstring(n int) string {
	const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	b := make([]byte, n)
	for i := range b {
		b[i] = chars[rand.Int63()%int64(len(chars))]
	}
	return string(b)
}

func mkdictdir(outpath string, dict map[string]interface{}) error {
	err := os.MkdirAll(outpath, 0755)
	if err != nil {
		return err
	}
	for k, v := range dict {
		switch v.(type) {
		case map[string]interface{}:
			err = mkdictdir(filepath.Join(outpath, k), v.(map[string]interface{}))
			if err != nil {
				return err
			}
		case nil:
		default:
			f, err := os.Create(filepath.Join(outpath, k))
			if err != nil {
				return err
			}
			defer f.Close()
			_, err = fmt.Fprintf(f, "%v\n", v)
			if err != nil {
				return err
			}
		}
		//NOTE: does this go in "default" above?
		if k[0] == '<' && k[len(k)-1] == '>' && v != nil {
			k2 := strings.ToUpper(k[1 : len(k)-1])
			os.Symlink(k, filepath.Join(outpath, k2))
		}
	}
	return nil
}

func main() {
	rand.Seed(time.Now().Unix())

	buf, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error reading docstring from stdin: %s\n", err)
		os.Exit(1)
	}
	doc := string(buf)

	args, err := docopt.Parse(doc, nil, false, "", false, false)
	if err != nil {
		//TODO: This can be called if the usage is wrong, that seems to be with an empty error
		if err.Error() != "" {
			fmt.Fprintf(os.Stderr, "Error parsing docstring: %#v\n", err)
		}
		os.Exit(2)
	}

	temppath := filepath.Join(os.TempDir(), "/optparse-"+randstring(8))

	err = mkdictdir(temppath, args)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error writing output: %s\n", err)
		os.Exit(3)
	}

	fmt.Println(temppath)
}