<commit_before>package main

import (
	"fmt"
	"os"
	"os/user"
	"path/filepath"
	"strconv"

	"github.com/astaxie/beego/logs"
	"github.com/codegangsta/cli"
	"github.com/shenwei356/cnote/note"
)

var (
	funcs  map[string]func(c *cli.Context)
	DBFILE string
	log    *logs.BeeLogger
	notedb *note.NoteDB
)

func init() {
	// DBFILE
	usr, err := user.Current()
	if err != nil {
		os.Exit(1)
	}
	DBFILE = filepath.Join(usr.HomeDir, ".cnote")

	// logger
	log := logs.NewLogger(10000)
	log.SetLogger("console", "")

	funcs = make(map[string]func(c *cli.Context))
	funcs["new"] = funNew
	funcs["del"] = funDel
	funcs["use"] = funUse
	funcs["list"] = funLs
	funcs["add"] = funAdd
	funcs["rm"] = funRm
	funcs["tag"] = funTag
	funcs["search"] = funSearch

}

func getFunc(funcs map[string]func(c *cli.Context), name string) func(c *cli.Context) {
	if f, ok := funcs[name]; ok {
		return f
	} else {
		return func(c *cli.Context) {
			fmt.Printf("command %s not implemented\n", name)
		}
	}
}

func funLs(c *cli.Context) {
	list := notedb.NotesList
	for _, notename := range list {
		fmt.Println(notename)
	}
}

func funNew(c *cli.Context) {
	if len(c.Args()) == 0 {
		fmt.Println("note name needed.")
		return
	}
	if len(c.Args()) > 1 {
		fmt.Println("only one note name allowed.")
		return
	}

	notename := c.Args().First()

	err := notedb.NewNote(notename)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Printf("note \"%s\" created.\n", notename)
	fmt.Printf("current note: \"%s\".\n", notename)
}

func funDel(c *cli.Context) {
	if len(c.Args()) == 0 {
		fmt.Println("note name needed.")
		return
	}

	for _, notename := range c.Args() {
		err := notedb.DelNote(notename)
		if err != nil {
			fmt.Println(err)
			continue
		}

		// fmt.Printf("note \"%s\" deleted.\n", notename)
	}
}

func funUse(c *cli.Context) {
	if len(c.Args()) == 0 {
		fmt.Println("note name needed.")
		return
	}
	if len(c.Args()) > 1 {
		fmt.Println("only one note name allowed.")
		return
	}

	notename := c.Args().First()
	err := notedb.UseNote(notename)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Printf("current note: \"%s\".\n", notename)
}

func funAdd(c *cli.Context) {
	if len(c.Args()) != 2 {
		fmt.Println("tag and content needed.")
		return
	}

	err := notedb.AddNoteItem(c.Args()[0], c.Args()[1])
	if err != nil {
		fmt.Println(err)
	}
}

func funRm(c *cli.Context) {
	if len(c.Args()) == 0 {
		fmt.Println("item ID needed.")
		return
	}

	for _, itemid := range c.Args() {

		itemid, err := strconv.Atoi(itemid)
		if err != nil {
			fmt.Println("item ID should be integer.")
			continue
		}

		err = notedb.RemoveNoteItem(notedb.CurrentNote, itemid)
		if err != nil {
			fmt.Println(err)
			continue
		}

		// fmt.Printf("note item \"%d\" deleted from note \"%s\".\n", itemid, notedb.CurrentNote.NoteID)
	}
}

func funTag(c *cli.Context) {
	err := notedb.ListByTag(c.Args())
	if err != nil {
		fmt.Println(err)
		return
	}
}

func funSearch(c *cli.Context) {
	if len(c.Args()) == 0 {
		fmt.Println("search keyword needed.")
		return
	}
	err := notedb.Search(c.Args())
	if err != nil {
		fmt.Println(err)
		return
	}
}

func main() {
	notedb = note.NewNoteDB(DBFILE)

	app := cli.NewApp()
	app.Name = "cnote"
	app.Usage = "A command line note app. https://github.com/shenwei356/cnote"
	app.Version = "1.0 (2014-07-18)"
	app.Author = "Wei Shen"
	app.Email = "shenwei356@gmail.com"

	app.Commands = []cli.Command{
		{
			Name:   "new",
			Usage:  "Create a new note",
			Action: getFunc(funcs, "new"),
		},
		{
			Name:   "del",
			Usage:  "Delete a note",
			Action: getFunc(funcs, "del"),
		},
		{
			Name:   "use",
			Usage:  "Select a note",
			Action: getFunc(funcs, "use"),
		},
		{
			Name:      "list",
			ShortName: "ls",
			Usage:     "List all notes",
			Action:    getFunc(funcs, "list"),
		},
		{
			Name:   "add",
			Usage:  "add a note item",
			Action: getFunc(funcs, "add"),
		},
		{
			Name:   "rm",
			Usage:  "Remove a note item",
			Action: getFunc(funcs, "rm"),
		},
		{
			Name:      "search",
			ShortName: "s",
			Usage:     "Search for",
			Action:    getFunc(funcs, "search"),
		},
		{
			Name:      "tag",
			ShortName: "t",
			Usage:     "List items by tags",
			Action:    getFunc(funcs, "tag"),
		},
		{
			Name:  "dump",
			Usage: "Dump whole database",
			Action: func(c *cli.Context) {
				notedb.Dump()
			},
		},
	}

	app.Run(os.Args)

	notedb.Close()
}
<commit_msg>remove logger<commit_after>package main

import (
	"fmt"
	"os"
	"os/user"
	"path/filepath"
	"strconv"

	"github.com/codegangsta/cli"
	"github.com/shenwei356/cnote/note"
)

var (
	funcs  map[string]func(c *cli.Context)
	DBFILE string
	notedb *note.NoteDB
)

func init() {
	// DBFILE
	usr, err := user.Current()
	if err != nil {
		os.Exit(1)
	}
	DBFILE = filepath.Join(usr.HomeDir, ".cnote")

	funcs = make(map[string]func(c *cli.Context))
	funcs["new"] = funNew
	funcs["del"] = funDel
	funcs["use"] = funUse
	funcs["list"] = funLs
	funcs["add"] = funAdd
	funcs["rm"] = funRm
	funcs["tag"] = funTag
	funcs["search"] = funSearch

}

func getFunc(funcs map[string]func(c *cli.Context), name string) func(c *cli.Context) {
	if f, ok := funcs[name]; ok {
		return f
	} else {
		return func(c *cli.Context) {
			fmt.Printf("command %s not implemented\n", name)
		}
	}
}

func funLs(c *cli.Context) {
	list := notedb.NotesList
	for _, notename := range list {
		fmt.Println(notename)
	}
}

func funNew(c *cli.Context) {
	if len(c.Args()) == 0 {
		fmt.Println("note name needed.")
		return
	}
	if len(c.Args()) > 1 {
		fmt.Println("only one note name allowed.")
		return
	}

	notename := c.Args().First()

	err := notedb.NewNote(notename)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Printf("note \"%s\" created.\n", notename)
	fmt.Printf("current note: \"%s\".\n", notename)
}

func funDel(c *cli.Context) {
	if len(c.Args()) == 0 {
		fmt.Println("note name needed.")
		return
	}

	for _, notename := range c.Args() {
		err := notedb.DelNote(notename)
		if err != nil {
			fmt.Println(err)
			continue
		}

		// fmt.Printf("note \"%s\" deleted.\n", notename)
	}
}

func funUse(c *cli.Context) {
	if len(c.Args()) == 0 {
		fmt.Println("note name needed.")
		return
	}
	if len(c.Args()) > 1 {
		fmt.Println("only one note name allowed.")
		return
	}

	notename := c.Args().First()
	err := notedb.UseNote(notename)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Printf("current note: \"%s\".\n", notename)
}

func funAdd(c *cli.Context) {
	if len(c.Args()) != 2 {
		fmt.Println("tag and content needed.")
		return
	}

	err := notedb.AddNoteItem(c.Args()[0], c.Args()[1])
	if err != nil {
		fmt.Println(err)
	}
}

func funRm(c *cli.Context) {
	if len(c.Args()) == 0 {
		fmt.Println("item ID needed.")
		return
	}

	for _, itemid := range c.Args() {

		itemid, err := strconv.Atoi(itemid)
		if err != nil {
			fmt.Println("item ID should be integer.")
			continue
		}

		err = notedb.RemoveNoteItem(notedb.CurrentNote, itemid)
		if err != nil {
			fmt.Println(err)
			continue
		}

		// fmt.Printf("note item \"%d\" deleted from note \"%s\".\n", itemid, notedb.CurrentNote.NoteID)
	}
}

func funTag(c *cli.Context) {
	err := notedb.ListByTag(c.Args())
	if err != nil {
		fmt.Println(err)
		return
	}
}

func funSearch(c *cli.Context) {
	if len(c.Args()) == 0 {
		fmt.Println("search keyword needed.")
		return
	}
	err := notedb.Search(c.Args())
	if err != nil {
		fmt.Println(err)
		return
	}
}

func main() {
	notedb = note.NewNoteDB(DBFILE)

	app := cli.NewApp()
	app.Name = "cnote"
	app.Usage = "A command line note app. https://github.com/shenwei356/cnote"
	app.Version = "1.0 (2014-07-18)"
	app.Author = "Wei Shen"
	app.Email = "shenwei356@gmail.com"

	app.Commands = []cli.Command{
		{
			Name:   "new",
			Usage:  "Create a new note",
			Action: getFunc(funcs, "new"),
		},
		{
			Name:   "del",
			Usage:  "Delete a note",
			Action: getFunc(funcs, "del"),
		},
		{
			Name:   "use",
			Usage:  "Select a note",
			Action: getFunc(funcs, "use"),
		},
		{
			Name:      "list",
			ShortName: "ls",
			Usage:     "List all notes",
			Action:    getFunc(funcs, "list"),
		},
		{
			Name:   "add",
			Usage:  "add a note item",
			Action: getFunc(funcs, "add"),
		},
		{
			Name:   "rm",
			Usage:  "Remove a note item",
			Action: getFunc(funcs, "rm"),
		},
		{
			Name:      "search",
			ShortName: "s",
			Usage:     "Search for",
			Action:    getFunc(funcs, "search"),
		},
		{
			Name:      "tag",
			ShortName: "t",
			Usage:     "List items by tags",
			Action:    getFunc(funcs, "tag"),
		},
		{
			Name:  "dump",
			Usage: "Dump whole database",
			Action: func(c *cli.Context) {
				notedb.Dump()
			},
		},
	}

	app.Run(os.Args)

	notedb.Close()
}
<|endoftext|>


<commit_before>package color

import (
	"fmt"
	"io"
	"os"
	"strconv"
	"strings"

	"github.com/shiena/ansicolor"
)

// NoColor defines if the output is colorized or not. By default it's set to
// false. This is a global option and affects all colors. For more control over
// each color block use the methods DisableColor() individually.
var NoColor bool = false

// Color defines a custom color object which is defined by SGR parameters.
type Color struct {
	params  []Attribute
	noColor *bool
}

// Attribute defines a single SGR Code
type Attribute int

const escape = "\x1b"

// Base attributes
const (
	Reset Attribute = iota
	Bold
	Faint
	Italic
	Underline
	BlinkSlow
	BlinkRapid
	ReverseVideo
	Concealed
	CrossedOut
)

// Foreground text colors
const (
	FgBlack Attribute = iota + 30
	FgRed
	FgGreen
	FgYellow
	FgBlue
	FgMagenta
	FgCyan
	FgWhite
)

// Background text colors
const (
	BgBlack Attribute = iota + 40
	BgRed
	BgGreen
	BgYellow
	BgBlue
	BgMagenta
	BgCyan
	BgWhite
)

// New returns a newly created color object.
func New(value ...Attribute) *Color {
	c := &Color{params: make([]Attribute, 0)}
	c.Add(value...)
	return c
}

// Set sets the given parameters immediately. It will change the color of
// output with the given SGR parameters until color.Unset() is called.
func Set(p ...Attribute) *Color {
	c := New(p...)
	c.Set()
	return c
}

// Unset resets all escape attributes and clears the output. Usually should
// be called after Set().
func Unset() {
	if NoColor {
		return
	}

	fmt.Fprintf(Output, "%s[%dm", escape, Reset)
}

// Set sets the SGR sequence.
func (c *Color) Set() *Color {
	if c.isNoColorSet() {
		return c
	}

	fmt.Fprintf(Output, c.format())
	return c
}

func (c *Color) unset() {
	if c.isNoColorSet() {
		return
	}

	Unset()
}

// Add is used to chain SGR parameters. Use as many as parameters to combine
// and create custom color objects. Example: Add(color.FgRed, color.Underline).
func (c *Color) Add(value ...Attribute) *Color {
	c.params = append(c.params, value...)
	return c
}

func (c *Color) prepend(value Attribute) {
	c.params = append(c.params, 0)
	copy(c.params[1:], c.params[0:])
	c.params[0] = value
}

// Output defines the standard output of the print functions. By default
// os.Stdout is used.
var Output io.Writer = ansicolor.NewAnsiColorWriter(os.Stdout)

// Print formats using the default formats for its operands and writes to
// standard output. Spaces are added between operands when neither is a
// string. It returns the number of bytes written and any write error
// encountered. This is the standard fmt.Print() method wrapped with the given
// color.
func (c *Color) Print(a ...interface{}) (n int, err error) {
	c.Set()
	defer c.unset()

	return fmt.Fprint(Output, a...)
}

// Printf formats according to a format specifier and writes to standard output.
// It returns the number of bytes written and any write error encountered.
// This is the standard fmt.Printf() method wrapped with the given color.
func (c *Color) Printf(format string, a ...interface{}) (n int, err error) {
	c.Set()
	defer c.unset()

	return fmt.Fprintf(Output, format, a...)
}

// Println formats using the default formats for its operands and writes to
// standard output. Spaces are always added between operands and a newline is
// appended. It returns the number of bytes written and any write error
// encountered. This is the standard fmt.Print() method wrapped with the given
// color.
func (c *Color) Println(a ...interface{}) (n int, err error) {
	c.Set()
	defer c.unset()

	return fmt.Fprintln(Output, a...)
}

// PrintFunc returns a new function that prints the passed arguments as
// colorized with color.Print().
func (c *Color) PrintFunc() func(a ...interface{}) {
	return func(a ...interface{}) { c.Print(a...) }
}

// PrintfFunc returns a new function that prints the passed arguments as
// colorized with color.Printf().
func (c *Color) PrintfFunc() func(format string, a ...interface{}) {
	return func(format string, a ...interface{}) { c.Printf(format, a...) }
}

// PrintlnFunc returns a new function that prints the passed arguments as
// colorized with color.Println().
func (c *Color) PrintlnFunc() func(a ...interface{}) {
	return func(a ...interface{}) { c.Println(a...) }
}

// SprintFunc returns a new function that returns colorized strings for the
// given arguments with fmt.Sprint(). Useful to put into or mix into other
// string. Windows users should use this in conjuction with color.Output, example:
//
//	put := New(FgYellow).SprintFunc()
//	fmt.Ffprintf(color.Output, "This is a %s", put("warning"))
func (c *Color) SprintFunc() func(a ...interface{}) string {
	return func(a ...interface{}) string {
		return c.wrap(fmt.Sprint(a...))
	}
}

// SprintfFunc returns a new function that returns colorized strings for the
// given arguments with fmt.Sprintf(). Useful to put into or mix into other
// string. Windows users should use this in conjuction with color.Output.
func (c *Color) SprintfFunc() func(format string, a ...interface{}) string {
	return func(format string, a ...interface{}) string {
		return c.wrap(fmt.Sprintf(format, a...))
	}
}

// SprintlnFunc returns a new function that returns colorized strings for the
// given arguments with fmt.Sprintln(). Useful to put into or mix into other
// string. Windows users should use this in conjuction with color.Output.
func (c *Color) SprintlnFunc() func(a ...interface{}) string {
	return func(a ...interface{}) string {
		return c.wrap(fmt.Sprintln(a...))
	}
}

// sequence returns a formated SGR sequence to be plugged into a "\x1b[...m"
// an example output might be: "1;36" -> bold cyan
func (c *Color) sequence() string {
	format := make([]string, len(c.params))
	for i, v := range c.params {
		format[i] = strconv.Itoa(int(v))
	}

	return strings.Join(format, ";")
}

// wrap wraps the s string with the colors attributes. The string is ready to
// be printed.
func (c *Color) wrap(s string) string {
	if c.isNoColorSet() {
		return s
	}

	return c.format() + s + c.unformat()
}

func (c *Color) format() string {
	return fmt.Sprintf("%s[%sm", escape, c.sequence())
}

func (c *Color) unformat() string {
	return fmt.Sprintf("%s[%dm", escape, Reset)
}

// DisableColor disables the color output. Useful to not change any existing
// code and still being able to output. Can be used for flags like
// "--no-color". To enable back use EnableColor() method.
func (c *Color) DisableColor() {
	c.noColor = boolPtr(true)
}

// EnableColor enables the color output. Use it in conjuction with
// DisableColor(). Otherwise this method has no side effects.
func (c *Color) EnableColor() {
	c.noColor = boolPtr(false)
}

func (c *Color) isNoColorSet() bool {
	// check first if we have user setted action
	if c.noColor != nil {
		return *c.noColor
	}

	// if not return the global option, which is disabled by default
	return NoColor
}

func boolPtr(v bool) *bool {
	return &v
}

// Black is an convenient helper function to print with black foreground. A
// newline is appended to format by default.
func Black(format string, a ...interface{}) { printColor(format, FgBlack, a...) }

// Red is an convenient helper function to print with red foreground. A
// newline is appended to format by default.
func Red(format string, a ...interface{}) { printColor(format, FgRed, a...) }

// Green is an convenient helper function to print with green foreground. A
// newline is appended to format by default.
func Green(format string, a ...interface{}) { printColor(format, FgGreen, a...) }

// Yellow is an convenient helper function to print with yellow foreground.
// A newline is appended to format by default.
func Yellow(format string, a ...interface{}) { printColor(format, FgYellow, a...) }

// Blue is an convenient helper function to print with blue foreground. A
// newline is appended to format by default.
func Blue(format string, a ...interface{}) { printColor(format, FgBlue, a...) }

// Magenta is an convenient helper function to print with magenta foreground.
// A newline is appended to format by default.
func Magenta(format string, a ...interface{}) { printColor(format, FgMagenta, a...) }

// Cyan is an convenient helper function to print with cyan foreground. A
// newline is appended to format by default.
func Cyan(format string, a ...interface{}) { printColor(format, FgCyan, a...) }

// White is an convenient helper function to print with white foreground. A
// newline is appended to format by default.
func White(format string, a ...interface{}) { printColor(format, FgWhite, a...) }

func printColor(format string, p Attribute, a ...interface{}) {
	if !strings.HasSuffix(format, "\n") {
		format += "\n"
	}

	c := &Color{params: []Attribute{p}}
	c.Printf(format, a...)
}

// BlackString is an convenient helper function to return a string with black
// foreground.
func BlackString(format string, a ...interface{}) string {
	return New(FgBlack).SprintfFunc()(format, a...)
}

// RedString is an convenient helper function to return a string with red
// foreground.
func RedString(format string, a ...interface{}) string {
	return New(FgRed).SprintfFunc()(format, a...)
}

// GreenString is an convenient helper function to return a string with green
// foreground.
func GreenString(format string, a ...interface{}) string {
	return New(FgGreen).SprintfFunc()(format, a...)
}

// YellowString is an convenient helper function to return a string with yellow
// foreground.
func YellowString(format string, a ...interface{}) string {
	return New(FgYellow).SprintfFunc()(format, a...)
}

// BlueString is an convenient helper function to return a string with blue
// foreground.
func BlueString(format string, a ...interface{}) string {
	return New(FgBlue).SprintfFunc()(format, a...)
}

// MagentaString is an convenient helper function to return a string with magenta
// foreground.
func MagentaString(format string, a ...interface{}) string {
	return New(FgMagenta).SprintfFunc()(format, a...)
}

// CyanString is an convenient helper function to return a string with cyan
// foreground.
func CyanString(format string, a ...interface{}) string {
	return New(FgCyan).SprintfFunc()(format, a...)
}

// WhiteString is an convenient helper function to return a string with white
// foreground.
func WhiteString(format string, a ...interface{}) string {
	return New(FgWhite).SprintfFunc()(format, a...)
}
<commit_msg>color: fix golint warnings<commit_after>package color

import (
	"fmt"
	"os"
	"strconv"
	"strings"

	"github.com/shiena/ansicolor"
)

// NoColor defines if the output is colorized or not. By default it's set to
// false. This is a global option and affects all colors. For more control over
// each color block use the methods DisableColor() individually.
var NoColor = false

// Color defines a custom color object which is defined by SGR parameters.
type Color struct {
	params  []Attribute
	noColor *bool
}

// Attribute defines a single SGR Code
type Attribute int

const escape = "\x1b"

// Base attributes
const (
	Reset Attribute = iota
	Bold
	Faint
	Italic
	Underline
	BlinkSlow
	BlinkRapid
	ReverseVideo
	Concealed
	CrossedOut
)

// Foreground text colors
const (
	FgBlack Attribute = iota + 30
	FgRed
	FgGreen
	FgYellow
	FgBlue
	FgMagenta
	FgCyan
	FgWhite
)

// Background text colors
const (
	BgBlack Attribute = iota + 40
	BgRed
	BgGreen
	BgYellow
	BgBlue
	BgMagenta
	BgCyan
	BgWhite
)

// New returns a newly created color object.
func New(value ...Attribute) *Color {
	c := &Color{params: make([]Attribute, 0)}
	c.Add(value...)
	return c
}

// Set sets the given parameters immediately. It will change the color of
// output with the given SGR parameters until color.Unset() is called.
func Set(p ...Attribute) *Color {
	c := New(p...)
	c.Set()
	return c
}

// Unset resets all escape attributes and clears the output. Usually should
// be called after Set().
func Unset() {
	if NoColor {
		return
	}

	fmt.Fprintf(Output, "%s[%dm", escape, Reset)
}

// Set sets the SGR sequence.
func (c *Color) Set() *Color {
	if c.isNoColorSet() {
		return c
	}

	fmt.Fprintf(Output, c.format())
	return c
}

func (c *Color) unset() {
	if c.isNoColorSet() {
		return
	}

	Unset()
}

// Add is used to chain SGR parameters. Use as many as parameters to combine
// and create custom color objects. Example: Add(color.FgRed, color.Underline).
func (c *Color) Add(value ...Attribute) *Color {
	c.params = append(c.params, value...)
	return c
}

func (c *Color) prepend(value Attribute) {
	c.params = append(c.params, 0)
	copy(c.params[1:], c.params[0:])
	c.params[0] = value
}

// Output defines the standard output of the print functions. By default
// os.Stdout is used.
var Output = ansicolor.NewAnsiColorWriter(os.Stdout)

// Print formats using the default formats for its operands and writes to
// standard output. Spaces are added between operands when neither is a
// string. It returns the number of bytes written and any write error
// encountered. This is the standard fmt.Print() method wrapped with the given
// color.
func (c *Color) Print(a ...interface{}) (n int, err error) {
	c.Set()
	defer c.unset()

	return fmt.Fprint(Output, a...)
}

// Printf formats according to a format specifier and writes to standard output.
// It returns the number of bytes written and any write error encountered.
// This is the standard fmt.Printf() method wrapped with the given color.
func (c *Color) Printf(format string, a ...interface{}) (n int, err error) {
	c.Set()
	defer c.unset()

	return fmt.Fprintf(Output, format, a...)
}

// Println formats using the default formats for its operands and writes to
// standard output. Spaces are always added between operands and a newline is
// appended. It returns the number of bytes written and any write error
// encountered. This is the standard fmt.Print() method wrapped with the given
// color.
func (c *Color) Println(a ...interface{}) (n int, err error) {
	c.Set()
	defer c.unset()

	return fmt.Fprintln(Output, a...)
}

// PrintFunc returns a new function that prints the passed arguments as
// colorized with color.Print().
func (c *Color) PrintFunc() func(a ...interface{}) {
	return func(a ...interface{}) { c.Print(a...) }
}

// PrintfFunc returns a new function that prints the passed arguments as
// colorized with color.Printf().
func (c *Color) PrintfFunc() func(format string, a ...interface{}) {
	return func(format string, a ...interface{}) { c.Printf(format, a...) }
}

// PrintlnFunc returns a new function that prints the passed arguments as
// colorized with color.Println().
func (c *Color) PrintlnFunc() func(a ...interface{}) {
	return func(a ...interface{}) { c.Println(a...) }
}

// SprintFunc returns a new function that returns colorized strings for the
// given arguments with fmt.Sprint(). Useful to put into or mix into other
// string. Windows users should use this in conjuction with color.Output, example:
//
//	put := New(FgYellow).SprintFunc()
//	fmt.Ffprintf(color.Output, "This is a %s", put("warning"))
func (c *Color) SprintFunc() func(a ...interface{}) string {
	return func(a ...interface{}) string {
		return c.wrap(fmt.Sprint(a...))
	}
}

// SprintfFunc returns a new function that returns colorized strings for the
// given arguments with fmt.Sprintf(). Useful to put into or mix into other
// string. Windows users should use this in conjuction with color.Output.
func (c *Color) SprintfFunc() func(format string, a ...interface{}) string {
	return func(format string, a ...interface{}) string {
		return c.wrap(fmt.Sprintf(format, a...))
	}
}

// SprintlnFunc returns a new function that returns colorized strings for the
// given arguments with fmt.Sprintln(). Useful to put into or mix into other
// string. Windows users should use this in conjuction with color.Output.
func (c *Color) SprintlnFunc() func(a ...interface{}) string {
	return func(a ...interface{}) string {
		return c.wrap(fmt.Sprintln(a...))
	}
}

// sequence returns a formated SGR sequence to be plugged into a "\x1b[...m"
// an example output might be: "1;36" -> bold cyan
func (c *Color) sequence() string {
	format := make([]string, len(c.params))
	for i, v := range c.params {
		format[i] = strconv.Itoa(int(v))
	}

	return strings.Join(format, ";")
}

// wrap wraps the s string with the colors attributes. The string is ready to
// be printed.
func (c *Color) wrap(s string) string {
	if c.isNoColorSet() {
		return s
	}

	return c.format() + s + c.unformat()
}

func (c *Color) format() string {
	return fmt.Sprintf("%s[%sm", escape, c.sequence())
}

func (c *Color) unformat() string {
	return fmt.Sprintf("%s[%dm", escape, Reset)
}

// DisableColor disables the color output. Useful to not change any existing
// code and still being able to output. Can be used for flags like
// "--no-color". To enable back use EnableColor() method.
func (c *Color) DisableColor() {
	c.noColor = boolPtr(true)
}

// EnableColor enables the color output. Use it in conjuction with
// DisableColor(). Otherwise this method has no side effects.
func (c *Color) EnableColor() {
	c.noColor = boolPtr(false)
}

func (c *Color) isNoColorSet() bool {
	// check first if we have user setted action
	if c.noColor != nil {
		return *c.noColor
	}

	// if not return the global option, which is disabled by default
	return NoColor
}

func boolPtr(v bool) *bool {
	return &v
}

// Black is an convenient helper function to print with black foreground. A
// newline is appended to format by default.
func Black(format string, a ...interface{}) { printColor(format, FgBlack, a...) }

// Red is an convenient helper function to print with red foreground. A
// newline is appended to format by default.
func Red(format string, a ...interface{}) { printColor(format, FgRed, a...) }

// Green is an convenient helper function to print with green foreground. A
// newline is appended to format by default.
func Green(format string, a ...interface{}) { printColor(format, FgGreen, a...) }

// Yellow is an convenient helper function to print with yellow foreground.
// A newline is appended to format by default.
func Yellow(format string, a ...interface{}) { printColor(format, FgYellow, a...) }

// Blue is an convenient helper function to print with blue foreground. A
// newline is appended to format by default.
func Blue(format string, a ...interface{}) { printColor(format, FgBlue, a...) }

// Magenta is an convenient helper function to print with magenta foreground.
// A newline is appended to format by default.
func Magenta(format string, a ...interface{}) { printColor(format, FgMagenta, a...) }

// Cyan is an convenient helper function to print with cyan foreground. A
// newline is appended to format by default.
func Cyan(format string, a ...interface{}) { printColor(format, FgCyan, a...) }

// White is an convenient helper function to print with white foreground. A
// newline is appended to format by default.
func White(format string, a ...interface{}) { printColor(format, FgWhite, a...) }

func printColor(format string, p Attribute, a ...interface{}) {
	if !strings.HasSuffix(format, "\n") {
		format += "\n"
	}

	c := &Color{params: []Attribute{p}}
	c.Printf(format, a...)
}

// BlackString is an convenient helper function to return a string with black
// foreground.
func BlackString(format string, a ...interface{}) string {
	return New(FgBlack).SprintfFunc()(format, a...)
}

// RedString is an convenient helper function to return a string with red
// foreground.
func RedString(format string, a ...interface{}) string {
	return New(FgRed).SprintfFunc()(format, a...)
}

// GreenString is an convenient helper function to return a string with green
// foreground.
func GreenString(format string, a ...interface{}) string {
	return New(FgGreen).SprintfFunc()(format, a...)
}

// YellowString is an convenient helper function to return a string with yellow
// foreground.
func YellowString(format string, a ...interface{}) string {
	return New(FgYellow).SprintfFunc()(format, a...)
}

// BlueString is an convenient helper function to return a string with blue
// foreground.
func BlueString(format string, a ...interface{}) string {
	return New(FgBlue).SprintfFunc()(format, a...)
}

// MagentaString is an convenient helper function to return a string with magenta
// foreground.
func MagentaString(format string, a ...interface{}) string {
	return New(FgMagenta).SprintfFunc()(format, a...)
}

// CyanString is an convenient helper function to return a string with cyan
// foreground.
func CyanString(format string, a ...interface{}) string {
	return New(FgCyan).SprintfFunc()(format, a...)
}

// WhiteString is an convenient helper function to return a string with white
// foreground.
func WhiteString(format string, a ...interface{}) string {
	return New(FgWhite).SprintfFunc()(format, a...)
}
<|endoftext|>


<commit_before>// <codedate
package clrmamepro

import (
	"testing"
	"strings"
)

var example = `clrmamepro (
	name "Sega - Mega Drive - Genesis"
	description "Sega - Mega Drive - Genesis"
	version 20150628-135736
	comment "no-intro | www.no-intro.org"
)

game (
	name "[BIOS] CDX (USA) (v2.21X)"
	description "[BIOS] CDX (USA) (v2.21X)"
	rom ( name "[BIOS] CDX (USA) (v2.21X).md" size 131072 crc D48C44B5 md5 BACA1DF271D7C11FE50087C0358F4EB5 sha1 2B125C0545AFA089B617F2558E686EA723BDC06E )
)

game (
	name "[BIOS] LaserActive (USA) (v1.02)"
	description "[BIOS] LaserActive (USA) (v1.02)"
	rom ( name "[BIOS] LaserActive (USA) (v1.02).md" size 131072 crc 3B10CF41 md5 691C3FD368211280D268645C0EFD2EFF sha1 8AF162223BB12FC19B414F126022910372790103 )
)

game (
	name "[BIOS] LaserActive (Japan) (v1.02)"
	description "[BIOS] LaserActive (Japan) (v1.02)"
	rom ( name "[BIOS] LaserActive (Japan) (v1.02).md" size 131072 crc 00EEDB3A md5 A5A2F9AAE57D464BC66B80EE79C3DA6E sha1 26237B333DB4A4C6770297FA5E655EA95840D5D9 )
)

game (
	name "[BIOS] LaserActive (USA) (v1.04)"
	description "[BIOS] LaserActive (USA) (v1.04)"
	rom ( name "[BIOS] LaserActive (USA) (v1.04).md" size 131072 crc 50CD3D23 md5 0E7393CD0951D6DDE818FCD4CD819466 sha1 AA811861F8874775075BD3F53008C8AAF59B07DB )
)

game (
	name "[BIOS] Mega-CD (Japan) (1.00S)"
	description "[BIOS] Mega-CD (Japan) (1.00S)"
	rom ( name "[BIOS] Mega-CD (Japan) (1.00S).md" size 131072 crc 79F85384 md5 A3DDCC8483B0368141ADFD99D9A1E466 sha1 230EBFC49DC9E15422089474BCC9FA040F2C57EB )
)

game (
	name "[BIOS] Mega-CD (Japan) (1.00l)"
	description "[BIOS] Mega-CD (Japan) (1.00l)"
	rom ( name "[BIOS] Mega-CD (Japan) (1.00l).md" size 131072 crc F18DDE5B md5 29AD9CE848B49D0F9CEFC294137F653C sha1 0D5485E67C3F033C41D677CC9936AFD6AD618D5F )
)
`

func TestClrmamepro(t *testing.T) {
	r := strings.NewReader(example)
	d, err := NewDatfile(r)
	if err != nil {
		t.Fatalf("error creating new datfile: %v", err)
	}
	for {
		b, err := d.GetBlock()
		if b == nil && err == nil {
			break
		}
		t.Log(b, err)
	}
}
<commit_msg>More clrmamepro package testing.<commit_after>// 29 june 2015
package clrmamepro

import (
	"testing"
	"strings"
)

var example = `clrmamepro (
	name "Sega - Mega Drive - Genesis"
	description "Sega - Mega Drive - Genesis"
	version 20150628-135736
	comment "no-intro | www.no-intro.org"
)

game (
	name "[BIOS] CDX (USA) (v2.21X)"
	description "[BIOS] CDX (USA) (v2.21X)"
	rom ( name "[BIOS] CDX (USA) (v2.21X).md" size 131072 crc D48C44B5 md5 BACA1DF271D7C11FE50087C0358F4EB5 sha1 2B125C0545AFA089B617F2558E686EA723BDC06E )
)

game (
	name "[BIOS] LaserActive (USA) (v1.02)"
	description "[BIOS] LaserActive (USA) (v1.02)"
	rom ( name "[BIOS] LaserActive (USA) (v1.02).md" size 131072 crc 3B10CF41 md5 691C3FD368211280D268645C0EFD2EFF sha1 8AF162223BB12FC19B414F126022910372790103 )
)

game (
	name "[BIOS] LaserActive (Japan) (v1.02)"
	description "[BIOS] LaserActive (Japan) (v1.02)"
	rom ( name "[BIOS] LaserActive (Japan) (v1.02).md" size 131072 crc 00EEDB3A md5 A5A2F9AAE57D464BC66B80EE79C3DA6E sha1 26237B333DB4A4C6770297FA5E655EA95840D5D9 )
)
`

var expected = []*Block{
	&Block{
		Name:	"clrmamepro",
		Texts:	map[string]string{
			"name":		"Sega - Mega Drive - Genesis",
			"description":	"Sega - Mega Drive - Genesis",
			"version":		"20150628-135736",
			"comment":	"no-intro | www.no-intro.org",
		},
	},
	&Block{
		Name:	"game",
		Texts:	map[string]string{
			"name":		"[BIOS] CDX (USA) (v2.21X)",
			"description":	"[BIOS] CDX (USA) (v2.21X)",
		},
		Blocks:	map[string]*Block{
			"rom":	&Block{
				Name:	"rom",
				Texts:	map[string]string{
					"name":	"[BIOS] CDX (USA) (v2.21X).md",
					"size":	"131072",
					"crc":	"D48C44B5",
					"md5":	"BACA1DF271D7C11FE50087C0358F4EB5",
					"sha1":	"2B125C0545AFA089B617F2558E686EA723BDC06E",
				},
			},
		},
	},
	&Block{
		Name:	"game",
		Texts:	map[string]string{
			"name":		"[BIOS] LaserActive (USA) (v1.02)",
			"description":	"[BIOS] LaserActive (USA) (v1.02)",
		},
		Blocks:	map[string]*Block{
			"rom":	&Block{
				Name:	"rom",
				Texts:	map[string]string{
					"name":	"[BIOS] LaserActive (USA) (v1.02).md",
					"size":	"131072",
					"crc":	"3B10CF41",
					"md5":	"691C3FD368211280D268645C0EFD2EFF",
					"sha1":	"8AF162223BB12FC19B414F126022910372790103",
				},
			},
		},
	},
	&Block{
		Name:	"game",
		Texts:	map[string]string{
			"name":		"[BIOS] LaserActive (Japan) (v1.02)",
			"description":	"[BIOS] LaserActive (Japan) (v1.02)",
		},
		Blocks:	map[string]*Block{
			"rom":	&Block{
				Name:	"rom",
				Texts:	map[string]string{
					"name":	"[BIOS] LaserActive (Japan) (v1.02).md",
					"size":	"131072",
					"crc":	"00EEDB3A",
					"md5":	"A5A2F9AAE57D464BC66B80EE79C3DA6E",
					"sha1":	"26237B333DB4A4C6770297FA5E655EA95840D5D9",
				},
			},
		},
	},
}

func TestClrmamepro(t *testing.T) {
	r := strings.NewReader(example)
	d, err := NewDatfile(r)
	if err != nil {
		t.Fatalf("error creating new datfile: %v", err)
	}
	for i, e := range expected {
		// TODO change to Next()
		b, err := d.GetBlock()
		if err != nil {
			t.Fatalf("error reading block: %v", err)
		}
		if b == nil {
			t.Fatalf("unexpected end of stream reading block %d", i)
		}
		// TODO
		t.Log(b)
	}
	b, err := d.GetBlock()
	if err != nil {
		t.Fatalf("error finishing reading blocks: %v", err)
	}
	if b != nil {
		t.Fatalf("another block was returned when no more were expected")
	}
}
<|endoftext|>


<commit_before>package graph

import (
	"fmt"
	"os"
	"path"
	"strings"
	"sync"
	"sync/atomic"

	log "github.com/Sirupsen/logrus"
	"github.com/docker/docker/daemon/graphdriver"
	"github.com/docker/docker/daemon/graphdriver/overlay"
	"github.com/docker/docker/pkg/archive"
	"github.com/docker/docker/pkg/idtools"
	"github.com/docker/docker/pkg/parsers"

	"github.com/libopenstorage/openstorage/api"
	"github.com/libopenstorage/openstorage/graph"
	"github.com/libopenstorage/openstorage/volume"
)

type Layer0Vol struct {
	// id self referential ID
	id string
	// parent image string
	parent string
	// path where the external volume is mounted.
	path string
	// volumeID mapping to this external volume
	volumeID api.VolumeID
	// ref keeps track of mount and unmounts.
	ref int32
}

type Layer0 struct {
	sync.Mutex
	// Driver is an implementation of GraphDriver. Only select methods are overridden
	graphdriver.Driver
	// home base string
	home string
	// volumes maintains a map of currently mounted volumes.
	volumes map[string]*Layer0Vol
	// volDriver is the volume driver used for the writeable layer.
	volDriver volume.VolumeDriver
}

// Layer0Graphdriver options
const (
	Layer0VolumeDriver = "layer0.volume_driver"
)

func init() {
	graph.Register("layer0", Init)
}

func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (graphdriver.Driver, error) {

	var volumeDriver string
	for _, option := range options {
		key, val, err := parsers.ParseKeyValueOpt(option)
		if err != nil {
			return nil, err
		}
		switch key {
		case Layer0VolumeDriver:
			volumeDriver = val
		default:
			return nil, fmt.Errorf("Unknown option %s\n", key)
		}
	}
	log.Infof("Layer0 volume driver: %v", volumeDriver)
	volDriver, err := volume.Get(volumeDriver)
	if err != nil {
		return nil, err
	}
	ov, err := overlay.Init(home, options, uidMaps, gidMaps)
	if err != nil {
		volDriver.Shutdown()
		return nil, err
	}
	d := &Layer0{
		Driver:    ov,
		home:      home,
		volumes:   make(map[string]*Layer0Vol),
		volDriver: volDriver,
	}

	return d, nil
}
func (l *Layer0) isLayer0Parent(id string) (string, bool) {
	// This relies on an <instance_id>-init volume being created for
	// every new container.
	if strings.HasSuffix(id, "-init") {
		return strings.TrimSuffix(id, "-init"), true
	}
	return "", false
}

func (l *Layer0) isLayer0(id string) bool {
	if strings.HasSuffix(id, "-init") {
		baseID := strings.TrimSuffix(id, "-init")
		if _, ok := l.volumes[baseID]; !ok {
			l.volumes[baseID] = &Layer0Vol{id: baseID}
		}
		return false
	}
	_, ok := l.volumes[id]
	return ok
}

func (l *Layer0) loID(id string) string {
	return id + "-vol"
}

func (l *Layer0) realID(id string) string {
	if l.isLayer0(id) {
		return path.Join(l.loID(id), id)
	}
	return id
}

func (l *Layer0) create(id, parent string) (string, *Layer0Vol, error) {
	l.Lock()
	defer l.Unlock()

	// If this is the parent of the Layer0, add an entry for it.
	baseID, l0 := l.isLayer0Parent(id)
	if l0 {
		l.volumes[baseID] = &Layer0Vol{id: baseID, parent: parent}
		return id, nil, nil
	}

	// Don't do anything if this is not layer 0
	if !l.isLayer0(id) {
		return id, nil, nil
	}

	vol, ok := l.volumes[id]
	if !ok {
		log.Warnf("Failed to find layer0 volume for id %v", id)
		return id, nil, nil
	}

	// Query volume for Layer 0
	vols, err := l.volDriver.Enumerate(api.VolumeLocator{Name: vol.parent}, nil)

	// If we don't find a volume configured for this image,
	// then don't track layer0
	if err != nil || vols == nil {
		log.Infof("Failed to find configured volume for id %v", vol.parent)
		delete(l.volumes, id)
		return id, nil, nil
	}

	// Find a volume that is available.
	index := -1
	for i, v := range vols {
		if len(v.AttachPath) == 0 {
			index = i
			break
		}
	}
	if index == -1 {
		log.Infof("Failed to find free volume for id %v", vol.parent)
		delete(l.volumes, id)
		return id, nil, nil
	}

	mountPath := path.Join(l.home, l.loID(id))
	os.MkdirAll(mountPath, 0755)
	err = l.volDriver.Mount(vols[index].ID, mountPath)
	if err != nil {
		log.Errorf("Failed to mount volume %v at path %v",
			vols[index].ID, mountPath)
		delete(l.volumes, id)
		return id, nil, nil
	}
	vol.path = mountPath
	vol.volumeID = vols[index].ID
	vol.ref = 1

	return l.realID(id), vol, nil
}

func (l *Layer0) Create(id string, parent string) error {
	id, vol, err := l.create(id, parent)
	if err != nil {
		return err
	}
	err = l.Driver.Create(id, parent)
	if err != nil || vol == nil {
		return err
	}
	// This is layer0. Restore saved upper dir, if one exists.
	savedUpper := path.Join(vol.path, "upper")
	if _, err := os.Stat(savedUpper); err != nil {
		// It's not an error if didn't have a saved upper
		return nil
	}
	// We found a saved upper, restore to newly created upper.
	upperDir := path.Join(path.Join(l.home, id), "upper")
	os.RemoveAll(upperDir)
	return os.Rename(savedUpper, upperDir)
}

func (l *Layer0) Remove(id string) error {
	if !l.isLayer0(id) {
		return l.Driver.Remove(l.realID(id))
	}
	l.Lock()
	defer l.Unlock()
	var err error
	v, ok := l.volumes[id]

	if ok {
		atomic.AddInt32(&v.ref, -1)
		if v.ref == 0 {
			// Save the upper dir and blow away the rest.
			upperDir := path.Join(path.Join(l.home, l.realID(id)), "upper")
			err := os.Rename(upperDir, path.Join(v.path, "upper"))
			if err != nil {
				log.Warnf("Failed in rename(%v): %v", id, err)
			}
			l.Driver.Remove(l.realID(id))
			err = l.volDriver.Unmount(v.volumeID, v.path)
			err = os.RemoveAll(v.path)
			delete(l.volumes, v.id)
		}
	} else {
		log.Warnf("Failed to find layer0 vol for id %v", id)
	}
	return err
}

func (l *Layer0) Get(id string, mountLabel string) (string, error) {
	id = l.realID(id)
	return l.Driver.Get(id, mountLabel)
}

func (l *Layer0) Put(id string) error {
	id = l.realID(id)
	return l.Driver.Put(id)
}

func (l *Layer0) ApplyDiff(id string, parent string, diff archive.Reader) (size int64, err error) {
	id = l.realID(id)
	return l.Driver.ApplyDiff(id, parent, diff)
}

func (l *Layer0) Exists(id string) bool {
	id = l.realID(id)
	return l.Driver.Exists(id)
}

func (l *Layer0) GetMetadata(id string) (map[string]string, error) {
	id = l.realID(id)
	return l.Driver.GetMetadata(id)
}
<commit_msg>Add usage documentation<commit_after>package graph

import (
	"fmt"
	"os"
	"path"
	"strings"
	"sync"
	"sync/atomic"

	log "github.com/Sirupsen/logrus"
	"github.com/docker/docker/daemon/graphdriver"
	"github.com/docker/docker/daemon/graphdriver/overlay"
	"github.com/docker/docker/pkg/archive"
	"github.com/docker/docker/pkg/idtools"
	"github.com/docker/docker/pkg/parsers"

	"github.com/libopenstorage/openstorage/api"
	"github.com/libopenstorage/openstorage/graph"
	"github.com/libopenstorage/openstorage/volume"
)

// Layer0 implemenation piggy backs on existing overlay graphdriver implementation
// to provide persistent storage for the uppermost/writeable layer in the
// container rootfs. The persistent storage is derived from one of the OSD volume drivers.
// To use this as the graphdriver in Docker with aws as the backend volume provider:
//
// DOCKER_STORAGE_OPTIONS= -s layer0 --storage-opt layer0.volume_driver=aws

type Layer0Vol struct {
	// id self referential ID
	id string
	// parent image string
	parent string
	// path where the external volume is mounted.
	path string
	// volumeID mapping to this external volume
	volumeID api.VolumeID
	// ref keeps track of mount and unmounts.
	ref int32
}

type Layer0 struct {
	sync.Mutex
	// Driver is an implementation of GraphDriver. Only select methods are overridden
	graphdriver.Driver
	// home base string
	home string
	// volumes maintains a map of currently mounted volumes.
	volumes map[string]*Layer0Vol
	// volDriver is the volume driver used for the writeable layer.
	volDriver volume.VolumeDriver
}

// Layer0Graphdriver options. This should be passed in as a st
const (
	Layer0VolumeDriver = "layer0.volume_driver"
)

func init() {
	graph.Register("layer0", Init)
}

func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (graphdriver.Driver, error) {

	var volumeDriver string
	for _, option := range options {
		key, val, err := parsers.ParseKeyValueOpt(option)
		if err != nil {
			return nil, err
		}
		switch key {
		case Layer0VolumeDriver:
			volumeDriver = val
		default:
			return nil, fmt.Errorf("Unknown option %s\n", key)
		}
	}
	log.Infof("Layer0 volume driver: %v", volumeDriver)
	volDriver, err := volume.Get(volumeDriver)
	if err != nil {
		return nil, err
	}
	ov, err := overlay.Init(home, options, uidMaps, gidMaps)
	if err != nil {
		volDriver.Shutdown()
		return nil, err
	}
	d := &Layer0{
		Driver:    ov,
		home:      home,
		volumes:   make(map[string]*Layer0Vol),
		volDriver: volDriver,
	}

	return d, nil
}
func (l *Layer0) isLayer0Parent(id string) (string, bool) {
	// This relies on an <instance_id>-init volume being created for
	// every new container.
	if strings.HasSuffix(id, "-init") {
		return strings.TrimSuffix(id, "-init"), true
	}
	return "", false
}

func (l *Layer0) isLayer0(id string) bool {
	if strings.HasSuffix(id, "-init") {
		baseID := strings.TrimSuffix(id, "-init")
		if _, ok := l.volumes[baseID]; !ok {
			l.volumes[baseID] = &Layer0Vol{id: baseID}
		}
		return false
	}
	_, ok := l.volumes[id]
	return ok
}

func (l *Layer0) loID(id string) string {
	return id + "-vol"
}

func (l *Layer0) realID(id string) string {
	if l.isLayer0(id) {
		return path.Join(l.loID(id), id)
	}
	return id
}

func (l *Layer0) create(id, parent string) (string, *Layer0Vol, error) {
	l.Lock()
	defer l.Unlock()

	// If this is the parent of the Layer0, add an entry for it.
	baseID, l0 := l.isLayer0Parent(id)
	if l0 {
		l.volumes[baseID] = &Layer0Vol{id: baseID, parent: parent}
		return id, nil, nil
	}

	// Don't do anything if this is not layer 0
	if !l.isLayer0(id) {
		return id, nil, nil
	}

	vol, ok := l.volumes[id]
	if !ok {
		log.Warnf("Failed to find layer0 volume for id %v", id)
		return id, nil, nil
	}

	// Query volume for Layer 0
	vols, err := l.volDriver.Enumerate(api.VolumeLocator{Name: vol.parent}, nil)

	// If we don't find a volume configured for this image,
	// then don't track layer0
	if err != nil || vols == nil {
		log.Infof("Failed to find configured volume for id %v", vol.parent)
		delete(l.volumes, id)
		return id, nil, nil
	}

	// Find a volume that is available.
	index := -1
	for i, v := range vols {
		if len(v.AttachPath) == 0 {
			index = i
			break
		}
	}
	if index == -1 {
		log.Infof("Failed to find free volume for id %v", vol.parent)
		delete(l.volumes, id)
		return id, nil, nil
	}

	mountPath := path.Join(l.home, l.loID(id))
	os.MkdirAll(mountPath, 0755)
	err = l.volDriver.Mount(vols[index].ID, mountPath)
	if err != nil {
		log.Errorf("Failed to mount volume %v at path %v",
			vols[index].ID, mountPath)
		delete(l.volumes, id)
		return id, nil, nil
	}
	vol.path = mountPath
	vol.volumeID = vols[index].ID
	vol.ref = 1

	return l.realID(id), vol, nil
}

func (l *Layer0) Create(id string, parent string) error {
	id, vol, err := l.create(id, parent)
	if err != nil {
		return err
	}
	err = l.Driver.Create(id, parent)
	if err != nil || vol == nil {
		return err
	}
	// This is layer0. Restore saved upper dir, if one exists.
	savedUpper := path.Join(vol.path, "upper")
	if _, err := os.Stat(savedUpper); err != nil {
		// It's not an error if didn't have a saved upper
		return nil
	}
	// We found a saved upper, restore to newly created upper.
	upperDir := path.Join(path.Join(l.home, id), "upper")
	os.RemoveAll(upperDir)
	return os.Rename(savedUpper, upperDir)
}

func (l *Layer0) Remove(id string) error {
	if !l.isLayer0(id) {
		return l.Driver.Remove(l.realID(id))
	}
	l.Lock()
	defer l.Unlock()
	var err error
	v, ok := l.volumes[id]

	if ok {
		atomic.AddInt32(&v.ref, -1)
		if v.ref == 0 {
			// Save the upper dir and blow away the rest.
			upperDir := path.Join(path.Join(l.home, l.realID(id)), "upper")
			err := os.Rename(upperDir, path.Join(v.path, "upper"))
			if err != nil {
				log.Warnf("Failed in rename(%v): %v", id, err)
			}
			l.Driver.Remove(l.realID(id))
			err = l.volDriver.Unmount(v.volumeID, v.path)
			err = os.RemoveAll(v.path)
			delete(l.volumes, v.id)
		}
	} else {
		log.Warnf("Failed to find layer0 vol for id %v", id)
	}
	return err
}

func (l *Layer0) Get(id string, mountLabel string) (string, error) {
	id = l.realID(id)
	return l.Driver.Get(id, mountLabel)
}

func (l *Layer0) Put(id string) error {
	id = l.realID(id)
	return l.Driver.Put(id)
}

func (l *Layer0) ApplyDiff(id string, parent string, diff archive.Reader) (size int64, err error) {
	id = l.realID(id)
	return l.Driver.ApplyDiff(id, parent, diff)
}

func (l *Layer0) Exists(id string) bool {
	id = l.realID(id)
	return l.Driver.Exists(id)
}

func (l *Layer0) GetMetadata(id string) (map[string]string, error) {
	id = l.realID(id)
	return l.Driver.GetMetadata(id)
}
<|endoftext|>


<commit_before>package main

import (
	"os"

	authapi "github.com/charakoba-com/auth-api"
	flags "github.com/jessevdk/go-flags"
	logger "github.com/nasa9084/go-logger"
)

type options struct {
	Listen string `short:"l" long:"listen" default:":8080" description:"Listen address"`
}

func main() {
	os.Exit(_main())
}

func _main() int {
	log := logger.New(os.Stdout, "", logger.InfoLevel)
	var opts options
	if _, err := flags.Parse(&opts); err != nil {
		log.Errorf.Printf("%s", err)
		return 1
	}
	if err := authapi.Run(opts.Listen); err != nil {
		log.Errorf("%s", err)
		return 1
	}
	return 0
}
<commit_msg>fix: typo<commit_after>package main

import (
	"os"

	authapi "github.com/charakoba-com/auth-api"
	flags "github.com/jessevdk/go-flags"
	logger "github.com/nasa9084/go-logger"
)

type options struct {
	Listen string `short:"l" long:"listen" default:":8080" description:"Listen address"`
}

func main() {
	os.Exit(_main())
}

func _main() int {
	log := logger.New(os.Stdout, "", logger.InfoLevel)
	var opts options
	if _, err := flags.Parse(&opts); err != nil {
		log.Errorf("%s", err)
		return 1
	}
	if err := authapi.Run(opts.Listen); err != nil {
		log.Errorf("%s", err)
		return 1
	}
	return 0
}
<|endoftext|>


<commit_before>package main_test

import (
	"os"
	"path"

	"github.com/cloudfoundry-incubator/bbs"
	"github.com/cloudfoundry-incubator/bbs/cmd/bbs/testrunner"
	"github.com/tedsuo/ifrit/ginkgomon"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Secure", func() {
	var (
		client bbs.Client
		err    error

		basePath string
	)

	BeforeEach(func() {
		basePath = path.Join(os.Getenv("GOPATH"), "src", "github.com", "cloudfoundry-incubator", "bbs", "cmd", "bbs", "fixtures")
		bbsURL.Scheme = "https"
	})

	JustBeforeEach(func() {
		client = bbs.NewClient(bbsURL.String())
		bbsRunner = testrunner.New(bbsBinPath, bbsArgs)
		bbsProcess = ginkgomon.Invoke(bbsRunner)
	})

	AfterEach(func() {
		ginkgomon.Kill(bbsProcess)
	})

	Context("when configuring mutual SSL", func() {
		BeforeEach(func() {
			bbsArgs.RequireSSL = true
			bbsArgs.CAFile = path.Join(basePath, "green-certs", "server-ca.crt")
			bbsArgs.CertFile = path.Join(basePath, "green-certs", "server.crt")
			bbsArgs.KeyFile = path.Join(basePath, "green-certs", "server.key")
		})

		It("succeeds for a client configured with the right certificate", func() {
			caFile := path.Join(basePath, "green-certs", "server-ca.crt")
			certFile := path.Join(basePath, "green-certs", "client.crt")
			keyFile := path.Join(basePath, "green-certs", "client.key")
			client, err = bbs.NewSecureClient(bbsURL.String(), caFile, certFile, keyFile)
			Expect(err).NotTo(HaveOccurred())
			Expect(client.Ping()).To(BeTrue())
		})

		It("fails for a client with no SSL", func() {
			client = bbs.NewClient(bbsURL.String())
			Expect(client.Ping()).To(BeFalse())
		})

		It("fails for a client configured with the wrong certificate", func() {
			caFile := path.Join(basePath, "blue-certs", "server-ca.crt")
			certFile := path.Join(basePath, "blue-certs", "client.crt")
			keyFile := path.Join(basePath, "blue-certs", "client.key")
			client, err = bbs.NewSecureClient(bbsURL.String(), caFile, certFile, keyFile)
			Expect(err).NotTo(HaveOccurred())
			Expect(client.Ping()).To(BeFalse())
		})

		It("fails to create the client if certs are not valid", func() {
			client, err = bbs.NewSecureClient(bbsURL.String(), "", "", "")
			Expect(err).To(HaveOccurred())
		})
	})
})
<commit_msg>Fix SSL verification tests<commit_after>package main_test

import (
	"os"
	"path"

	"github.com/cloudfoundry-incubator/bbs"
	"github.com/cloudfoundry-incubator/bbs/cmd/bbs/testrunner"
	"github.com/tedsuo/ifrit/ginkgomon"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Secure", func() {
	var (
		client bbs.Client
		err    error

		basePath string
	)

	BeforeEach(func() {
		basePath = path.Join(os.Getenv("GOPATH"), "src", "github.com", "cloudfoundry-incubator", "bbs", "cmd", "bbs", "fixtures")
		bbsURL.Scheme = "https"
	})

	JustBeforeEach(func() {
		client = bbs.NewClient(bbsURL.String())
		bbsRunner = testrunner.New(bbsBinPath, bbsArgs)
		bbsProcess = ginkgomon.Invoke(bbsRunner)
	})

	AfterEach(func() {
		ginkgomon.Kill(bbsProcess)
	})

	Context("when configuring mutual SSL", func() {
		BeforeEach(func() {
			bbsArgs.RequireSSL = true
			bbsArgs.CAFile = path.Join(basePath, "green-certs", "server-ca.crt")
			bbsArgs.CertFile = path.Join(basePath, "green-certs", "server.crt")
			bbsArgs.KeyFile = path.Join(basePath, "green-certs", "server.key")
		})

		It("succeeds for a client configured with the right certificate", func() {
			caFile := path.Join(basePath, "green-certs", "server-ca.crt")
			certFile := path.Join(basePath, "green-certs", "client.crt")
			keyFile := path.Join(basePath, "green-certs", "client.key")
			client, err = bbs.NewSecureClient(bbsURL.String(), caFile, certFile, keyFile)
			Expect(err).NotTo(HaveOccurred())
			Expect(client.Ping()).To(BeTrue())
		})

		It("fails for a client with no SSL", func() {
			client = bbs.NewClient(bbsURL.String())
			Expect(client.Ping()).To(BeFalse())
		})

		It("fails for a client configured with the wrong certificates", func() {
			caFile := path.Join(basePath, "green-certs", "server-ca.crt")
			certFile := path.Join(basePath, "blue-certs", "client.crt")
			keyFile := path.Join(basePath, "blue-certs", "client.key")
			client, err = bbs.NewSecureClient(bbsURL.String(), caFile, certFile, keyFile)
			Expect(err).NotTo(HaveOccurred())
			Expect(client.Ping()).To(BeFalse())
		})

		It("fails for a client configured with a different ca certificate", func() {
			caFile := path.Join(basePath, "blue-certs", "server-ca.crt")
			certFile := path.Join(basePath, "green-certs", "client.crt")
			keyFile := path.Join(basePath, "green-certs", "client.key")
			client, err = bbs.NewSecureClient(bbsURL.String(), caFile, certFile, keyFile)
			Expect(err).NotTo(HaveOccurred())
			Expect(client.Ping()).To(BeFalse())
		})

		It("fails to create the client if certs are not valid", func() {
			client, err = bbs.NewSecureClient(bbsURL.String(), "", "", "")
			Expect(err).To(HaveOccurred())
		})
	})
})
<|endoftext|>


<commit_before>/*
   Copyright 2020 Docker Compose CLI authors

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

package compose

import (
	"bufio"
	"context"
	"fmt"
	"io"
	"os"
	"sort"
	"strings"

	"github.com/cnabio/cnab-to-oci/remotes"
	"github.com/compose-spec/compose-go/cli"
	"github.com/compose-spec/compose-go/types"
	"github.com/distribution/distribution/v3/reference"
	cliconfig "github.com/docker/cli/cli/config"
	"github.com/opencontainers/go-digest"
	"github.com/spf13/cobra"

	"github.com/docker/compose/v2/pkg/api"
	"github.com/docker/compose/v2/pkg/compose"
)

type convertOptions struct {
	*projectOptions
	Format              string
	Output              string
	quiet               bool
	resolveImageDigests bool
	noInterpolate       bool
	noNormalize         bool
	services            bool
	volumes             bool
	profiles            bool
	images              bool
	hash                string
}

func convertCommand(p *projectOptions, backend api.Service) *cobra.Command {
	opts := convertOptions{
		projectOptions: p,
	}
	cmd := &cobra.Command{
		Aliases: []string{"config"},
		Use:     "convert SERVICES",
		Short:   "Converts the compose file to platform's canonical format",
		PreRunE: Adapt(func(ctx context.Context, args []string) error {
			if opts.quiet {
				devnull, err := os.Open(os.DevNull)
				if err != nil {
					return err
				}
				os.Stdout = devnull
			}
			if p.Compatibility {
				opts.noNormalize = true
			}
			return nil
		}),
		RunE: Adapt(func(ctx context.Context, args []string) error {
			if opts.services {
				return runServices(opts)
			}
			if opts.volumes {
				return runVolumes(opts)
			}
			if opts.hash != "" {
				return runHash(opts)
			}
			if opts.profiles {
				return runProfiles(opts, args)
			}
			if opts.images {
				return runConfigImages(opts, args)
			}

			return runConvert(ctx, backend, opts, args)
		}),
		ValidArgsFunction: serviceCompletion(p),
	}
	flags := cmd.Flags()
	flags.StringVar(&opts.Format, "format", "yaml", "Format the output. Values: [yaml | json]")
	flags.BoolVar(&opts.resolveImageDigests, "resolve-image-digests", false, "Pin image tags to digests.")
	flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Only validate the configuration, don't print anything.")
	flags.BoolVar(&opts.noInterpolate, "no-interpolate", false, "Don't interpolate environment variables.")
	flags.BoolVar(&opts.noNormalize, "no-normalize", false, "Don't normalize compose model.")

	flags.BoolVar(&opts.services, "services", false, "Print the service names, one per line.")
	flags.BoolVar(&opts.volumes, "volumes", false, "Print the volume names, one per line.")
	flags.BoolVar(&opts.profiles, "profiles", false, "Print the profile names, one per line.")
	flags.BoolVar(&opts.images, "images", false, "Print the image names, one per line.")
	flags.StringVar(&opts.hash, "hash", "", "Print the service config hash, one per line.")
	flags.StringVarP(&opts.Output, "output", "o", "", "Save to file (default to stdout)")

	return cmd
}

func runConvert(ctx context.Context, backend api.Service, opts convertOptions, services []string) error {
	var json []byte
	project, err := opts.toProject(services,
		cli.WithInterpolation(!opts.noInterpolate),
		cli.WithResolvedPaths(true),
		cli.WithNormalization(!opts.noNormalize))
	if err != nil {
		return err
	}

	if opts.resolveImageDigests {
		configFile := cliconfig.LoadDefaultConfigFile(os.Stderr)

		resolver := remotes.CreateResolver(configFile)
		err = project.ResolveImages(func(named reference.Named) (digest.Digest, error) {
			_, desc, err := resolver.Resolve(ctx, named.String())
			return desc.Digest, err
		})
		if err != nil {
			return err
		}
	}

	json, err = backend.Convert(ctx, project, api.ConvertOptions{
		Format: opts.Format,
		Output: opts.Output,
	})
	if err != nil {
		return err
	}

	if opts.quiet {
		return nil
	}

	var out io.Writer = os.Stdout
	if opts.Output != "" && len(json) > 0 {
		file, err := os.Create(opts.Output)
		if err != nil {
			return err
		}
		out = bufio.NewWriter(file)
	}
	_, err = fmt.Fprint(out, string(json))
	return err
}

func runServices(opts convertOptions) error {
	project, err := opts.toProject(nil)
	if err != nil {
		return err
	}
	return project.WithServices(project.ServiceNames(), func(s types.ServiceConfig) error {
		fmt.Println(s.Name)
		return nil
	})
}

func runVolumes(opts convertOptions) error {
	project, err := opts.toProject(nil)
	if err != nil {
		return err
	}
	for n := range project.Volumes {
		fmt.Println(n)
	}
	return nil
}

func runHash(opts convertOptions) error {
	var services []string
	if opts.hash != "*" {
		services = append(services, strings.Split(opts.hash, ",")...)
	}
	project, err := opts.toProject(services)
	if err != nil {
		return err
	}
	for _, s := range project.Services {
		hash, err := compose.ServiceHash(s)
		if err != nil {
			return err
		}
		fmt.Printf("%s %s\n", s.Name, hash)
	}
	return nil
}

func runProfiles(opts convertOptions, services []string) error {
	set := map[string]struct{}{}
	project, err := opts.toProject(services)
	if err != nil {
		return err
	}
	for _, s := range project.AllServices() {
		for _, p := range s.Profiles {
			set[p] = struct{}{}
		}
	}
	profiles := make([]string, 0, len(set))
	for p := range set {
		profiles = append(profiles, p)
	}
	sort.Strings(profiles)
	for _, p := range profiles {
		fmt.Println(p)
	}
	return nil
}

func runConfigImages(opts convertOptions, services []string) error {
	project, err := opts.toProject(services)
	if err != nil {
		return err
	}
	for _, s := range project.Services {
		if s.Image != "" {
			fmt.Println(s.Image)
		} else {
			fmt.Printf("%s_%s\n", project.Name, s.Name)
		}
	}
	return nil
}
<commit_msg>Discard env_file section on convert/config<commit_after>/*
   Copyright 2020 Docker Compose CLI authors

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

package compose

import (
	"bufio"
	"context"
	"fmt"
	"io"
	"os"
	"sort"
	"strings"

	"github.com/cnabio/cnab-to-oci/remotes"
	"github.com/compose-spec/compose-go/cli"
	"github.com/compose-spec/compose-go/types"
	"github.com/distribution/distribution/v3/reference"
	cliconfig "github.com/docker/cli/cli/config"
	"github.com/opencontainers/go-digest"
	"github.com/spf13/cobra"

	"github.com/docker/compose/v2/pkg/api"
	"github.com/docker/compose/v2/pkg/compose"
)

type convertOptions struct {
	*projectOptions
	Format              string
	Output              string
	quiet               bool
	resolveImageDigests bool
	noInterpolate       bool
	noNormalize         bool
	services            bool
	volumes             bool
	profiles            bool
	images              bool
	hash                string
}

func convertCommand(p *projectOptions, backend api.Service) *cobra.Command {
	opts := convertOptions{
		projectOptions: p,
	}
	cmd := &cobra.Command{
		Aliases: []string{"config"},
		Use:     "convert SERVICES",
		Short:   "Converts the compose file to platform's canonical format",
		PreRunE: Adapt(func(ctx context.Context, args []string) error {
			if opts.quiet {
				devnull, err := os.Open(os.DevNull)
				if err != nil {
					return err
				}
				os.Stdout = devnull
			}
			if p.Compatibility {
				opts.noNormalize = true
			}
			return nil
		}),
		RunE: Adapt(func(ctx context.Context, args []string) error {
			if opts.services {
				return runServices(opts)
			}
			if opts.volumes {
				return runVolumes(opts)
			}
			if opts.hash != "" {
				return runHash(opts)
			}
			if opts.profiles {
				return runProfiles(opts, args)
			}
			if opts.images {
				return runConfigImages(opts, args)
			}

			return runConvert(ctx, backend, opts, args)
		}),
		ValidArgsFunction: serviceCompletion(p),
	}
	flags := cmd.Flags()
	flags.StringVar(&opts.Format, "format", "yaml", "Format the output. Values: [yaml | json]")
	flags.BoolVar(&opts.resolveImageDigests, "resolve-image-digests", false, "Pin image tags to digests.")
	flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Only validate the configuration, don't print anything.")
	flags.BoolVar(&opts.noInterpolate, "no-interpolate", false, "Don't interpolate environment variables.")
	flags.BoolVar(&opts.noNormalize, "no-normalize", false, "Don't normalize compose model.")

	flags.BoolVar(&opts.services, "services", false, "Print the service names, one per line.")
	flags.BoolVar(&opts.volumes, "volumes", false, "Print the volume names, one per line.")
	flags.BoolVar(&opts.profiles, "profiles", false, "Print the profile names, one per line.")
	flags.BoolVar(&opts.images, "images", false, "Print the image names, one per line.")
	flags.StringVar(&opts.hash, "hash", "", "Print the service config hash, one per line.")
	flags.StringVarP(&opts.Output, "output", "o", "", "Save to file (default to stdout)")

	return cmd
}

func runConvert(ctx context.Context, backend api.Service, opts convertOptions, services []string) error {
	var json []byte
	project, err := opts.toProject(services,
		cli.WithInterpolation(!opts.noInterpolate),
		cli.WithResolvedPaths(true),
		cli.WithNormalization(!opts.noNormalize),
		cli.WithDiscardEnvFile)

	if err != nil {
		return err
	}

	if opts.resolveImageDigests {
		configFile := cliconfig.LoadDefaultConfigFile(os.Stderr)

		resolver := remotes.CreateResolver(configFile)
		err = project.ResolveImages(func(named reference.Named) (digest.Digest, error) {
			_, desc, err := resolver.Resolve(ctx, named.String())
			return desc.Digest, err
		})
		if err != nil {
			return err
		}
	}

	json, err = backend.Convert(ctx, project, api.ConvertOptions{
		Format: opts.Format,
		Output: opts.Output,
	})
	if err != nil {
		return err
	}

	if opts.quiet {
		return nil
	}

	var out io.Writer = os.Stdout
	if opts.Output != "" && len(json) > 0 {
		file, err := os.Create(opts.Output)
		if err != nil {
			return err
		}
		out = bufio.NewWriter(file)
	}
	_, err = fmt.Fprint(out, string(json))
	return err
}

func runServices(opts convertOptions) error {
	project, err := opts.toProject(nil)
	if err != nil {
		return err
	}
	return project.WithServices(project.ServiceNames(), func(s types.ServiceConfig) error {
		fmt.Println(s.Name)
		return nil
	})
}

func runVolumes(opts convertOptions) error {
	project, err := opts.toProject(nil)
	if err != nil {
		return err
	}
	for n := range project.Volumes {
		fmt.Println(n)
	}
	return nil
}

func runHash(opts convertOptions) error {
	var services []string
	if opts.hash != "*" {
		services = append(services, strings.Split(opts.hash, ",")...)
	}
	project, err := opts.toProject(services)
	if err != nil {
		return err
	}
	for _, s := range project.Services {
		hash, err := compose.ServiceHash(s)
		if err != nil {
			return err
		}
		fmt.Printf("%s %s\n", s.Name, hash)
	}
	return nil
}

func runProfiles(opts convertOptions, services []string) error {
	set := map[string]struct{}{}
	project, err := opts.toProject(services)
	if err != nil {
		return err
	}
	for _, s := range project.AllServices() {
		for _, p := range s.Profiles {
			set[p] = struct{}{}
		}
	}
	profiles := make([]string, 0, len(set))
	for p := range set {
		profiles = append(profiles, p)
	}
	sort.Strings(profiles)
	for _, p := range profiles {
		fmt.Println(p)
	}
	return nil
}

func runConfigImages(opts convertOptions, services []string) error {
	project, err := opts.toProject(services)
	if err != nil {
		return err
	}
	for _, s := range project.Services {
		if s.Image != "" {
			fmt.Println(s.Image)
		} else {
			fmt.Printf("%s_%s\n", project.Name, s.Name)
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	".."
	"../filters"
	"fmt"
	"os"
)

func main() {
	gitmedia.SetupDebugging()

	cleaned, err := gitmediafilters.Clean(os.Stdin)
	if err != nil {
		fmt.Println("Error cleaning asset")
		panic(err)
	}
	defer cleaned.Close()

	tmpfile := cleaned.File.Name()
	mediafile := gitmedia.LocalMediaPath(cleaned.Sha)
	if stat, _ := os.Stat(mediafile); stat != nil {
		if stat.Size() != cleaned.Size {
			gitmedia.Panic(nil, "Files don't match:\n%s\n%s", mediafile, tmpfile)
		}
		gitmedia.Debug("%s exists", mediafile)
	} else {
		if err := os.Rename(tmpfile, mediafile); err != nil {
			gitmedia.Panic(err, "Unable to move %s to %s\n", tmpfile, mediafile)
		}
		gitmedia.Debug("Writing %s", mediafile)
	}

	gitmedia.Encode(os.Stdout, cleaned.Sha)
}
<commit_msg>add cleaned files to the clean queue<commit_after>package main

import (
	".."
	"../filters"
	"../queuedir"
	"fmt"
	"os"
	"path/filepath"
)

func main() {
	gitmedia.SetupDebugging()
	qdir := queuedir.New(filepath.Join(gitmedia.LocalMediaDir, "queue"))
	cleanqueue, err := qdir.Queue("clean")
	if err != nil {
		fmt.Println("Error setting up queue")
		panic(err)
	}

	cleaned, err := gitmediafilters.Clean(os.Stdin)
	if err != nil {
		fmt.Println("Error cleaning asset")
		panic(err)
	}
	defer cleaned.Close()

	tmpfile := cleaned.File.Name()
	mediafile := gitmedia.LocalMediaPath(cleaned.Sha)
	if stat, _ := os.Stat(mediafile); stat != nil {
		if stat.Size() != cleaned.Size {
			gitmedia.Panic(nil, "Files don't match:\n%s\n%s", mediafile, tmpfile)
		}
		gitmedia.Debug("%s exists", mediafile)
	} else {
		if err := os.Rename(tmpfile, mediafile); err != nil {
			gitmedia.Panic(err, "Unable to move %s to %s\n", tmpfile, mediafile)
		}
		if _, err := cleanqueue.AddString(cleaned.Sha); err != nil {
			gitmedia.Panic(err, "Unable to add %s to queue", cleaned.Sha)
		}
		gitmedia.Debug("Writing %s", mediafile)
	}

	gitmedia.Encode(os.Stdout, cleaned.Sha)
}
<|endoftext|>


<commit_before>/*
Copyright The Helm Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
	"fmt"
	"io"
	"os"
	"path/filepath"

	"github.com/spf13/cobra"

	"helm.sh/helm/v3/cmd/helm/require"
)

const completionDesc = `
Generate autocompletion scripts for Helm for the specified shell.
`
const bashCompDesc = `
Generate the autocompletion script for Helm for the bash shell.

To load completions in your current shell session:
$ source <(helm completion bash)

To load completions for every new session, execute once:
Linux:
  $ helm completion bash > /etc/bash_completion.d/helm
MacOS:
  $ helm completion bash > /usr/local/etc/bash_completion.d/helm
`

const zshCompDesc = `
Generate the autocompletion script for Helm for the zsh shell.

To load completions in your current shell session:
$ source <(helm completion zsh)

To load completions for every new session, execute once:
$ helm completion zsh > "${fpath[1]}/_helm"
`

const fishCompDesc = `
Generate the autocompletion script for Helm for the fish shell.

To load completions in your current shell session:
$ helm completion fish | source

To load completions for every new session, execute once:
$ helm completion fish > ~/.config/fish/completions/helm.fish

You will need to start a new shell for this setup to take effect.
`

const (
	noDescFlagName = "no-descriptions"
	noDescFlagText = "disable completion descriptions"
)

var disableCompDescriptions bool

func newCompletionCmd(out io.Writer) *cobra.Command {
	cmd := &cobra.Command{
		Use:   "completion",
		Short: "generate autocompletion scripts for the specified shell",
		Long:  completionDesc,
		Args:  require.NoArgs,
	}

	bash := &cobra.Command{
		Use:                   "bash",
		Short:                 "generate autocompletion script for bash",
		Long:                  bashCompDesc,
		Args:                  require.NoArgs,
		DisableFlagsInUseLine: true,
		ValidArgsFunction:     noCompletions,
		RunE: func(cmd *cobra.Command, args []string) error {
			return runCompletionBash(out, cmd)
		},
	}

	zsh := &cobra.Command{
		Use:                   "zsh",
		Short:                 "generate autocompletion script for zsh",
		Long:                  zshCompDesc,
		Args:                  require.NoArgs,
		DisableFlagsInUseLine: true,
		ValidArgsFunction:     noCompletions,
		RunE: func(cmd *cobra.Command, args []string) error {
			return runCompletionZsh(out, cmd)
		},
	}
	zsh.Flags().BoolVar(&disableCompDescriptions, noDescFlagName, false, noDescFlagText)

	fish := &cobra.Command{
		Use:                   "fish",
		Short:                 "generate autocompletion script for fish",
		Long:                  fishCompDesc,
		Args:                  require.NoArgs,
		DisableFlagsInUseLine: true,
		ValidArgsFunction:     noCompletions,
		RunE: func(cmd *cobra.Command, args []string) error {
			return runCompletionFish(out, cmd)
		},
	}
	fish.Flags().BoolVar(&disableCompDescriptions, noDescFlagName, false, noDescFlagText)

	cmd.AddCommand(bash, zsh, fish)

	return cmd
}

func runCompletionBash(out io.Writer, cmd *cobra.Command) error {
	err := cmd.Root().GenBashCompletion(out)

	// In case the user renamed the helm binary (e.g., to be able to run
	// both helm2 and helm3), we hook the new binary name to the completion function
	if binary := filepath.Base(os.Args[0]); binary != "helm" {
		renamedBinaryHook := `
# Hook the command used to generate the completion script
# to the helm completion function to handle the case where
# the user renamed the helm binary
if [[ $(type -t compopt) = "builtin" ]]; then
    complete -o default -F __start_helm %[1]s
else
    complete -o default -o nospace -F __start_helm %[1]s
fi
`
		fmt.Fprintf(out, renamedBinaryHook, binary)
	}

	return err
}

func runCompletionZsh(out io.Writer, cmd *cobra.Command) error {
	var err error
	if disableCompDescriptions {
		err = cmd.Root().GenZshCompletionNoDesc(out)
	} else {
		err = cmd.Root().GenZshCompletion(out)
	}

	// In case the user renamed the helm binary (e.g., to be able to run
	// both helm2 and helm3), we hook the new binary name to the completion function
	if binary := filepath.Base(os.Args[0]); binary != "helm" {
		renamedBinaryHook := `
# Hook the command used to generate the completion script
# to the helm completion function to handle the case where
# the user renamed the helm binary
compdef _helm %[1]s
`
		fmt.Fprintf(out, renamedBinaryHook, binary)
	}

	// Cobra doesn't source zsh completion file, explicitly doing it here
	fmt.Fprintf(out, "compdef _helm helm")

	return err
}

func runCompletionFish(out io.Writer, cmd *cobra.Command) error {
	return cmd.Root().GenFishCompletion(out, !disableCompDescriptions)
}

// Function to disable file completion
func noCompletions(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
	return nil, cobra.ShellCompDirectiveNoFileComp
}
<commit_msg>fix(cmd): Show that flags can be used for zsh/fish<commit_after>/*
Copyright The Helm Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
	"fmt"
	"io"
	"os"
	"path/filepath"

	"github.com/spf13/cobra"

	"helm.sh/helm/v3/cmd/helm/require"
)

const completionDesc = `
Generate autocompletion scripts for Helm for the specified shell.
`
const bashCompDesc = `
Generate the autocompletion script for Helm for the bash shell.

To load completions in your current shell session:
$ source <(helm completion bash)

To load completions for every new session, execute once:
Linux:
  $ helm completion bash > /etc/bash_completion.d/helm
MacOS:
  $ helm completion bash > /usr/local/etc/bash_completion.d/helm
`

const zshCompDesc = `
Generate the autocompletion script for Helm for the zsh shell.

To load completions in your current shell session:
$ source <(helm completion zsh)

To load completions for every new session, execute once:
$ helm completion zsh > "${fpath[1]}/_helm"
`

const fishCompDesc = `
Generate the autocompletion script for Helm for the fish shell.

To load completions in your current shell session:
$ helm completion fish | source

To load completions for every new session, execute once:
$ helm completion fish > ~/.config/fish/completions/helm.fish

You will need to start a new shell for this setup to take effect.
`

const (
	noDescFlagName = "no-descriptions"
	noDescFlagText = "disable completion descriptions"
)

var disableCompDescriptions bool

func newCompletionCmd(out io.Writer) *cobra.Command {
	cmd := &cobra.Command{
		Use:   "completion",
		Short: "generate autocompletion scripts for the specified shell",
		Long:  completionDesc,
		Args:  require.NoArgs,
	}

	bash := &cobra.Command{
		Use:                   "bash",
		Short:                 "generate autocompletion script for bash",
		Long:                  bashCompDesc,
		Args:                  require.NoArgs,
		DisableFlagsInUseLine: true,
		ValidArgsFunction:     noCompletions,
		RunE: func(cmd *cobra.Command, args []string) error {
			return runCompletionBash(out, cmd)
		},
	}

	zsh := &cobra.Command{
		Use:               "zsh",
		Short:             "generate autocompletion script for zsh",
		Long:              zshCompDesc,
		Args:              require.NoArgs,
		ValidArgsFunction: noCompletions,
		RunE: func(cmd *cobra.Command, args []string) error {
			return runCompletionZsh(out, cmd)
		},
	}
	zsh.Flags().BoolVar(&disableCompDescriptions, noDescFlagName, false, noDescFlagText)

	fish := &cobra.Command{
		Use:               "fish",
		Short:             "generate autocompletion script for fish",
		Long:              fishCompDesc,
		Args:              require.NoArgs,
		ValidArgsFunction: noCompletions,
		RunE: func(cmd *cobra.Command, args []string) error {
			return runCompletionFish(out, cmd)
		},
	}
	fish.Flags().BoolVar(&disableCompDescriptions, noDescFlagName, false, noDescFlagText)

	cmd.AddCommand(bash, zsh, fish)

	return cmd
}

func runCompletionBash(out io.Writer, cmd *cobra.Command) error {
	err := cmd.Root().GenBashCompletion(out)

	// In case the user renamed the helm binary (e.g., to be able to run
	// both helm2 and helm3), we hook the new binary name to the completion function
	if binary := filepath.Base(os.Args[0]); binary != "helm" {
		renamedBinaryHook := `
# Hook the command used to generate the completion script
# to the helm completion function to handle the case where
# the user renamed the helm binary
if [[ $(type -t compopt) = "builtin" ]]; then
    complete -o default -F __start_helm %[1]s
else
    complete -o default -o nospace -F __start_helm %[1]s
fi
`
		fmt.Fprintf(out, renamedBinaryHook, binary)
	}

	return err
}

func runCompletionZsh(out io.Writer, cmd *cobra.Command) error {
	var err error
	if disableCompDescriptions {
		err = cmd.Root().GenZshCompletionNoDesc(out)
	} else {
		err = cmd.Root().GenZshCompletion(out)
	}

	// In case the user renamed the helm binary (e.g., to be able to run
	// both helm2 and helm3), we hook the new binary name to the completion function
	if binary := filepath.Base(os.Args[0]); binary != "helm" {
		renamedBinaryHook := `
# Hook the command used to generate the completion script
# to the helm completion function to handle the case where
# the user renamed the helm binary
compdef _helm %[1]s
`
		fmt.Fprintf(out, renamedBinaryHook, binary)
	}

	// Cobra doesn't source zsh completion file, explicitly doing it here
	fmt.Fprintf(out, "compdef _helm helm")

	return err
}

func runCompletionFish(out io.Writer, cmd *cobra.Command) error {
	return cmd.Root().GenFishCompletion(out, !disableCompDescriptions)
}

// Function to disable file completion
func noCompletions(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
	return nil, cobra.ShellCompDirectiveNoFileComp
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"net/http"
	"net/url"
	"strings"

	"github.com/influxdb/influxdb"
	"github.com/influxdb/influxdb/httpd"
	"github.com/influxdb/influxdb/messaging"
	"github.com/influxdb/influxdb/raft"
)

// Handler represents an HTTP handler for InfluxDB node.
// Depending on its role, it will serve many different endpoints.
type Handler struct {
	Log    *raft.Log
	Broker *influxdb.Broker
	Server *influxdb.Server
	Config *Config
}

// NewHandler returns a new instance of Handler.
func NewHandler() *Handler {
	return &Handler{}
}

// ServeHTTP responds to HTTP request to the handler.
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	// FIXME: This is very brittle.  Refactor to have common path prefix
	if strings.HasPrefix(r.URL.Path, "/raft") {
		h.serveRaft(w, r)
		return
	}

	if strings.HasPrefix(r.URL.Path, "/messaging") {
		h.serveMessaging(w, r)
		return
	}

	if strings.HasPrefix(r.URL.Path, "/data_nodes") ||
		strings.HasPrefix(r.URL.Path, "/process_continuous_queries") ||
		strings.HasPrefix(r.URL.Path, "/metastore") {
		h.serveMetadata(w, r)
		return
	}
	h.serveData(w, r)
}

// serveMessaging responds to broker requests
func (h *Handler) serveMessaging(w http.ResponseWriter, r *http.Request) {
	if h.Broker == nil && h.Server == nil {
		log.Println("no broker or server configured to handle messaging endpoints")
		http.Error(w, "server unavailable", http.StatusServiceUnavailable)
		return
	}

	// If we're running a broker, handle the broker endpoints
	if h.Broker != nil {
		mh := &messaging.Handler{
			Broker:      h.Broker.Broker,
			RaftHandler: &raft.Handler{Log: h.Log},
		}
		mh.ServeHTTP(w, r)
		return
	}

	// Redirect to a valid broker to handle the request
	h.redirect(h.Server.BrokerURLs(), w, r)
}

// serveMetadata responds to broker requests
func (h *Handler) serveMetadata(w http.ResponseWriter, r *http.Request) {
	if h.Broker == nil && h.Server == nil {
		log.Println("no broker or server configured to handle messaging endpoints")
		http.Error(w, "server unavailable", http.StatusServiceUnavailable)
		return
	}

	if h.Server != nil {
		sh := httpd.NewClusterHandler(h.Server, h.Config.Authentication.Enabled, version)
		sh.WriteTrace = h.Config.Logging.WriteTracing
		sh.ServeHTTP(w, r)
		return
	}

	t := h.Broker.Topic(influxdb.BroadcastTopicID)
	if t == nil {
		http.Error(w, "not found", http.StatusNotFound)
		return
	}

	// Redirect to a valid data URL to handle the request
	h.redirect(h.Broker.Topic(influxdb.BroadcastTopicID).DataURLs(), w, r)
}

// serveRaft responds to raft requests.
func (h *Handler) serveRaft(w http.ResponseWriter, r *http.Request) {
	if h.Log == nil && h.Server == nil {
		log.Println("no broker or server configured to handle messaging endpoints")
		http.Error(w, "server unavailable", http.StatusServiceUnavailable)
		return
	}

	if h.Log != nil {
		rh := raft.Handler{Log: h.Log}
		rh.ServeHTTP(w, r)
		return
	}

	// Redirect to a valid broker to handle the request
	h.redirect(h.Server.BrokerURLs(), w, r)
}

// serveData responds to data requests
func (h *Handler) serveData(w http.ResponseWriter, r *http.Request) {
	if h.Broker == nil && h.Server == nil {
		log.Println("no broker or server configured to handle messaging endpoints")
		http.Error(w, "server unavailable", http.StatusServiceUnavailable)
		return
	}

	if h.Server != nil {
		sh := httpd.NewAPIHandler(h.Server, h.Config.Authentication.Enabled, version)
		sh.WriteTrace = h.Config.Logging.WriteTracing
		sh.ServeHTTP(w, r)
		return
	}

	t := h.Broker.Topic(influxdb.BroadcastTopicID)
	if t == nil {
		http.Error(w, "not found", http.StatusNotFound)
		return
	}

	// Redirect to a valid data URL to handle the request
	h.redirect(h.Broker.Topic(influxdb.BroadcastTopicID).DataURLs(), w, r)
}

// redirect redirects a request to URL in u.  If u is an empty slice,
// a 503 is returned
func (h *Handler) redirect(u []url.URL, w http.ResponseWriter, r *http.Request) {
	// No valid URLs, return an error
	if len(u) == 0 {
		http.Error(w, "service unavailable", http.StatusServiceUnavailable)
		return
	}

	// TODO: Log to internal stats to track how frequently this is happening. If
	// this is happening frequently, the clients are using a suboptimal endpoint

	// Redirect the client to a valid data node that can handle the request
	http.Redirect(w, r, u[0].String()+r.RequestURI, http.StatusTemporaryRedirect)
}
<commit_msg>Fix erroneous logging for http handlers<commit_after>package main

import (
	"log"
	"net/http"
	"net/url"
	"strings"

	"github.com/influxdb/influxdb"
	"github.com/influxdb/influxdb/httpd"
	"github.com/influxdb/influxdb/messaging"
	"github.com/influxdb/influxdb/raft"
)

// Handler represents an HTTP handler for InfluxDB node.
// Depending on its role, it will serve many different endpoints.
type Handler struct {
	Log    *raft.Log
	Broker *influxdb.Broker
	Server *influxdb.Server
	Config *Config
}

// NewHandler returns a new instance of Handler.
func NewHandler() *Handler {
	return &Handler{}
}

// ServeHTTP responds to HTTP request to the handler.
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	// FIXME: This is very brittle.  Refactor to have common path prefix
	if strings.HasPrefix(r.URL.Path, "/raft") {
		h.serveRaft(w, r)
		return
	}

	if strings.HasPrefix(r.URL.Path, "/messaging") {
		h.serveMessaging(w, r)
		return
	}

	if strings.HasPrefix(r.URL.Path, "/data_nodes") ||
		strings.HasPrefix(r.URL.Path, "/process_continuous_queries") ||
		strings.HasPrefix(r.URL.Path, "/metastore") {
		h.serveMetadata(w, r)
		return
	}
	h.serveData(w, r)
}

// serveMessaging responds to broker requests
func (h *Handler) serveMessaging(w http.ResponseWriter, r *http.Request) {
	if h.Broker == nil && h.Server == nil {
		log.Println("no broker or server configured to handle messaging endpoints")
		http.Error(w, "server unavailable", http.StatusServiceUnavailable)
		return
	}

	// If we're running a broker, handle the broker endpoints
	if h.Broker != nil {
		mh := &messaging.Handler{
			Broker:      h.Broker.Broker,
			RaftHandler: &raft.Handler{Log: h.Log},
		}
		mh.ServeHTTP(w, r)
		return
	}

	// Redirect to a valid broker to handle the request
	h.redirect(h.Server.BrokerURLs(), w, r)
}

// serveMetadata responds to broker requests
func (h *Handler) serveMetadata(w http.ResponseWriter, r *http.Request) {
	if h.Broker == nil && h.Server == nil {
		log.Println("no broker or server configured to handle metadata endpoints")
		http.Error(w, "server unavailable", http.StatusServiceUnavailable)
		return
	}

	if h.Server != nil {
		sh := httpd.NewClusterHandler(h.Server, h.Config.Authentication.Enabled, version)
		sh.WriteTrace = h.Config.Logging.WriteTracing
		sh.ServeHTTP(w, r)
		return
	}

	t := h.Broker.Topic(influxdb.BroadcastTopicID)
	if t == nil {
		http.Error(w, "not found", http.StatusNotFound)
		return
	}

	// Redirect to a valid data URL to handle the request
	h.redirect(h.Broker.Topic(influxdb.BroadcastTopicID).DataURLs(), w, r)
}

// serveRaft responds to raft requests.
func (h *Handler) serveRaft(w http.ResponseWriter, r *http.Request) {
	if h.Log == nil && h.Server == nil {
		log.Println("no broker or server configured to handle raft endpoints")
		http.Error(w, "server unavailable", http.StatusServiceUnavailable)
		return
	}

	if h.Log != nil {
		rh := raft.Handler{Log: h.Log}
		rh.ServeHTTP(w, r)
		return
	}

	// Redirect to a valid broker to handle the request
	h.redirect(h.Server.BrokerURLs(), w, r)
}

// serveData responds to data requests
func (h *Handler) serveData(w http.ResponseWriter, r *http.Request) {
	if h.Broker == nil && h.Server == nil {
		log.Println("no broker or server configured to handle data endpoints")
		http.Error(w, "server unavailable", http.StatusServiceUnavailable)
		return
	}

	if h.Server != nil {
		sh := httpd.NewAPIHandler(h.Server, h.Config.Authentication.Enabled, version)
		sh.WriteTrace = h.Config.Logging.WriteTracing
		sh.ServeHTTP(w, r)
		return
	}

	t := h.Broker.Topic(influxdb.BroadcastTopicID)
	if t == nil {
		http.Error(w, "not found", http.StatusNotFound)
		return
	}

	// Redirect to a valid data URL to handle the request
	h.redirect(h.Broker.Topic(influxdb.BroadcastTopicID).DataURLs(), w, r)
}

// redirect redirects a request to URL in u.  If u is an empty slice,
// a 503 is returned
func (h *Handler) redirect(u []url.URL, w http.ResponseWriter, r *http.Request) {
	// No valid URLs, return an error
	if len(u) == 0 {
		http.Error(w, "service unavailable", http.StatusServiceUnavailable)
		return
	}

	// TODO: Log to internal stats to track how frequently this is happening. If
	// this is happening frequently, the clients are using a suboptimal endpoint

	// Redirect the client to a valid data node that can handle the request
	http.Redirect(w, r, u[0].String()+r.RequestURI, http.StatusTemporaryRedirect)
}
<|endoftext|>