<commit_before>package car

import (
    "fmt"
    "path"
    "regexp"
    "strings"

    "github.com/jtyr/gbt/gbt/core/utils"
)

// ModelElement is an element of which the car model is constructed from.
type ModelElement struct {
    Bg string
    Fg string
    Fm string
    Text string
}

// Car is a type defining the model of the car.
type Car struct {
    Model map[string]ModelElement
    Display bool
    Sep string
    Wrap bool
    Params map[string]interface{}
}

// Shell type.
var Shell string = utils.GetEnv("GBT_SHELL", path.Base(utils.GetEnv("SHELL", "zsh")))

// List of named colors and their codes.
var colors = map[string]string {
    "black":          "0",
    "red":            "1",
    "green":          "2",
    "yellow":         "3",
    "blue":           "4",
    "magenta":        "5",
    "cyan":           "6",
    "light_gray":     "7",
    "dark_gray":      "8",
    "light_red":      "9",
    "light_green":   "10",
    "light_yellow":  "11",
    "light_blue":    "12",
    "light_magenta": "13",
    "light_cyan":    "14",
    "white":         "15",
}

// SetParamStr sets string value to a parameter.
func (c *Car) SetParamStr(name, value string) {
    if c.Params == nil {
        c.Params = make(map[string]interface{})
    }

    c.Params[name] = value
}

// GetModel returns the Model value.
func (c *Car) GetModel() map[string]ModelElement {
    return c.Model
}

// GetDisplay returns the Display value.
func (c *Car) GetDisplay() bool {
    return c.Display
}

// GetSep returns the Sep value.
func (c *Car) GetSep() string {
    return c.Sep
}

// GetWrap returns the Wrap value.
func (c *Car) GetWrap() bool {
    return c.Wrap
}

var reTemplating = regexp.MustCompile(`{{\s*(\w+)\s*}}`)

// Format initiates replacement of all templating elements.
func (c *Car) Format() string {
    if ! c.Display {
        return ""
    }

    text := fmt.Sprintf("%s%s", c.DecorateElement("root", "", "", "", ""), c.Model["root"].Text)

    for range make([]int, 10) {
        match := reTemplating.MatchString(text)

        if match {
            text = reTemplating.ReplaceAllStringFunc(text, c.replaceElement)
        } else {
            break
        }
    }

    return text
}

// Replaces the specific templating element.
func (c *Car) replaceElement(format string) string {
    match := reTemplating.FindStringSubmatch(format)[1]

    if _, ok := c.Model[match]; ! ok {
        return format
    }

    return fmt.Sprintf(
        "%s%s",
        c.DecorateElement(match, "", "", "", ""),
        c.DecorateElement("root", "", "", "", ""))
}

// DecorateElement decorates the element text with its colors and formatting.
func (c *Car) DecorateElement(element, bg, fg, fm, text string) string {
    fmEnd := ""

    if element != "" {
        e := c.Model[element]

        if element != "root" {
            text = e.Text
        } else {
            text = ""
        }

        bg = c.GetColor(e.Bg, false)
        fg = c.GetColor(e.Fg, true)
        fm = c.GetFormat(e.Fm, false)

        if fm != c.GetFormat("empty", false) {
            fmEnd = c.GetFormat(e.Fm, true)
        } else {
            fm = ""
        }
    }

    return fmt.Sprintf("%s%s%s%s%s", bg, fg, fm, text, fmEnd)
}

// Patterns to parse the color codes
var reColorNumber = regexp.MustCompile(`^\d{1,3}$`)
var reRgbTriplet = regexp.MustCompile(`^\d{1,3};\d{1,3};\d{1,3}$`)

// GetColor returns color sequence based on the color name or code.
func (c *Car) GetColor(name string, isFg bool) (ret string) {
    kind := 4
    seq := ""

    if isFg {
        kind = 3
    }

    if name == "default" {
        // Default
        seq = fmt.Sprintf("\x1b[%d9m", kind)
    } else {
        if val, ok := colors[name]; ok {
            // Named color
            seq = fmt.Sprintf("\x1b[%d8;5;%sm", kind, val)
        } else if match := reColorNumber.MatchString(name); match {
            // Color number
            seq = fmt.Sprintf("\x1b[%d8;5;%sm", kind, name)
        } else if match := reRgbTriplet.MatchString(name); match {
            // RGB color
            seq = fmt.Sprintf("\x1b[%d8;2;%sm", kind, name)
        } else {
            // If anything else, use default
            seq = fmt.Sprintf("\x1b[%d9m", kind)
        }
    }

    ret = DecorateShell(seq)

    return
}

// GetFormat returns formatting sequence based on the format name.
func (c *Car) GetFormat(name string, end bool) (ret string) {
    seq := ""
    kind := 0

    if end {
        kind = 2
    }

    if strings.Contains(name, "bold") {
        seq += fmt.Sprintf("\x1b[%d1m", kind)
    }

    if strings.Contains(name, "underline") {
        seq += fmt.Sprintf("\x1b[%d4m", kind)
    }

    if strings.Contains(name, "blink") {
        seq += fmt.Sprintf("\x1b[%d5m", kind)
    }

    ret = DecorateShell(seq)

    return
}

// DecorateShell decorates the string with shell-specific closure.
func DecorateShell(seq string) (ret string) {
    if Shell == "zsh" {
        ret = fmt.Sprintf("%%{%s%%}", seq)
    } else {
        ret = fmt.Sprintf("\001%s\002", seq)
    }

    return
}
<commit_msg>Adding Bash-native sequences output<commit_after>package car

import (
    "fmt"
    "path"
    "regexp"
    "strings"

    "github.com/jtyr/gbt/gbt/core/utils"
)

// ModelElement is an element of which the car model is constructed from.
type ModelElement struct {
    Bg string
    Fg string
    Fm string
    Text string
}

// Car is a type defining the model of the car.
type Car struct {
    Model map[string]ModelElement
    Display bool
    Sep string
    Wrap bool
    Params map[string]interface{}
}

// Shell type.
var Shell string = utils.GetEnv("GBT_SHELL", path.Base(utils.GetEnv("SHELL", "zsh")))

// List of named colors and their codes.
var colors = map[string]string {
    "black":          "0",
    "red":            "1",
    "green":          "2",
    "yellow":         "3",
    "blue":           "4",
    "magenta":        "5",
    "cyan":           "6",
    "light_gray":     "7",
    "dark_gray":      "8",
    "light_red":      "9",
    "light_green":   "10",
    "light_yellow":  "11",
    "light_blue":    "12",
    "light_magenta": "13",
    "light_cyan":    "14",
    "white":         "15",
}

// SetParamStr sets string value to a parameter.
func (c *Car) SetParamStr(name, value string) {
    if c.Params == nil {
        c.Params = make(map[string]interface{})
    }

    c.Params[name] = value
}

// GetModel returns the Model value.
func (c *Car) GetModel() map[string]ModelElement {
    return c.Model
}

// GetDisplay returns the Display value.
func (c *Car) GetDisplay() bool {
    return c.Display
}

// GetSep returns the Sep value.
func (c *Car) GetSep() string {
    return c.Sep
}

// GetWrap returns the Wrap value.
func (c *Car) GetWrap() bool {
    return c.Wrap
}

var reTemplating = regexp.MustCompile(`{{\s*(\w+)\s*}}`)

// Format initiates replacement of all templating elements.
func (c *Car) Format() string {
    if ! c.Display {
        return ""
    }

    text := fmt.Sprintf("%s%s", c.DecorateElement("root", "", "", "", ""), c.Model["root"].Text)

    for range make([]int, 10) {
        match := reTemplating.MatchString(text)

        if match {
            text = reTemplating.ReplaceAllStringFunc(text, c.replaceElement)
        } else {
            break
        }
    }

    return text
}

// Replaces the specific templating element.
func (c *Car) replaceElement(format string) string {
    match := reTemplating.FindStringSubmatch(format)[1]

    if _, ok := c.Model[match]; ! ok {
        return format
    }

    return fmt.Sprintf(
        "%s%s",
        c.DecorateElement(match, "", "", "", ""),
        c.DecorateElement("root", "", "", "", ""))
}

// DecorateElement decorates the element text with its colors and formatting.
func (c *Car) DecorateElement(element, bg, fg, fm, text string) string {
    fmEnd := ""

    if element != "" {
        e := c.Model[element]

        if element != "root" {
            text = e.Text
        } else {
            text = ""
        }

        bg = c.GetColor(e.Bg, false)
        fg = c.GetColor(e.Fg, true)
        fm = c.GetFormat(e.Fm, false)

        if fm != c.GetFormat("empty", false) {
            fmEnd = c.GetFormat(e.Fm, true)
        } else {
            fm = ""
        }
    }

    return fmt.Sprintf("%s%s%s%s%s", bg, fg, fm, text, fmEnd)
}

// Patterns to parse the color codes
var reColorNumber = regexp.MustCompile(`^\d{1,3}$`)
var reRgbTriplet = regexp.MustCompile(`^\d{1,3};\d{1,3};\d{1,3}$`)

// GetColor returns color sequence based on the color name or code.
func (c *Car) GetColor(name string, isFg bool) (ret string) {
    kind := 4
    seq := ""
    esc := "\x1b"

    if isFg {
        kind = 3
    }

    if Shell == "_bash" {
        esc = "\\e"
    }

    if name == "default" {
        // Default
        seq = fmt.Sprintf("%s[%d9m", esc, kind)
    } else {
        if val, ok := colors[name]; ok {
            // Named color
            seq = fmt.Sprintf("%s[%d8;5;%sm", esc, kind, val)
        } else if match := reColorNumber.MatchString(name); match {
            // Color number
            seq = fmt.Sprintf("%s[%d8;5;%sm", esc, kind, name)
        } else if match := reRgbTriplet.MatchString(name); match {
            // RGB color
            seq = fmt.Sprintf("%s[%d8;2;%sm", esc, kind, name)
        } else {
            // If anything else, use default
            seq = fmt.Sprintf("%s[%d9m", esc, kind)
        }
    }

    ret = DecorateShell(seq)

    return
}

// GetFormat returns formatting sequence based on the format name.
func (c *Car) GetFormat(name string, end bool) (ret string) {
    seq := ""
    kind := 0
    esc := "\x1b"

    if end {
        kind = 2
    }

    if Shell == "_bash" {
        esc = "\\e"
    }

    if strings.Contains(name, "bold") {
        seq += fmt.Sprintf("%s[%d1m", esc, kind)
    }

    if strings.Contains(name, "underline") {
        seq += fmt.Sprintf("%s[%d4m", esc, kind)
    }

    if strings.Contains(name, "blink") {
        seq += fmt.Sprintf("%s[%d5m", esc, kind)
    }

    ret = DecorateShell(seq)

    return
}

// DecorateShell decorates the string with shell-specific closure.
func DecorateShell(seq string) (ret string) {
    if Shell == "zsh" {
        ret = fmt.Sprintf("%%{%s%%}", seq)
    } else if Shell == "_bash" {
        ret = fmt.Sprintf("\\[%s\\]", seq)
    } else {
        ret = fmt.Sprintf("\001%s\002", seq)
    }

    return
}
<|endoftext|>


<commit_before>package state_test

import (
	. "launchpad.net/gocheck"
	"launchpad.net/juju-core/state"
	"time"
)

type UnitSuite struct {
	ConnSuite
	charm *state.Charm
	unit  *state.Unit
}

var _ = Suite(&UnitSuite{})

func (s *UnitSuite) SetUpTest(c *C) {
	s.ConnSuite.SetUpTest(c)
	s.charm = s.AddTestingCharm(c, "dummy")
	svc, err := s.State.AddService("wordpress", s.charm)
	c.Assert(err, IsNil)
	s.unit, err = svc.AddUnit()
	c.Assert(err, IsNil)
}

func (s *UnitSuite) TestGetSetPublicAddress(c *C) {
	address, err := s.unit.PublicAddress()
	c.Assert(err, ErrorMatches, `public address of unit "wordpress/0" not found`)
	err = s.unit.SetPublicAddress("example.foobar.com")
	c.Assert(err, IsNil)
	address, err = s.unit.PublicAddress()
	c.Assert(err, IsNil)
	c.Assert(address, Equals, "example.foobar.com")
}

func (s *UnitSuite) TestGetSetPrivateAddress(c *C) {
	address, err := s.unit.PrivateAddress()
	c.Assert(err, ErrorMatches, `private address of unit "wordpress/0" not found`)
	err = s.unit.SetPrivateAddress("example.local")
	c.Assert(err, IsNil)
	address, err = s.unit.PrivateAddress()
	c.Assert(err, IsNil)
	c.Assert(address, Equals, "example.local")
}

func (s *UnitSuite) TestGetSetStatus(c *C) {
	fail := func() { s.unit.SetStatus(state.UnitPending, "") }
	c.Assert(fail, PanicMatches, "unit status must not be set to pending")

	status, info, err := s.unit.Status()
	c.Assert(err, IsNil)
	c.Assert(status, Equals, state.UnitPending)
	c.Assert(info, Equals, "")

	err = s.unit.SetStatus(state.UnitStarted, "")
	c.Assert(err, IsNil)
	status, info, err = s.unit.Status()
	c.Assert(err, IsNil)
	c.Assert(status, Equals, state.UnitDown)
	c.Assert(info, Equals, "")

	p, err := s.unit.SetAgentAlive()
	c.Assert(err, IsNil)
	defer func() {
		c.Assert(p.Kill(), IsNil)
	}()

	status, info, err = s.unit.Status()
	c.Assert(err, IsNil)
	c.Assert(status, Equals, state.UnitStarted)
	c.Assert(info, Equals, "")

	err = s.unit.SetStatus(state.UnitError, "test-hook failed")
	c.Assert(err, IsNil)
	status, info, err = s.unit.Status()
	c.Assert(err, IsNil)
	c.Assert(status, Equals, state.UnitError)
	c.Assert(info, Equals, "test-hook failed")
}

func (s *UnitSuite) TestUnitCharm(c *C) {
	_, err := s.unit.Charm()
	c.Assert(err, ErrorMatches, `charm URL of unit "wordpress/0" not found`)

	err = s.unit.SetCharm(s.charm)
	c.Assert(err, IsNil)

	ch, err := s.unit.Charm()
	c.Assert(err, IsNil)
	c.Assert(ch.URL(), DeepEquals, s.charm.URL())
}

func (s *UnitSuite) TestGetSetClearResolved(c *C) {
	setting, err := s.unit.Resolved()
	c.Assert(err, IsNil)
	c.Assert(setting, Equals, state.ResolvedNone)

	err = s.unit.SetResolved(state.ResolvedNoHooks)
	c.Assert(err, IsNil)
	err = s.unit.SetResolved(state.ResolvedNoHooks)
	c.Assert(err, ErrorMatches, `cannot set resolved mode for unit "wordpress/0": flag already set`)
	retry, err := s.unit.Resolved()
	c.Assert(err, IsNil)
	c.Assert(retry, Equals, state.ResolvedNoHooks)

	err = s.unit.ClearResolved()
	c.Assert(err, IsNil)
	setting, err = s.unit.Resolved()
	c.Assert(err, IsNil)
	c.Assert(setting, Equals, state.ResolvedNone)
	err = s.unit.ClearResolved()
	c.Assert(err, IsNil)

	err = s.unit.SetResolved(state.ResolvedMode(999))
	c.Assert(err, ErrorMatches, `cannot set resolved mode for unit "wordpress/0": invalid error resolution mode: 999`)
}

func (s *UnitSuite) TestGetOpenPorts(c *C) {
	// Verify no open ports before activity.
	open, err := s.unit.OpenPorts()
	c.Assert(err, IsNil)
	c.Assert(open, HasLen, 0)

	// Now open and close port.
	err = s.unit.OpenPort("tcp", 80)
	c.Assert(err, IsNil)
	open, err = s.unit.OpenPorts()
	c.Assert(err, IsNil)
	c.Assert(open, DeepEquals, []state.Port{
		{"tcp", 80},
	})

	err = s.unit.OpenPort("udp", 53)
	c.Assert(err, IsNil)
	open, err = s.unit.OpenPorts()
	c.Assert(err, IsNil)
	c.Assert(open, DeepEquals, []state.Port{
		{"tcp", 80},
		{"udp", 53},
	})

	err = s.unit.OpenPort("tcp", 53)
	c.Assert(err, IsNil)
	open, err = s.unit.OpenPorts()
	c.Assert(err, IsNil)
	c.Assert(open, DeepEquals, []state.Port{
		{"tcp", 80},
		{"udp", 53},
		{"tcp", 53},
	})

	err = s.unit.OpenPort("tcp", 443)
	c.Assert(err, IsNil)
	open, err = s.unit.OpenPorts()
	c.Assert(err, IsNil)
	c.Assert(open, DeepEquals, []state.Port{
		{"tcp", 80},
		{"udp", 53},
		{"tcp", 53},
		{"tcp", 443},
	})

	err = s.unit.ClosePort("tcp", 80)
	c.Assert(err, IsNil)
	open, err = s.unit.OpenPorts()
	c.Assert(err, IsNil)
	c.Assert(open, DeepEquals, []state.Port{
		{"udp", 53},
		{"tcp", 53},
		{"tcp", 443},
	})
}

func (s *UnitSuite) TestPathKey(c *C) {
	c.Assert(s.unit.PathKey(), Equals, "unit-wordpress-0")
}

func (s *UnitSuite) TestUnitSetAgentAlive(c *C) {
	alive, err := s.unit.AgentAlive()
	c.Assert(err, IsNil)
	c.Assert(alive, Equals, false)

	pinger, err := s.unit.SetAgentAlive()
	c.Assert(err, IsNil)
	c.Assert(pinger, Not(IsNil))
	defer pinger.Kill()

	alive, err = s.unit.AgentAlive()
	c.Assert(err, IsNil)
	c.Assert(alive, Equals, true)
}

func (s *UnitSuite) TestUnitWaitAgentAlive(c *C) {
	timeout := 5 * time.Second
	alive, err := s.unit.AgentAlive()
	c.Assert(err, IsNil)
	c.Assert(alive, Equals, false)

	err = s.unit.WaitAgentAlive(timeout)
	c.Assert(err, ErrorMatches, `waiting for agent of unit "wordpress/0": presence: still not alive after timeout`)

	pinger, err := s.unit.SetAgentAlive()
	c.Assert(err, IsNil)
	c.Assert(pinger, Not(IsNil))

	err = s.unit.WaitAgentAlive(timeout)
	c.Assert(err, IsNil)

	alive, err = s.unit.AgentAlive()
	c.Assert(err, IsNil)
	c.Assert(alive, Equals, true)

	pinger.Kill()

	alive, err = s.unit.AgentAlive()
	c.Assert(err, IsNil)
	c.Assert(alive, Equals, false)
}

type unitWatchResolvedTest struct {
	test func(*state.Unit) error
	want state.ResolvedMode
}

var unitWatchResolvedTests = []unitWatchResolvedTest{
	{func(u *state.Unit) error { return nil }, state.ResolvedNone},
	{func(u *state.Unit) error { return u.SetResolved(state.ResolvedRetryHooks) }, state.ResolvedRetryHooks},
	{func(u *state.Unit) error { return u.ClearResolved() }, state.ResolvedNone},
	{func(u *state.Unit) error { return u.SetResolved(state.ResolvedNoHooks) }, state.ResolvedNoHooks},
}

func (s *UnitSuite) TestUnitWatchResolved(c *C) {
	resolvedWatcher := s.unit.WatchResolved()
	defer func() {
		c.Assert(resolvedWatcher.Stop(), IsNil)
	}()

	for i, test := range unitWatchResolvedTests {
		c.Logf("test %d", i)
		err := test.test(s.unit)
		c.Assert(err, IsNil)
		select {
		case got, ok := <-resolvedWatcher.Changes():
			c.Assert(ok, Equals, true)
			c.Assert(got, Equals, test.want)
		case <-time.After(200 * time.Millisecond):
			c.Fatalf("did not get change: %#v", test.want)
		}
	}

	select {
	case got := <-resolvedWatcher.Changes():
		c.Fatalf("got unexpected change: %#v", got)
	case <-time.After(100 * time.Millisecond):
	}
}

type unitWatchPortsTest struct {
	test func(*state.Unit) error
	want []state.Port
}

var unitWatchPortsTests = []unitWatchPortsTest{
	{func(u *state.Unit) error { return nil }, nil},
	{func(u *state.Unit) error { return u.OpenPort("tcp", 80) }, []state.Port{{"tcp", 80}}},
	{func(u *state.Unit) error { return u.OpenPort("udp", 53) }, []state.Port{{"tcp", 80}, {"udp", 53}}},
	{func(u *state.Unit) error { return u.ClosePort("tcp", 80) }, []state.Port{{"udp", 53}}},
}

func (s *UnitSuite) TestUnitWatchPorts(c *C) {
	portsWatcher := s.unit.WatchPorts()
	defer func() {
		c.Assert(portsWatcher.Stop(), IsNil)
	}()

	for i, test := range unitWatchPortsTests {
		c.Logf("test %d", i)
		err := test.test(s.unit)
		c.Assert(err, IsNil)
		select {
		case got, ok := <-portsWatcher.Changes():
			c.Assert(ok, Equals, true)
			c.Assert(got, DeepEquals, test.want)
		case <-time.After(200 * time.Millisecond):
			c.Fatalf("did not get change: %#v", test.want)
		}
	}

	select {
	case got := <-portsWatcher.Changes():
		c.Fatalf("got unexpected change: %#v", got)
	case <-time.After(100 * time.Millisecond):
	}
}

type unitInfo struct {
	publicAddress string
	tools *state.Tools
}

var watchUnitTests = []struct {
	test func(u *state.Unit) error
	want unitInfo
}{
	{
		func(u *state.Unit) error {
			return nil
		},
		unitInfo{
			tools: &state.Tools{},
		},
	},
	{
		func(u *state.Unit) error {
			return u.SetPublicAddress("localhost")
		},
		unitInfo{
			publicAddress:      "localhost",
		},
	},
	{
		func(u *state.Unit) error {
			return u.SetAgentTools(tools(3, "baz"))
		},
		unitInfo{
			publicAddress:      "localhost",
			tools: tools(3, "baz"),
		},
	},
	{
		func(u *state.Unit) error {
			return u.SetAgentTools(tools(4, "khroomph"))
		},
		unitInfo{
			publicAddress:      "localhost",
			tools: tools(4, "khroomph"),
		},
	},
}

func (s *UnitSuite) TestWatchUnit(c *C) {
	w := s.unit.Watch()
	defer func() {
		c.Assert(w.Stop(), IsNil)
	}()
	for i, test := range watchUnitTests {
		c.Logf("test %d", i)
		err := test.test(s.unit)
		c.Assert(err, IsNil)
		select {
		case u, ok := <-w.Changes():
			c.Assert(ok, Equals, true)
			c.Assert(u.Name(), Equals, s.unit.Name())
			var info unitInfo
			info.tools, err = u.AgentTools()
			c.Assert(err, IsNil)
			info.publicAddress, err = u.PublicAddress()
			c.Assert(err, IsNil)
			c.Assert(info, DeepEquals, test.want)
		case <-time.After(500 * time.Millisecond):
			c.Fatalf("did not get change: %v", test.want)
		}
	}
	select {
	case got := <-w.Changes():
		c.Fatalf("got unexpected change: %#v", got)
	case <-time.After(100 * time.Millisecond):
	}
}
<commit_msg>state: fix test<commit_after>package state_test

import (
	. "launchpad.net/gocheck"
	"launchpad.net/juju-core/state"
	"time"
)

type UnitSuite struct {
	ConnSuite
	charm *state.Charm
	unit  *state.Unit
}

var _ = Suite(&UnitSuite{})

func (s *UnitSuite) SetUpTest(c *C) {
	s.ConnSuite.SetUpTest(c)
	s.charm = s.AddTestingCharm(c, "dummy")
	svc, err := s.State.AddService("wordpress", s.charm)
	c.Assert(err, IsNil)
	s.unit, err = svc.AddUnit()
	c.Assert(err, IsNil)
}

func (s *UnitSuite) TestGetSetPublicAddress(c *C) {
	address, err := s.unit.PublicAddress()
	c.Assert(err, ErrorMatches, `public address of unit "wordpress/0" not found`)
	err = s.unit.SetPublicAddress("example.foobar.com")
	c.Assert(err, IsNil)
	address, err = s.unit.PublicAddress()
	c.Assert(err, IsNil)
	c.Assert(address, Equals, "example.foobar.com")
}

func (s *UnitSuite) TestGetSetPrivateAddress(c *C) {
	address, err := s.unit.PrivateAddress()
	c.Assert(err, ErrorMatches, `private address of unit "wordpress/0" not found`)
	err = s.unit.SetPrivateAddress("example.local")
	c.Assert(err, IsNil)
	address, err = s.unit.PrivateAddress()
	c.Assert(err, IsNil)
	c.Assert(address, Equals, "example.local")
}

func (s *UnitSuite) TestGetSetStatus(c *C) {
	fail := func() { s.unit.SetStatus(state.UnitPending, "") }
	c.Assert(fail, PanicMatches, "unit status must not be set to pending")

	status, info, err := s.unit.Status()
	c.Assert(err, IsNil)
	c.Assert(status, Equals, state.UnitPending)
	c.Assert(info, Equals, "")

	err = s.unit.SetStatus(state.UnitStarted, "")
	c.Assert(err, IsNil)
	status, info, err = s.unit.Status()
	c.Assert(err, IsNil)
	c.Assert(status, Equals, state.UnitDown)
	c.Assert(info, Equals, "")

	p, err := s.unit.SetAgentAlive()
	c.Assert(err, IsNil)
	defer func() {
		c.Assert(p.Kill(), IsNil)
	}()

	status, info, err = s.unit.Status()
	c.Assert(err, IsNil)
	c.Assert(status, Equals, state.UnitStarted)
	c.Assert(info, Equals, "")

	err = s.unit.SetStatus(state.UnitError, "test-hook failed")
	c.Assert(err, IsNil)
	status, info, err = s.unit.Status()
	c.Assert(err, IsNil)
	c.Assert(status, Equals, state.UnitError)
	c.Assert(info, Equals, "test-hook failed")
}

func (s *UnitSuite) TestUnitCharm(c *C) {
	_, err := s.unit.Charm()
	c.Assert(err, ErrorMatches, `charm URL of unit "wordpress/0" not found`)

	err = s.unit.SetCharm(s.charm)
	c.Assert(err, IsNil)

	ch, err := s.unit.Charm()
	c.Assert(err, IsNil)
	c.Assert(ch.URL(), DeepEquals, s.charm.URL())
}

func (s *UnitSuite) TestGetSetClearResolved(c *C) {
	setting, err := s.unit.Resolved()
	c.Assert(err, IsNil)
	c.Assert(setting, Equals, state.ResolvedNone)

	err = s.unit.SetResolved(state.ResolvedNoHooks)
	c.Assert(err, IsNil)
	err = s.unit.SetResolved(state.ResolvedNoHooks)
	c.Assert(err, ErrorMatches, `cannot set resolved mode for unit "wordpress/0": flag already set`)
	retry, err := s.unit.Resolved()
	c.Assert(err, IsNil)
	c.Assert(retry, Equals, state.ResolvedNoHooks)

	err = s.unit.ClearResolved()
	c.Assert(err, IsNil)
	setting, err = s.unit.Resolved()
	c.Assert(err, IsNil)
	c.Assert(setting, Equals, state.ResolvedNone)
	err = s.unit.ClearResolved()
	c.Assert(err, IsNil)

	err = s.unit.SetResolved(state.ResolvedMode(999))
	c.Assert(err, ErrorMatches, `cannot set resolved mode for unit "wordpress/0": invalid error resolution mode: 999`)
}

func (s *UnitSuite) TestGetOpenPorts(c *C) {
	// Verify no open ports before activity.
	open, err := s.unit.OpenPorts()
	c.Assert(err, IsNil)
	c.Assert(open, HasLen, 0)

	// Now open and close port.
	err = s.unit.OpenPort("tcp", 80)
	c.Assert(err, IsNil)
	open, err = s.unit.OpenPorts()
	c.Assert(err, IsNil)
	c.Assert(open, DeepEquals, []state.Port{
		{"tcp", 80},
	})

	err = s.unit.OpenPort("udp", 53)
	c.Assert(err, IsNil)
	open, err = s.unit.OpenPorts()
	c.Assert(err, IsNil)
	c.Assert(open, DeepEquals, []state.Port{
		{"tcp", 80},
		{"udp", 53},
	})

	err = s.unit.OpenPort("tcp", 53)
	c.Assert(err, IsNil)
	open, err = s.unit.OpenPorts()
	c.Assert(err, IsNil)
	c.Assert(open, DeepEquals, []state.Port{
		{"tcp", 80},
		{"udp", 53},
		{"tcp", 53},
	})

	err = s.unit.OpenPort("tcp", 443)
	c.Assert(err, IsNil)
	open, err = s.unit.OpenPorts()
	c.Assert(err, IsNil)
	c.Assert(open, DeepEquals, []state.Port{
		{"tcp", 80},
		{"udp", 53},
		{"tcp", 53},
		{"tcp", 443},
	})

	err = s.unit.ClosePort("tcp", 80)
	c.Assert(err, IsNil)
	open, err = s.unit.OpenPorts()
	c.Assert(err, IsNil)
	c.Assert(open, DeepEquals, []state.Port{
		{"udp", 53},
		{"tcp", 53},
		{"tcp", 443},
	})
}

func (s *UnitSuite) TestPathKey(c *C) {
	c.Assert(s.unit.PathKey(), Equals, "unit-wordpress-0")
}

func (s *UnitSuite) TestUnitSetAgentAlive(c *C) {
	alive, err := s.unit.AgentAlive()
	c.Assert(err, IsNil)
	c.Assert(alive, Equals, false)

	pinger, err := s.unit.SetAgentAlive()
	c.Assert(err, IsNil)
	c.Assert(pinger, Not(IsNil))
	defer pinger.Kill()

	alive, err = s.unit.AgentAlive()
	c.Assert(err, IsNil)
	c.Assert(alive, Equals, true)
}

func (s *UnitSuite) TestUnitWaitAgentAlive(c *C) {
	timeout := 5 * time.Second
	alive, err := s.unit.AgentAlive()
	c.Assert(err, IsNil)
	c.Assert(alive, Equals, false)

	err = s.unit.WaitAgentAlive(timeout)
	c.Assert(err, ErrorMatches, `waiting for agent of unit "wordpress/0": presence: still not alive after timeout`)

	pinger, err := s.unit.SetAgentAlive()
	c.Assert(err, IsNil)
	c.Assert(pinger, Not(IsNil))

	err = s.unit.WaitAgentAlive(timeout)
	c.Assert(err, IsNil)

	alive, err = s.unit.AgentAlive()
	c.Assert(err, IsNil)
	c.Assert(alive, Equals, true)

	pinger.Kill()

	alive, err = s.unit.AgentAlive()
	c.Assert(err, IsNil)
	c.Assert(alive, Equals, false)
}

type unitWatchResolvedTest struct {
	test func(*state.Unit) error
	want state.ResolvedMode
}

var unitWatchResolvedTests = []unitWatchResolvedTest{
	{func(u *state.Unit) error { return nil }, state.ResolvedNone},
	{func(u *state.Unit) error { return u.SetResolved(state.ResolvedRetryHooks) }, state.ResolvedRetryHooks},
	{func(u *state.Unit) error { return u.ClearResolved() }, state.ResolvedNone},
	{func(u *state.Unit) error { return u.SetResolved(state.ResolvedNoHooks) }, state.ResolvedNoHooks},
}

func (s *UnitSuite) TestUnitWatchResolved(c *C) {
	resolvedWatcher := s.unit.WatchResolved()
	defer func() {
		c.Assert(resolvedWatcher.Stop(), IsNil)
	}()

	for i, test := range unitWatchResolvedTests {
		c.Logf("test %d", i)
		err := test.test(s.unit)
		c.Assert(err, IsNil)
		select {
		case got, ok := <-resolvedWatcher.Changes():
			c.Assert(ok, Equals, true)
			c.Assert(got, Equals, test.want)
		case <-time.After(200 * time.Millisecond):
			c.Fatalf("did not get change: %#v", test.want)
		}
	}

	select {
	case got := <-resolvedWatcher.Changes():
		c.Fatalf("got unexpected change: %#v", got)
	case <-time.After(100 * time.Millisecond):
	}
}

type unitWatchPortsTest struct {
	test func(*state.Unit) error
	want []state.Port
}

var unitWatchPortsTests = []unitWatchPortsTest{
	{func(u *state.Unit) error { return nil }, nil},
	{func(u *state.Unit) error { return u.OpenPort("tcp", 80) }, []state.Port{{"tcp", 80}}},
	{func(u *state.Unit) error { return u.OpenPort("udp", 53) }, []state.Port{{"tcp", 80}, {"udp", 53}}},
	{func(u *state.Unit) error { return u.ClosePort("tcp", 80) }, []state.Port{{"udp", 53}}},
}

func (s *UnitSuite) TestUnitWatchPorts(c *C) {
	portsWatcher := s.unit.WatchPorts()
	defer func() {
		c.Assert(portsWatcher.Stop(), IsNil)
	}()

	for i, test := range unitWatchPortsTests {
		c.Logf("test %d", i)
		err := test.test(s.unit)
		c.Assert(err, IsNil)
		select {
		case got, ok := <-portsWatcher.Changes():
			c.Assert(ok, Equals, true)
			c.Assert(got, DeepEquals, test.want)
		case <-time.After(200 * time.Millisecond):
			c.Fatalf("did not get change: %#v", test.want)
		}
	}

	select {
	case got := <-portsWatcher.Changes():
		c.Fatalf("got unexpected change: %#v", got)
	case <-time.After(100 * time.Millisecond):
	}
}

type unitInfo struct {
	publicAddress string
	tools *state.Tools
}

var watchUnitTests = []struct {
	test func(u *state.Unit) error
	want unitInfo
}{
	{
		func(u *state.Unit) error {
			return nil
		},
		unitInfo{
			tools: &state.Tools{},
		},
	},
	{
		func(u *state.Unit) error {
			return u.SetPublicAddress("localhost")
		},
		unitInfo{
			publicAddress:      "localhost",
			tools: &state.Tools{},
		},
	},
	{
		func(u *state.Unit) error {
			return u.SetAgentTools(tools(3, "baz"))
		},
		unitInfo{
			publicAddress:      "localhost",
			tools: tools(3, "baz"),
		},
	},
	{
		func(u *state.Unit) error {
			return u.SetAgentTools(tools(4, "khroomph"))
		},
		unitInfo{
			publicAddress:      "localhost",
			tools: tools(4, "khroomph"),
		},
	},
}

func (s *UnitSuite) TestWatchUnit(c *C) {
	w := s.unit.Watch()
	defer func() {
		c.Assert(w.Stop(), IsNil)
	}()
	for i, test := range watchUnitTests {
		c.Logf("test %d", i)
		err := test.test(s.unit)
		c.Assert(err, IsNil)
		select {
		case u, ok := <-w.Changes():
			c.Assert(ok, Equals, true)
			c.Assert(u.Name(), Equals, s.unit.Name())
			var info unitInfo
			info.tools, err = u.AgentTools()
			c.Assert(err, IsNil)
			info.publicAddress, err = u.PublicAddress()
			if _, ok := err.(*state.NotFoundError); !ok {
				c.Assert(err, IsNil)
			}
			c.Assert(info, DeepEquals, test.want, Commentf("%+v", info.tools))
		case <-time.After(500 * time.Millisecond):
			c.Fatalf("did not get change: %v", test.want)
		}
	}
	select {
	case got := <-w.Changes():
		c.Fatalf("got unexpected change: %#v", got)
	case <-time.After(100 * time.Millisecond):
	}
}
<|endoftext|>


<commit_before>/*
Copyright IBM Corp 2016 All Rights Reserved.

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 (
	"errors"
	"fmt"

	"github.com/hyperledger/fabric/core/chaincode/shim"
)

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

func main() {
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}

// Init resets all the things
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting 1")
	}

	err := stub.PutState("hello_world", []byte(args[0]))
	if err != nil {
		return nil, err
	}

	return nil, nil
}

// Invoke isur entry point to invoke a chaincode function
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("invoke is running " + function)

	// Handle different functions
	if function == "init" {
		return t.Init(stub, "init", args)
	} else if function == "write" {
		return t.write(stub, args)
	}
	fmt.Println("invoke did not find func: " + function)

	return nil, errors.New("Received unknown function invocation: " + function)
}

// Query is our entry point for queries
func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("query is running " + function)

	// Handle different functions
	if function == "read" { //read a variable
		return t.read(stub, args)
	}
	fmt.Println("query did not find func: " + function)

	return nil, errors.New("Received unknown function query: " + function)
}

// write - invoke function to write key/value pair
func (t *SimpleChaincode) write(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	var key, value string
	var err error
	fmt.Println("running write()")

	if len(args) != 2 {
		return nil, errors.New("Incorrect number of arguments. Expecting 2. name of the key and value to set")
	}

	key = args[0] //rename for funsies
	value = args[1]
	err = stub.PutState(key, []byte(value)) //write the variable into the chaincode state
	if err != nil {
		return nil, err
	}
	return nil, nil
}

// read - query function to read key/value pair
func (t *SimpleChaincode) read(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	var key, jsonResp string
	var err error

	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting name of the key to query")
	}

	key = args[0]
	valAsbytes, err := stub.GetState(key)
	if err != nil {
		jsonResp = "{\"Error\":\"Failed to get state for " + key + "\"}"
		return nil, errors.New(jsonResp)
	}

	return valAsbytes, nil
}<commit_msg>added order methods<commit_after>package main

import (
	"errors"
	"fmt"
	"strconv"
	"encoding/json"
	"github.com/hyperledger/fabric/core/chaincode/shim"
)

type SimpleChaincode struct { }

func main() {
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}

// Init resets all the things
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	if len(args) > 0 {
		return nil, errors.New("Incorrect number of arguments. Expecting 0")
	}
	return nil, nil
}

// Invoke is our entry point to invoke a chaincode function
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("invoke is running " + function)

	// Handle different functions
	if function == "addOrder" {
		investor := args[0]
		ioi, _ := strconv.ParseFloat(args[1], 64)
		return t.addOrder(stub, investor, ioi)
	}
	fmt.Println("invoke did not find func: " + function)

	return nil, errors.New("Received unknown function invocation: " + function)
}

// Query is our entry point for queries
func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("query is running " + function)

	// Handle different functions
	if function == "getOrder" { //read a variable
		investor := args[0]
		return t.getOrder(stub, investor)
	}
	fmt.Println("query did not find func: " + function)

	return nil, errors.New("Received unknown function query: " + function)
}

type Order struct {
	investor	string
	ioi 		float64
	alloc 		float64
}

func (t *SimpleChaincode) addOrder(stub shim.ChaincodeStubInterface, investor string, ioi float64) ([]byte, error)  {
	order := Order{investor: investor, ioi: ioi}
	orderJson, _ := json.Marshal(order)
	orderJsonBytes := []byte(orderJson)
	stub.PutState(investor, []byte(orderJson))
	return orderJsonBytes, nil
}

func (t *SimpleChaincode) getOrder(stub shim.ChaincodeStubInterface, investor string) ([]byte, error) {
	orderJsonBytes, _ := stub.GetState(investor)
	return orderJsonBytes, nil
}<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"strconv"
	"encoding/json"
	"github.com/hyperledger/fabric/core/chaincode/shim"
)

type Chaincode struct { }

type ChaincodeFunctions struct {
	stub shim.ChaincodeStubInterface
}

// Adding a comment
func main() {
	err := shim.Start(new(Chaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}

// Init resets all the things
func (t Chaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	if len(args) > 0 {
		return nil, errors.New("Incorrect number of arguments. Expecting 0")
	}
	_ = stub.PutState("orderbook", []byte("{}"))
	return nil, nil
}

func (t Chaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("invoke is running " + function)
	fns := ChaincodeFunctions{stub}
	if function == "addOrder" {
		investor := args[0]
		ioi, err := strconv.ParseFloat(args[1], 64)
		if err != nil {
	        return nil, errors.New("Failed to parse " + args[1] + " as a float64")
    	}
		return fns.AddOrder(investor, ioi)
	} else if function == "allocateOrder" {
		investor := args[0]
		alloc, err := strconv.ParseFloat(args[1], 64)
		if err != nil {
	        return nil, errors.New("Failed to parse " + args[1] + " as a float64")
    	}
		return fns.AllocateOrder(investor, alloc)
	}
	fmt.Println("invoke did not find func: " + function)

	return nil, errors.New("Received unknown function invocation: " + function)
}

func (t Chaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("query is running " + function)
	fns := ChaincodeFunctions{stub}
	if function == "getOrder" {
		investor := args[0]
		return fns.GetOrder(investor)
	} else if function == "getOrderbook" {
		return fns.GetOrderbook()
	}
	fmt.Println("query did not find func: " + function)

	return nil, errors.New("Received unknown function query: " + function)
}

type Order struct {
	Investor	string 		`json:"investor"`
	Ioi 		float64 	`json:"ioi"`
	Alloc 		float64		`json:"alloc"`
}

// Public Functions

func (c ChaincodeFunctions) AddOrder(investor string, ioi float64) ([]byte, error)  {
	order := Order{Investor: investor, Ioi: ioi, Alloc: 0.0}
	c.saveOrderToBlockChain(order)
	return nil, nil
}

func (c ChaincodeFunctions) GetOrder(investor string) ([]byte, error) {
	orderJson := c.getOrderAsJsonFromBlockchain(investor)
	return []byte(orderJson), nil
}

func (c ChaincodeFunctions) GetOrderbook() ([]byte, error) {
	orderbookJson, _ := c.stub.GetState("orderbook")
	return []byte(orderbookJson), nil
}

func (c ChaincodeFunctions) AllocateOrder(investor string, alloc float64) ([]byte, error) {
	order := c.getOrderFromBlockChain(investor)
	order.Alloc = alloc
	c.saveOrderToBlockChain(order)
	return nil, nil
}

// Private Functions

func (c ChaincodeFunctions) getOrderAsJsonFromBlockchain(investor string) string {
	order := c.getOrderFromBlockChain(investor)
	orderJson, _ := json.Marshal(order)
	return string(orderJson)
}

func (c ChaincodeFunctions) getOrderFromBlockChain(investor string) Order {
	orderbook := c.getOrderbookFromBlockChain()
	return orderbook[investor]
}

func (c ChaincodeFunctions) saveOrderToBlockChain(order Order) {
	orderbook := c.getOrderbookFromBlockChain()
	orderbook[order.Investor] = order
	c.saveOrderbookToBlockChain(orderbook)
}

func (c ChaincodeFunctions) getOrderbookFromBlockChain() map[string]Order {
	orderbookJson, _ := c.stub.GetState("orderbook")
	var orderbook map[string]Order
	_ = json.Unmarshal(orderbookJson, &orderbook)
	return orderbook
}

func (c ChaincodeFunctions) saveOrderbookToBlockChain(orderbook map[string]Order) {
	orderbookJson, _ := json.Marshal(orderbook)
	_ = c.stub.PutState("orderbook", []byte(orderbookJson))
}<commit_msg>batch check-in<commit_after>package main

import (
	"errors"
	"fmt"
	"strconv"
	"encoding/json"
	"github.com/hyperledger/fabric/core/chaincode/shim"
)

type Chaincode struct { }

type ChaincodeFunctions struct {
	stub shim.ChaincodeStubInterface
}

func main() {
	err := shim.Start(new(Chaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}

// Init resets all the things
func (t Chaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	if len(args) > 0 {
		return nil, errors.New("Incorrect number of arguments. Expecting 0")
	}
	_ = stub.PutState("orderbook", []byte("{}"))
	return nil, nil
}

func (t Chaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("invoke is running " + function)
	fns := ChaincodeFunctions{stub}
	if function == "addOrder" {
		investor := args[0]
		ioi, err := strconv.ParseFloat(args[1], 64)
		if err != nil {
	        return nil, errors.New("Failed to parse " + args[1] + " as a float64")
    	}
		return fns.AddOrder(investor, ioi)
	} else if function == "allocateOrder" {
		investor := args[0]
		alloc, err := strconv.ParseFloat(args[1], 64)
		if err != nil {
	        return nil, errors.New("Failed to parse " + args[1] + " as a float64")
    	}
		return fns.AllocateOrder(investor, alloc)
	}
	fmt.Println("invoke did not find func: " + function)

	return nil, errors.New("Received unknown function invocation: " + function)
}

func (t Chaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("query is running " + function)
	fns := ChaincodeFunctions{stub}
	if function == "getOrder" {
		investor := args[0]
		return fns.GetOrder(investor)
	} else if function == "getOrderbook" {
		return fns.GetOrderbook()
	}
	fmt.Println("query did not find func: " + function)

	return nil, errors.New("Received unknown function query: " + function)
}

type Order struct {
	Investor	string 		`json:"investor"`
	Ioi 		float64 	`json:"ioi"`
	Alloc 		float64		`json:"alloc"`
}

// Public Functions

func (c ChaincodeFunctions) AddOrder(investor string, ioi float64) ([]byte, error)  {
	order := Order{Investor: investor, Ioi: ioi, Alloc: 0.0}
	c.saveOrderToBlockChain(order)
	return nil, nil
}

func (c ChaincodeFunctions) GetOrder(investor string) ([]byte, error) {
	orderJson := c.getOrderAsJsonFromBlockchain(investor)
	return []byte(orderJson), nil
}

func (c ChaincodeFunctions) GetOrderbook() ([]byte, error) {
	orderbookJson, _ := c.stub.GetState("orderbook")
	return []byte(orderbookJson), nil
}

func (c ChaincodeFunctions) AllocateOrder(investor string, alloc float64) ([]byte, error) {
	order := c.getOrderFromBlockChain(investor)
	order.Alloc = alloc
	c.saveOrderToBlockChain(order)
	return nil, nil
}

// Private Functions

func (c ChaincodeFunctions) getOrderAsJsonFromBlockchain(investor string) string {
	order := c.getOrderFromBlockChain(investor)
	orderJson, _ := json.Marshal(order)
	return string(orderJson)
}

func (c ChaincodeFunctions) getOrderFromBlockChain(investor string) Order {
	orderbook := c.getOrderbookFromBlockChain()
	return orderbook[investor]
}

func (c ChaincodeFunctions) saveOrderToBlockChain(order Order) {
	orderbook := c.getOrderbookFromBlockChain()
	orderbook[order.Investor] = order
	c.saveOrderbookToBlockChain(orderbook)
}

func (c ChaincodeFunctions) getOrderbookFromBlockChain() map[string]Order {
	orderbookJson, _ := c.stub.GetState("orderbook")
	var orderbook map[string]Order
	_ = json.Unmarshal(orderbookJson, &orderbook)
	return orderbook
}

func (c ChaincodeFunctions) saveOrderbookToBlockChain(orderbook map[string]Order) {
	orderbookJson, _ := json.Marshal(orderbook)
	_ = c.stub.PutState("orderbook", []byte(orderbookJson))
}<|endoftext|>


<commit_before>package dita

import (
	"errors"
	"fmt"
	"html"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"sync/atomic"
	"time"

	"github.com/raintreeinc/knowledgebase/kb"
	"github.com/raintreeinc/knowledgebase/kb/items/index"
)

var _ *kb.Page
var _ kb.Module = &Module{}

type Module struct {
	name    string
	ditamap string
	server  *kb.Server

	cache atomic.Value
}

func New(name, ditamap string, server *kb.Server) *Module {
	mod := &Module{
		name:    name,
		ditamap: ditamap,
		server:  server,
	}
	mod.init()
	return mod
}

func (mod *Module) Info() kb.Group {
	return kb.Group{
		ID:          kb.Slugify(mod.name),
		Name:        mod.name,
		Public:      true,
		Description: "Displays \"" + mod.ditamap + "\" content.",
	}
}

func (mod *Module) init() {
	mod.cache.Store(NewConversion("", ""))
	go mod.monitor()
}

func (mod *Module) Pages() (r []kb.PageEntry) {
	cache := mod.cache.Load().(*Conversion)
	for _, page := range cache.Pages {
		r = append(r, kb.PageEntryFrom(page))
	}
	return
}

func (mod *Module) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	cache := mod.cache.Load().(*Conversion)
	path := strings.TrimPrefix(r.URL.Path, "/")
	slug := kb.Slugify(path)
	if data, ok := cache.Raw[slug]; ok {
		w.Write(data)
		return
	}

	name := kb.Slugify(mod.name)
	switch slug {
	case name + "=errors":
		page := &kb.Page{}
		page.Slug = name + "=errors"
		page.Title = "Errors"
		page.Modified = time.Now()

		page.Story.Append(kb.HTML("
Loading
"))
		for _, err := range cache.LoadErrors {
			page.Story.Append(kb.Paragraph(err.Error()))
		}

		page.Story.Append(kb.HTML("
Mapping
"))
		for _, err := range cache.MappingErrors {
			page.Story.Append(kb.Paragraph(err.Error()))
		}

		page.Story.Append(kb.HTML("
Converting
"))
		for _, errs := range cache.Errors {
			text := "
[[" + string(errs.Slug) + "]]
"
			for _, err := range errs.Errors {
				text += "
" + err.Error() + "
"
			}
			page.Story.Append(kb.HTML(text))
		}

		w.Header().Set("Content-Type", "application/json")
		if err := page.Write(w); err != nil {
			log.Println(err)
		}
		return

	case name + "=all-pages":
		page := &kb.Page{
			Slug:     name + "=all-pages",
			Title:    "All Pages",
			Modified: time.Now(),
		}

		content := "
"
		for _, slug := range cache.Slugs {
			page := cache.Pages[slug]
			content += fmt.Sprintf("
%s
", slug, html.EscapeString(page.Title))
		}
		content += "
"

		page.Story.Append(kb.HTML(content))
		page.WriteResponse(w)
		return

	case name + "=index":
		page := &kb.Page{
			Slug:     name + "=index",
			Title:    "Index",
			Modified: time.Now(),
		}

		page.Story.Append(index.New("index", cache.Nav))
		page.WriteResponse(w)
		return
	}
	http.NotFound(w, r)
}

func (mod *Module) reload() {
	start := time.Now()

	context := NewConversion(kb.Slugify(mod.name), mod.ditamap)
	context.Run()
	mod.cache.Store(context)

	log.Println("DITA reloaded (", time.Since(start), ")")
}

func (mod *Module) monitor() {
	modified := time.Now()
	mod.reload()
	for range time.Tick(3 * time.Second) {
		filepath.Walk(filepath.Dir(mod.ditamap),
			func(_ string, info os.FileInfo, err error) error {
				if err != nil {
					return err
				}
				if info.ModTime().After(modified) {
					modified = time.Now()
					mod.reload()
					return errors.New("stop iterate")
				}
				return nil
			})
	}
}
<commit_msg>Show fatal errors in dita module properly.<commit_after>package dita

import (
	"errors"
	"fmt"
	"html"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"sync/atomic"
	"time"

	"github.com/raintreeinc/knowledgebase/kb"
	"github.com/raintreeinc/knowledgebase/kb/items/index"
)

var _ *kb.Page
var _ kb.Module = &Module{}

type Module struct {
	name    string
	ditamap string
	server  *kb.Server

	cache atomic.Value
}

func New(name, ditamap string, server *kb.Server) *Module {
	mod := &Module{
		name:    name,
		ditamap: ditamap,
		server:  server,
	}
	mod.init()
	return mod
}

func (mod *Module) Info() kb.Group {
	return kb.Group{
		ID:          kb.Slugify(mod.name),
		Name:        mod.name,
		Public:      true,
		Description: "Displays \"" + mod.ditamap + "\" content.",
	}
}

func (mod *Module) init() {
	mod.cache.Store(NewConversion("", ""))
	go mod.monitor()
}

func (mod *Module) Pages() (r []kb.PageEntry) {
	cache := mod.cache.Load().(*Conversion)
	for _, page := range cache.Pages {
		r = append(r, kb.PageEntryFrom(page))
	}
	return
}

func (mod *Module) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	cache := mod.cache.Load().(*Conversion)
	path := strings.TrimPrefix(r.URL.Path, "/")
	slug := kb.Slugify(path)
	if data, ok := cache.Raw[slug]; ok {
		w.Write(data)
		return
	}

	name := kb.Slugify(mod.name)
	switch slug {
	case name + "=errors":
		page := &kb.Page{}
		page.Slug = name + "=errors"
		page.Title = "Errors"
		page.Modified = time.Now()

		page.Story.Append(kb.HTML("
Loading
"))
		for _, err := range cache.LoadErrors {
			page.Story.Append(kb.Paragraph(err.Error()))
		}

		page.Story.Append(kb.HTML("
Mapping
"))
		for _, err := range cache.MappingErrors {
			page.Story.Append(kb.Paragraph(err.Error()))
		}

		page.Story.Append(kb.HTML("
Converting
"))
		for _, errs := range cache.Errors {
			text := "
[[" + string(errs.Slug) + "]]
"
			if errs.Fatal != nil {
				text += "
" + errs.Fatal.Error() + "
"
			}
			for _, err := range errs.Errors {
				text += "
" + err.Error() + "
"
			}
			page.Story.Append(kb.HTML(text))
		}

		w.Header().Set("Content-Type", "application/json")
		if err := page.Write(w); err != nil {
			log.Println(err)
		}
		return

	case name + "=all-pages":
		page := &kb.Page{
			Slug:     name + "=all-pages",
			Title:    "All Pages",
			Modified: time.Now(),
		}

		content := "
"
		for _, slug := range cache.Slugs {
			page := cache.Pages[slug]
			content += fmt.Sprintf("
%s
", slug, html.EscapeString(page.Title))
		}
		content += "
"

		page.Story.Append(kb.HTML(content))
		page.WriteResponse(w)
		return

	case name + "=index":
		page := &kb.Page{
			Slug:     name + "=index",
			Title:    "Index",
			Modified: time.Now(),
		}

		page.Story.Append(index.New("index", cache.Nav))
		page.WriteResponse(w)
		return
	}
	http.NotFound(w, r)
}

func (mod *Module) reload() {
	start := time.Now()

	context := NewConversion(kb.Slugify(mod.name), mod.ditamap)
	context.Run()
	mod.cache.Store(context)

	log.Println("DITA reloaded (", time.Since(start), ")")
}

func (mod *Module) monitor() {
	modified := time.Now()
	mod.reload()
	for range time.Tick(3 * time.Second) {
		filepath.Walk(filepath.Dir(mod.ditamap),
			func(_ string, info os.FileInfo, err error) error {
				if err != nil {
					return err
				}
				if info.ModTime().After(modified) {
					modified = time.Now()
					mod.reload()
					return errors.New("stop iterate")
				}
				return nil
			})
	}
}
<|endoftext|>


<commit_before>package utils

import (
    Logger "github.com/sn0w/Karen/logger"
    "github.com/sn0w/Karen/models"
    rethink "gopkg.in/gorethink/gorethink.v3"
)

var dbSession *rethink.Session

func ConnectDB(url string, db string) {
    Logger.INF("[DB] Connecting to " + url)

    rethink.SetTags("rethink", "json")

    session, err := rethink.Connect(rethink.ConnectOpts{
        Address:  url,
        Database: db,
    })

    if err != nil {
        Logger.ERR("[DB] " + err.Error())
        panic(err)
        return
    }

    dbSession = session

    Logger.INF("[DB] Connected!")
}

func GetDB() *rethink.Session {
    return dbSession
}

func GuildSettingsSet(guild string, config models.Config) error {
    // Check if an config object exists
    var settings models.Config

    cursor, err := rethink.Table("guild_configs").Filter(map[string]interface{}{"guild": guild}).Run(GetDB())
    defer cursor.Close()

    if err != nil {
        return err
    }

    err = cursor.One(&settings)

    switch err {
    // Insert
    case rethink.ErrEmptyResult:
        _, err = rethink.Table("guild_configs").Insert(config).RunWrite(GetDB())
        break

    // Update
    case nil:
        _, err = rethink.Table("guild_configs").Filter(
            map[string]interface{}{"guild": guild},
        ).Update(config).RunWrite(GetDB())
        break

    default:
        panic(err)
    }

    return err
}

func GuildSettingsGet(guild string) (models.Config, error) {
    var settings models.Config
    var cursor *rethink.Cursor
    var err error

    cursor, err = rethink.Table("guild_configs").Filter(map[string]interface{}{"guild": guild}).Run(GetDB())
    defer cursor.Close()

    if err != nil {
        return settings, err
    }

    err = cursor.One(&settings)

    switch err {
    case rethink.ErrEmptyResult:
        settings = models.Config{}.Default(guild)
        return settings, nil
    default:
        return settings, err
    }
}
<commit_msg>Remove dead code<commit_after>package utils

import (
    Logger "github.com/sn0w/Karen/logger"
    "github.com/sn0w/Karen/models"
    rethink "gopkg.in/gorethink/gorethink.v3"
)

var dbSession *rethink.Session

func ConnectDB(url string, db string) {
    Logger.INF("[DB] Connecting to " + url)

    rethink.SetTags("rethink", "json")

    session, err := rethink.Connect(rethink.ConnectOpts{
        Address:  url,
        Database: db,
    })

    if err != nil {
        Logger.ERR("[DB] " + err.Error())
        panic(err)
    }

    dbSession = session

    Logger.INF("[DB] Connected!")
}

func GetDB() *rethink.Session {
    return dbSession
}

func GuildSettingsSet(guild string, config models.Config) error {
    // Check if an config object exists
    var settings models.Config

    cursor, err := rethink.Table("guild_configs").Filter(map[string]interface{}{"guild": guild}).Run(GetDB())
    defer cursor.Close()

    if err != nil {
        return err
    }

    err = cursor.One(&settings)

    switch err {
    // Insert
    case rethink.ErrEmptyResult:
        _, err = rethink.Table("guild_configs").Insert(config).RunWrite(GetDB())
        break

    // Update
    case nil:
        _, err = rethink.Table("guild_configs").Filter(
            map[string]interface{}{"guild": guild},
        ).Update(config).RunWrite(GetDB())
        break

    default:
        panic(err)
    }

    return err
}

func GuildSettingsGet(guild string) (models.Config, error) {
    var settings models.Config
    var cursor *rethink.Cursor
    var err error

    cursor, err = rethink.Table("guild_configs").Filter(map[string]interface{}{"guild": guild}).Run(GetDB())
    defer cursor.Close()

    if err != nil {
        return settings, err
    }

    err = cursor.One(&settings)

    switch err {
    case rethink.ErrEmptyResult:
        settings = models.Config{}.Default(guild)
        return settings, nil
    default:
        return settings, err
    }
}
<|endoftext|>


<commit_before>package changes

import (
	"reflect"
	"strings"
	"sync"
)

// KeyMapper defines an interface for finding the key name for a given type field.
type KeyMapper interface {
	// KeyIndexes returns the key names, and their location, for comparing. This
	// operation should be heavily cached to avoid runtime performance issues.
	KeyIndexes(reflect.Value) (KeyIndexes, error)
}

// TagMapper is a KeyMapper implements that looks up tags in a sorted order for
// key names, then falls back to the field name.
type TagMapper struct {
	tags  []string
	types map[reflect.Type]KeyIndexes
	sync.RWMutex
}

// KeyIndexes provides an ordered list of keys with their reflection indexes.
type KeyIndexes struct {
	Keys    []string
	Indexes map[string][]int
}

// NewKeyIndexes initialises a new KeyIndexes.
func NewKeyIndexes() KeyIndexes {
	return KeyIndexes{
		Keys:    []string{},
		Indexes: map[string][]int{},
	}
}

// NewTagMapper returns a new TagMapper instance.
func NewTagMapper(tags ...string) *TagMapper {
	return &TagMapper{
		tags:  tags,
		types: map[reflect.Type]KeyIndexes{},
	}
}

// KeyIndexes implements the KeyMapper interface and returns the keys and their
// locations in the value's type.
func (mapper *TagMapper) KeyIndexes(value reflect.Value) (KeyIndexes, error) {
	typ := value.Type()
	if indexes, ok := mapper.types[typ]; ok {
		return indexes, nil
	}
	return mapper.registerValue(value)
}

// registerValue will create an index lookup, save it for later use, and return it.
func (mapper *TagMapper) registerValue(value reflect.Value) (KeyIndexes, error) {
	mapper.Lock()
	indexes := mapper.registerPart("", NewKeyIndexes(), value, []int{})
	mapper.types[value.Type()] = indexes
	mapper.Unlock()
	return indexes, nil
}

func (mapper *TagMapper) registerPart(prefix string, indexes KeyIndexes, val reflect.Value, runningIndex []int) KeyIndexes {
	// Get the type of the instance supplied.
	typ := val.Type()

	for i := 0; i < typ.NumField(); i++ {
		// Loop over every field, and add the sideload entity if it exists.
		field := typ.Field(i)

		// Exclude unexported fields.
		if field.PkgPath != "" {
			continue
		}

		fieldType := field.Type
		value := val.Field(i)
		// If this is a pointer, we need to take the pointer field and value.
		if fieldType.Kind() == reflect.Ptr {
			fieldType = fieldType.Elem()
			value = value.Elem()
		}

		// Create the index value.
		index := make([]int, len(runningIndex)+1)
		copy(index, runningIndex)
		index[len(runningIndex)] = i

		/**
		 * Due to the complicity of differentiating between a straight up struct,
		 * and an implementation of a type, we just look at the first level by default.
		 * For example, how do we determine the difference between an embedded struct
		 * and a stdlib struct such as `time.Time`. Chances are we want to compare
		 * the `time.Time` vs the underlying values.
		 * An optional tag can force recursion of a struct. FieldName string `diff:"include"`
		 */
		diffTag := field.Tag.Get("diff")
		if diffTag == "exclude" {
			continue
		}

		// Generate a name for this field, which can be set via a tag.
		var tagName string
		for _, tag := range mapper.tags {
			tagName = field.Tag.Get(tag)
			if tagName != "" {
				break
			}
		}

		var name string
		if tagName != "" {
			name = prefix + tagName
		} else {
			// If recursion of a struct append field name to given prefix.
			name = prefix + field.Name

			// If struct has single field, strip period from prefix and don't append
			// inner field name.
			if typ.NumField() == 1 {
				name = strings.TrimSuffix(prefix, ".")
			}
		}

		// If this is a struct, we can go deeper - but only if it tells us to.
		if fieldType.Kind() == reflect.Struct && diffTag == "include" {
			// IsValid is true if it's not the zero value and CanInterface is true
			// if it's an exported field.
			if !value.IsValid() || !value.CanInterface() {
				continue
			}

			// If this is a struct, recurse down the chain with the interface.
			indexes = mapper.registerPart(name+".", indexes, reflect.ValueOf(value.Interface()), index)
			continue
		}
		indexes.Keys = append(indexes.Keys, name)
		indexes.Indexes[name] = index
	}
	return indexes
}
<commit_msg>Added read locking to KeyIndexes<commit_after>package changes

import (
	"reflect"
	"strings"
	"sync"
)

// KeyMapper defines an interface for finding the key name for a given type field.
type KeyMapper interface {
	// KeyIndexes returns the key names, and their location, for comparing. This
	// operation should be heavily cached to avoid runtime performance issues.
	KeyIndexes(reflect.Value) (KeyIndexes, error)
}

// TagMapper is a KeyMapper implements that looks up tags in a sorted order for
// key names, then falls back to the field name.
type TagMapper struct {
	tags  []string
	types map[reflect.Type]KeyIndexes
	sync.RWMutex
}

// KeyIndexes provides an ordered list of keys with their reflection indexes.
type KeyIndexes struct {
	Keys    []string
	Indexes map[string][]int
}

// NewKeyIndexes initialises a new KeyIndexes.
func NewKeyIndexes() KeyIndexes {
	return KeyIndexes{
		Keys:    []string{},
		Indexes: map[string][]int{},
	}
}

// NewTagMapper returns a new TagMapper instance.
func NewTagMapper(tags ...string) *TagMapper {
	return &TagMapper{
		tags:  tags,
		types: map[reflect.Type]KeyIndexes{},
	}
}

// KeyIndexes implements the KeyMapper interface and returns the keys and their
// locations in the value's type.
func (mapper *TagMapper) KeyIndexes(value reflect.Value) (KeyIndexes, error) {
	mapper.RLock()
	defer mapper.RUnlock()

	typ := value.Type()
	if indexes, ok := mapper.types[typ]; ok {
		return indexes, nil
	}
	return mapper.registerValue(value)
}

// registerValue will create an index lookup, save it for later use, and return it.
func (mapper *TagMapper) registerValue(value reflect.Value) (KeyIndexes, error) {
	mapper.Lock()
	indexes := mapper.registerPart("", NewKeyIndexes(), value, []int{})
	mapper.types[value.Type()] = indexes
	mapper.Unlock()
	return indexes, nil
}

func (mapper *TagMapper) registerPart(prefix string, indexes KeyIndexes, val reflect.Value, runningIndex []int) KeyIndexes {
	// Get the type of the instance supplied.
	typ := val.Type()

	for i := 0; i < typ.NumField(); i++ {
		// Loop over every field, and add the sideload entity if it exists.
		field := typ.Field(i)

		// Exclude unexported fields.
		if field.PkgPath != "" {
			continue
		}

		fieldType := field.Type
		value := val.Field(i)
		// If this is a pointer, we need to take the pointer field and value.
		if fieldType.Kind() == reflect.Ptr {
			fieldType = fieldType.Elem()
			value = value.Elem()
		}

		// Create the index value.
		index := make([]int, len(runningIndex)+1)
		copy(index, runningIndex)
		index[len(runningIndex)] = i

		/**
		 * Due to the complicity of differentiating between a straight up struct,
		 * and an implementation of a type, we just look at the first level by default.
		 * For example, how do we determine the difference between an embedded struct
		 * and a stdlib struct such as `time.Time`. Chances are we want to compare
		 * the `time.Time` vs the underlying values.
		 * An optional tag can force recursion of a struct. FieldName string `diff:"include"`
		 */
		diffTag := field.Tag.Get("diff")
		if diffTag == "exclude" {
			continue
		}

		// Generate a name for this field, which can be set via a tag.
		var tagName string
		for _, tag := range mapper.tags {
			tagName = field.Tag.Get(tag)
			if tagName != "" {
				break
			}
		}

		var name string
		if tagName != "" {
			name = prefix + tagName
		} else {
			// If recursion of a struct append field name to given prefix.
			name = prefix + field.Name

			// If struct has single field, strip period from prefix and don't append
			// inner field name.
			if typ.NumField() == 1 {
				name = strings.TrimSuffix(prefix, ".")
			}
		}

		// If this is a struct, we can go deeper - but only if it tells us to.
		if fieldType.Kind() == reflect.Struct && diffTag == "include" {
			// IsValid is true if it's not the zero value and CanInterface is true
			// if it's an exported field.
			if !value.IsValid() || !value.CanInterface() {
				continue
			}

			// If this is a struct, recurse down the chain with the interface.
			indexes = mapper.registerPart(name+".", indexes, reflect.ValueOf(value.Interface()), index)
			continue
		}
		indexes.Keys = append(indexes.Keys, name)
		indexes.Indexes[name] = index
	}
	return indexes
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/signal"

	"github.com/n0stack/n0stack/n0proto.go/pkg/dag"
	"github.com/urfave/cli"
	"google.golang.org/grpc"
	yaml "gopkg.in/yaml.v2"
)

// TODO: 複数ファイルを連結して処理できるようにしたい `n0cli do foo.yaml bar.yaml` みたいな
func Do(ctx *cli.Context) error {
	if ctx.NArg() == 1 {
		return do(ctx)
	}

	return fmt.Errorf("set valid arguments")
}

// TODO: エラーレスポンス
func do(ctx *cli.Context) error {
	filepath := ctx.Args().Get(0)
	buf, err := ioutil.ReadFile(filepath)
	if err != nil {
		return err
	}

	tasks := map[string]*dag.Task{}
	// _, err := toml.DecodeFile(filepath, &tasks)
	if err := yaml.Unmarshal(buf, tasks); err != nil {
		return err
	}

	endpoint := ctx.GlobalString("api-endpoint")
	conn, err := grpc.Dial(endpoint, grpc.WithInsecure())
	if err != nil {
		return err
	}
	defer conn.Close()
	log.Printf("[DEBUG] Connected to '%s'\n", endpoint)

	ctxCancel, cancel := context.WithCancel(context.Background())
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	defer func() {
		signal.Stop(c)
	}()

	go func() {
		select {
		case <-c: // SIGINT
			cancel()       // notify DoDAG to cancel
			signal.Stop(c) // allow sending SIGINT again to force SIGINT
		case <-ctxCancel.Done():
			return
		}
	}()

	dag.Marshaler = marshaler
	if err := dag.CheckDAG(tasks); err != nil {
		return err
	}

	if ok := dag.DoDAG(ctxCancel, tasks, os.Stdout, conn); !ok {
		return fmt.Errorf("Failed to do tasks")
	}

	fmt.Fprintf(os.Stderr, "DAG tasks are completed\n")
	return nil
}
<commit_msg>detect unnecessary parameters like that args parameter moved high level<commit_after>package main

import (
	"context"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/signal"

	"github.com/n0stack/n0stack/n0proto.go/pkg/dag"
	"github.com/urfave/cli"
	"google.golang.org/grpc"
	yaml "gopkg.in/yaml.v2"
)

// TODO: 複数ファイルを連結して処理できるようにしたい `n0cli do foo.yaml bar.yaml` みたいな
func Do(ctx *cli.Context) error {
	if ctx.NArg() == 1 {
		return do(ctx)
	}

	return fmt.Errorf("set valid arguments")
}

// TODO: エラーレスポンス
func do(ctx *cli.Context) error {
	filepath := ctx.Args().Get(0)
	buf, err := ioutil.ReadFile(filepath)
	if err != nil {
		return err
	}

	tasks := map[string]*dag.Task{}
	// _, err := toml.DecodeFile(filepath, &tasks)
	if err := yaml.UnmarshalStrict(buf, tasks); err != nil {
		return err
	}

	endpoint := ctx.GlobalString("api-endpoint")
	conn, err := grpc.Dial(endpoint, grpc.WithInsecure())
	if err != nil {
		return err
	}
	defer conn.Close()
	log.Printf("[DEBUG] Connected to '%s'\n", endpoint)

	ctxCancel, cancel := context.WithCancel(context.Background())
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	defer func() {
		signal.Stop(c)
	}()

	go func() {
		select {
		case <-c: // SIGINT
			cancel()       // notify DoDAG to cancel
			signal.Stop(c) // allow sending SIGINT again to force SIGINT
		case <-ctxCancel.Done():
			return
		}
	}()

	dag.Marshaler = marshaler
	if err := dag.CheckDAG(tasks); err != nil {
		return err
	}

	if ok := dag.DoDAG(ctxCancel, tasks, os.Stdout, conn); !ok {
		return fmt.Errorf("Failed to do tasks")
	}

	fmt.Fprintf(os.Stderr, "DAG tasks are completed\n")
	return nil
}
<|endoftext|>


<commit_before>package generator

import (
	"fmt"
	. "github.com/meridor/perspective-installer/data"
	"github.com/meridor/perspective-installer/wizard"
	"os"
	"path"
	"io/ioutil"
	"gopkg.in/yaml.v2"
)

const (
	fileMode = 0644
)

type DockerComposeYml struct {
	Version  string                   `yaml:"version,omitempty"`
	Services map[string]ServiceConfig `yaml:"services,omitempty"`
	Networks map[string]interface{}   `yaml:"networks,omitempty"`
}

type ServiceConfig struct {
	ContainerName string                 `yaml:"container_name,omitempty"`
	DependsOn     []string               `yaml:"depends_on,omitempty"`
	Environment   map[string]interface{} `yaml:"environment,omitempty"`
	Expose        []string               `yaml:"expose,omitempty"`
	Image         string                 `yaml:"image,omitempty"`
	Labels        []string               `yaml:"labels,omitempty"`
	Links         []string               `yaml:"links,omitempty"`
	Ports         []string               `yaml:"ports,omitempty"`
	Privileged    bool                   `yaml:"privileged,omitempty"`
	Volumes       []string               `yaml:"volumes,omitempty"`
}

type DockerComposeGenerator struct {
	BaseGenerator
	configDir string
	logsDir string
}

func (g DockerComposeGenerator) Name() string {
	return "docker-compose"
}

func (g DockerComposeGenerator) Config(config ClusterConfig) {
	fmt.Println("To use Docker Compose answer a bit more questions:")
	g.configDir = wizard.FreeInputQuestion("Specify configuration directory on Docker host machine:", "/etc/perspective")
	g.logsDir = wizard.FreeInputQuestion("Specify logs directory on Docker host machine:", "/var/log/perspective")
	if (wizard.YesNoQuestion("Will now create directories and configuration files. Proceed?", true)){
		g.createDirectory(g.logsDir)
		for cloudType, cloud := range config.Clouds {
			cloudsXmlPath := g.getCloudsXmlPath(cloudType)
			g.saveCloudsXml(cloudsXmlPath, cloud.XmlConfig)
		}
		dockerComposeYml := g.createDockerCompose(config)
		g.saveDockerCompose(dockerComposeYml)
	}
	composeYmlPath := createComposeYmlPath(g.Dir)
	fmt.Printf(
		"Use the following command to start cluster: docker-compose -f %s up\n",
		composeYmlPath,
	)
	fmt.Printf(
		"To completely remove cluster type: docker-compose -f %s down && rm -Rf %s && rm -Rf %s\n",
		composeYmlPath,
		g.configDir,
		g.logsDir,
	)
}

func (g DockerComposeGenerator) createDirectory(path string) {
	fmt.Printf("Creating directory [%s]...\n", path)
	if (!g.DryRun) {
		err := os.MkdirAll(path, fileMode)
		if (err != nil) {
			fmt.Printf("Failed to create directory [%s]: %v. Exiting.", path, err)
			os.Exit(1)
		}
	}
}

func (g DockerComposeGenerator) getCloudsXmlPath(cloudType CloudType) string {
	dirName := prepareCloudType(cloudType)
	cloudDir := path.Join(g.configDir, dirName)
	g.createDirectory(cloudDir)
	return path.Join(cloudDir, "clouds.xml")
}

func (g DockerComposeGenerator) saveCloudsXml(path string, cloudsXml CloudsXml) {
	cloudsXmlContents := marshalCloudsXml(cloudsXml)
	fmt.Printf("Saving [%s]...\n", path)
	if (g.DryRun) {
		fmt.Println(string(cloudsXmlContents))
	} else {
		err := ioutil.WriteFile(path, cloudsXmlContents, fileMode)
		exitIfFailed(path, err)
	}
}

func (g DockerComposeGenerator) createDockerCompose(config ClusterConfig) DockerComposeYml {
	dockerComposeYml := DockerComposeYml{
		Version: "2.1",
		Services: make(map[string] ServiceConfig),
	}
	dockerComposeYml.Services["storage"] = g.createStorageService(config)
	dockerComposeYml.Services["rest"] = g.createRestService(config)
	for cloudType := range config.Clouds {
		workerServiceName := prepareCloudType(cloudType)
		dockerComposeYml.Services[workerServiceName] = g.createWorkerService(cloudType, config.Version)
	}
	return dockerComposeYml
}

func (g DockerComposeGenerator) createEnvironment(serviceName string) map[string] interface{} {
	env := make(map[string] interface{})
	env["MISC_OPTS"] = "-Dperspective.storage.hosts=storage:5801"
	env["LOGGING_OPTS"] = " >> " + path.Join(g.logsDir, serviceName + ".log")
	return env
}

func (g DockerComposeGenerator) createStorageService(config ClusterConfig) ServiceConfig {
	env := g.createEnvironment("perspective-storage")
	delete(env, "MISC_OPTS")
	return ServiceConfig{
		ContainerName: "perspective-storage",
		Image: fmt.Sprintf("meridor/perspective-storage:%s", config.Version),
		Environment: env,
		Volumes: []string{volume(g.logsDir), readOnlyVolume(path.Join(g.configDir, "storage"))},
	}
}

func readOnlyVolume(dir string) string {
	return fmt.Sprintf("%s:ro", volume(dir))
}

func volume(dir string) string {
	return fmt.Sprintf("%s:%s", dir, dir)
}

func (g DockerComposeGenerator) createRestService(config ClusterConfig) ServiceConfig {
	return ServiceConfig{
		ContainerName: "perspective-rest",
		Image: fmt.Sprintf("meridor/perspective-rest:%s", config.Version),
		Ports: []string{fmt.Sprintf("8080:%d", config.ApiPort)},
		Environment: g.createEnvironment("perspective-rest"),
		Links: []string{"storage"},
		DependsOn: []string{"storage"},
		Volumes: []string{volume(g.logsDir), readOnlyVolume(path.Join(g.configDir, "rest"))},
	}
}

func (g DockerComposeGenerator) createWorkerService(cloudType CloudType, version string) ServiceConfig {
	suffix := prepareCloudType(cloudType)
	volumes := []string{volume(g.logsDir), readOnlyVolume(path.Join(g.configDir, suffix))}
	if (cloudType == DOCKER) {
		volumes = append(volumes, volume("/var/run"))
	}
	return ServiceConfig{
		ContainerName: fmt.Sprintf("perspective-%s", suffix),
		Image: fmt.Sprintf("meridor/%s:%s", suffix, version),
		Environment: g.createEnvironment(suffix),
		Links: []string{"storage"},
		DependsOn: []string{"rest"},
		Volumes: volumes,
	}
}

func (g DockerComposeGenerator) saveDockerCompose(composeYml DockerComposeYml) {
	bytes, err := yaml.Marshal(&composeYml)
	if (err != nil) {
		fmt.Printf("Failed to generate docker-compose.yml contents: %v\n", err)
	}
	ymlString := string(bytes)
	ymlPath := createComposeYmlPath(g.Dir)
	fmt.Printf("Saving [%s]...\n", ymlPath)
	if (g.DryRun) {
		fmt.Println(ymlString)
	} else {
		g.createDirectory(g.Dir)
		err := ioutil.WriteFile(ymlPath, bytes, fileMode)
		exitIfFailed(ymlPath, err)
	}
}

func createComposeYmlPath(dir string) string {
	return path.Join(dir, "docker-compose.yml")
}<commit_msg>Added worker image name for compose<commit_after>package generator

import (
	"fmt"
	. "github.com/meridor/perspective-installer/data"
	"github.com/meridor/perspective-installer/wizard"
	"os"
	"path"
	"io/ioutil"
	"gopkg.in/yaml.v2"
)

const (
	fileMode = 0644
)

type DockerComposeYml struct {
	Version  string                   `yaml:"version,omitempty"`
	Services map[string]ServiceConfig `yaml:"services,omitempty"`
	Networks map[string]interface{}   `yaml:"networks,omitempty"`
}

type ServiceConfig struct {
	ContainerName string                 `yaml:"container_name,omitempty"`
	DependsOn     []string               `yaml:"depends_on,omitempty"`
	Environment   map[string]interface{} `yaml:"environment,omitempty"`
	Expose        []string               `yaml:"expose,omitempty"`
	Image         string                 `yaml:"image,omitempty"`
	Labels        []string               `yaml:"labels,omitempty"`
	Links         []string               `yaml:"links,omitempty"`
	Ports         []string               `yaml:"ports,omitempty"`
	Privileged    bool                   `yaml:"privileged,omitempty"`
	Volumes       []string               `yaml:"volumes,omitempty"`
}

type DockerComposeGenerator struct {
	BaseGenerator
	configDir string
	logsDir string
}

func (g DockerComposeGenerator) Name() string {
	return "docker-compose"
}

func (g DockerComposeGenerator) Config(config ClusterConfig) {
	fmt.Println("To use Docker Compose answer a bit more questions:")
	g.configDir = wizard.FreeInputQuestion("Specify configuration directory on Docker host machine:", "/etc/perspective")
	g.logsDir = wizard.FreeInputQuestion("Specify logs directory on Docker host machine:", "/var/log/perspective")
	if (wizard.YesNoQuestion("Will now create directories and configuration files. Proceed?", true)){
		g.createDirectory(g.logsDir)
		for cloudType, cloud := range config.Clouds {
			cloudsXmlPath := g.getCloudsXmlPath(cloudType)
			g.saveCloudsXml(cloudsXmlPath, cloud.XmlConfig)
		}
		dockerComposeYml := g.createDockerCompose(config)
		g.saveDockerCompose(dockerComposeYml)
	}
	composeYmlPath := createComposeYmlPath(g.Dir)
	fmt.Printf(
		"Use the following command to start cluster: docker-compose -f %s up\n",
		composeYmlPath,
	)
	fmt.Printf(
		"To completely remove cluster type: docker-compose -f %s down && rm -Rf %s && rm -Rf %s\n",
		composeYmlPath,
		g.configDir,
		g.logsDir,
	)
}

func (g DockerComposeGenerator) createDirectory(path string) {
	fmt.Printf("Creating directory [%s]...\n", path)
	if (!g.DryRun) {
		err := os.MkdirAll(path, fileMode)
		if (err != nil) {
			fmt.Printf("Failed to create directory [%s]: %v. Exiting.", path, err)
			os.Exit(1)
		}
	}
}

func (g DockerComposeGenerator) getCloudsXmlPath(cloudType CloudType) string {
	dirName := prepareCloudType(cloudType)
	cloudDir := path.Join(g.configDir, dirName)
	g.createDirectory(cloudDir)
	return path.Join(cloudDir, "clouds.xml")
}

func (g DockerComposeGenerator) saveCloudsXml(path string, cloudsXml CloudsXml) {
	cloudsXmlContents := marshalCloudsXml(cloudsXml)
	fmt.Printf("Saving [%s]...\n", path)
	if (g.DryRun) {
		fmt.Println(string(cloudsXmlContents))
	} else {
		err := ioutil.WriteFile(path, cloudsXmlContents, fileMode)
		exitIfFailed(path, err)
	}
}

func (g DockerComposeGenerator) createDockerCompose(config ClusterConfig) DockerComposeYml {
	dockerComposeYml := DockerComposeYml{
		Version: "2.1",
		Services: make(map[string] ServiceConfig),
	}
	dockerComposeYml.Services["storage"] = g.createStorageService(config)
	dockerComposeYml.Services["rest"] = g.createRestService(config)
	for cloudType := range config.Clouds {
		workerServiceName := prepareCloudType(cloudType)
		dockerComposeYml.Services[workerServiceName] = g.createWorkerService(cloudType, config.Version)
	}
	return dockerComposeYml
}

func (g DockerComposeGenerator) createEnvironment(serviceName string) map[string] interface{} {
	env := make(map[string] interface{})
	env["MISC_OPTS"] = "-Dperspective.storage.hosts=storage:5801"
	env["LOGGING_OPTS"] = " >> " + path.Join(g.logsDir, serviceName + ".log")
	return env
}

func (g DockerComposeGenerator) createStorageService(config ClusterConfig) ServiceConfig {
	env := g.createEnvironment("perspective-storage")
	delete(env, "MISC_OPTS")
	return ServiceConfig{
		ContainerName: "perspective-storage",
		Image: fmt.Sprintf("meridor/perspective-storage:%s", config.Version),
		Environment: env,
		Volumes: []string{volume(g.logsDir), readOnlyVolume(path.Join(g.configDir, "storage"))},
	}
}

func readOnlyVolume(dir string) string {
	return fmt.Sprintf("%s:ro", volume(dir))
}

func volume(dir string) string {
	return fmt.Sprintf("%s:%s", dir, dir)
}

func (g DockerComposeGenerator) createRestService(config ClusterConfig) ServiceConfig {
	return ServiceConfig{
		ContainerName: "perspective-rest",
		Image: fmt.Sprintf("meridor/perspective-rest:%s", config.Version),
		Ports: []string{fmt.Sprintf("8080:%d", config.ApiPort)},
		Environment: g.createEnvironment("perspective-rest"),
		Links: []string{"storage"},
		DependsOn: []string{"storage"},
		Volumes: []string{volume(g.logsDir), readOnlyVolume(path.Join(g.configDir, "rest"))},
	}
}

func (g DockerComposeGenerator) createWorkerService(cloudType CloudType, version string) ServiceConfig {
	suffix := prepareCloudType(cloudType)
	volumes := []string{volume(g.logsDir), readOnlyVolume(path.Join(g.configDir, suffix))}
	if (cloudType == DOCKER) {
		volumes = append(volumes, volume("/var/run"))
	}
	return ServiceConfig{
		ContainerName: fmt.Sprintf("perspective-%s", suffix),
		Image: fmt.Sprintf("meridor/perspective-%s:%s", suffix, version),
		Environment: g.createEnvironment(suffix),
		Links: []string{"storage"},
		DependsOn: []string{"rest"},
		Volumes: volumes,
	}
}

func (g DockerComposeGenerator) saveDockerCompose(composeYml DockerComposeYml) {
	bytes, err := yaml.Marshal(&composeYml)
	if (err != nil) {
		fmt.Printf("Failed to generate docker-compose.yml contents: %v\n", err)
	}
	ymlString := string(bytes)
	ymlPath := createComposeYmlPath(g.Dir)
	fmt.Printf("Saving [%s]...\n", ymlPath)
	if (g.DryRun) {
		fmt.Println(ymlString)
	} else {
		g.createDirectory(g.Dir)
		err := ioutil.WriteFile(ymlPath, bytes, fileMode)
		exitIfFailed(ymlPath, err)
	}
}

func createComposeYmlPath(dir string) string {
	return path.Join(dir, "docker-compose.yml")
}<|endoftext|>


<commit_before>// Copyright 2017, TCN Inc.
// All rights reserved.

// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:

//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of TCN Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.

// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package generator

import (
	"github.com/golang/protobuf/proto"
	"github.com/golang/protobuf/protoc-gen-go/descriptor"
	"github.com/tcncloud/protoc-gen-persist/persist"
)

type Service struct {
	Desc       *descriptor.ServiceDescriptorProto
	Methods    *Methods
	Package    string // protobuf package
	File       *FileStruct
	AllStructs *StructList
}

func (s *Service) ProcessMethods() {
	for _, m := range s.Desc.GetMethod() {
		s.Methods.AddMethod(m, s)
	}
}

func (s *Service) Process() {
	s.ProcessMethods()
}

func (s *Service) GetName() string {
	return s.Desc.GetName()
}

func (s *Service) GetServiceOption() *persist.TypeMapping {
	if s.Desc.Options != nil && proto.HasExtension(s.Desc.Options, persist.E_Mapping) {
		ext, err := proto.GetExtension(s.Desc.Options, persist.E_Mapping)
		if err == nil {
			return ext.(*persist.TypeMapping)
		}
	}
	return nil
}

func (s *Service) IsSQL() bool {
	for _, m := range *s.Methods {
		if m.IsSQL() {
			return true
		}
	}
	return false
}

// func (s *Service) IsMongo() bool {
// 	for _, m := range *s.Methods {
// 		if m.IsMongo() {
// 			return true
// 		}
// 	}
// 	return false
// }
//
// func (s *Service) IsSpanner() bool {
// 	for _, m := range *s.Methods {
// 		if m.IsSpanner() {
// 			return true
// 		}
// 	}
// 	return false
// }

func (s *Service) IsServiceEnabled() bool {
	if s.GetServiceOption() != nil {
		return true
	}
	for _, m := range *s.Methods {
		if m.IsSQL() {
			return true
		}
	}
	return false
}

func (s *Service) ProcessImports() {
	s.File.ImportList.GetOrAddImport("io", "io")
	s.File.ImportList.GetOrAddImport("strings", "strings")
	s.File.ImportList.GetOrAddImport("context", "golang.org/x/net/context")
	s.File.ImportList.GetOrAddImport("grpc", "google.golang.org/grpc")
	s.File.ImportList.GetOrAddImport("codes", "google.golang.org/grpc/codes")
	if opt := s.GetServiceOption(); opt != nil {
		for _, m := range opt.GetTypes() {
			s.File.ImportList.GetOrAddImport(GetGoPackage(m.GetGoPackage()), GetGoPath(m.GetGoPackage()))
		}
	}
	for _, met := range *s.Methods {
		met.ProcessImports()
	}
}

type Services []*Service

func (s *Services) AddService(pkg string, desc *descriptor.ServiceDescriptorProto, allStructs *StructList, file *FileStruct) *Service {
	ret := &Service{
		Package:    pkg,
		Desc:       desc,
		Methods:    &Methods{},
		AllStructs: allStructs,
		File:       file,
	}
	ret.ProcessMethods()
	*s = append(*s, ret)
	return ret
}

func (s *Services) Process() {
	for _, srv := range *s {
		srv.Process()
	}
}
<commit_msg>add string method, logging, bubble up errors<commit_after>// Copyright 2017, TCN Inc.
// All rights reserved.

// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:

//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of TCN Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.

// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package generator

import (
	"github.com/golang/protobuf/proto"
	"fmt"
	"github.com/Sirupsen/logrus"
	"github.com/golang/protobuf/protoc-gen-go/descriptor"
	"github.com/tcncloud/protoc-gen-persist/persist"
)

type Service struct {
	Desc       *descriptor.ServiceDescriptorProto
	Methods    *Methods
	Package    string // protobuf package
	File       *FileStruct
	AllStructs *StructList
}

func (s *Service) String() string {
	var ms string
	if s.Methods != nil {
		ms = fmt.Sprintf("%s", s.Methods)
	} else {
		ms = "<nil>"
	}
	sname := s.Desc.GetName()
	fname := s.File.Desc.GetName()
	return fmt.Sprintf("\nSERVICE:\n\tPackage: %s\n\tServiceName: %s\n\tFileName: %s\n\tService Methods: %+v\n\n",
			s.Package, sname, fname, ms)
}

func (s *Service) ProcessMethods() error {
	for _, m := range s.Desc.GetMethod() {
		err := s.Methods.AddMethod(m, s)
		if err != nil {
			return err
		}
	}
	return nil
}

func (s *Service) Process() error {
	return s.ProcessMethods()
}

func (s *Service) GetName() string {
	return s.Desc.GetName()
}

func (s *Service) GetServiceOption() *persist.TypeMapping {
	if s.Desc.Options != nil && proto.HasExtension(s.Desc.Options, persist.E_Mapping) {
		ext, err := proto.GetExtension(s.Desc.Options, persist.E_Mapping)
		if err == nil {
			return ext.(*persist.TypeMapping)
		}
	}
	return nil
}

func (s *Service) GetServiceType() *persist.PersistenceOptions {
	if s.Desc.Options != nil && proto.HasExtension(s.Desc.Options, persist.E_ServiceType) {
		ext, err := proto.GetExtension(s.Desc.Options, persist.E_ServiceType)
		if err == nil {
			return ext.(*persist.PersistenceOptions)
		}
	}
	return nil
}

func (s *Service) IsSQL() bool {
	if p := s.GetServiceType(); p != nil {
		if *p == persist.PersistenceOptions_SQL {
			return true
		}
	}
	return false
}

// func (s *Service) IsMongo() bool {
// 	for _, m := range *s.Methods {
// 		if m.IsMongo() {
// 			return true
// 		}
// 	}
// 	return false
// }
//
func (s *Service) IsSpanner() bool {
	if p := s.GetServiceType(); p != nil {
		if *p == persist.PersistenceOptions_SPANNER {
			return true
		}
	}
	return false
}

func (s *Service) IsServiceEnabled() bool {
	if s.GetServiceOption() != nil {
		return true
	}
	if s.IsSQL() || s.IsSpanner() {
		return true
	}
	return false
}

func (s *Service) ProcessImports() {
	logrus.Warn("PROCESS IMPORTS FOR SERVICE CALLED")
	s.File.ImportList.GetOrAddImport("io", "io")
	s.File.ImportList.GetOrAddImport("strings", "strings")
	s.File.ImportList.GetOrAddImport("context", "golang.org/x/net/context")
	s.File.ImportList.GetOrAddImport("grpc", "google.golang.org/grpc")
	s.File.ImportList.GetOrAddImport("codes", "google.golang.org/grpc/codes")
	if opt := s.GetServiceOption(); opt != nil {
		for _, m := range opt.GetTypes() {
			logrus.Warnf("adding import: %+v  for type: %s",GetGoPackage(m.GetGoPackage()), m)
			s.File.ImportList.GetOrAddImport(GetGoPackage(m.GetGoPackage()), GetGoPath(m.GetGoPackage()))
		}
	}
	for _, met := range *s.Methods {
		met.ProcessImports()
	}
}

type Services []*Service

func (s *Services) AddService(pkg string, desc *descriptor.ServiceDescriptorProto, allStructs *StructList, file *FileStruct) *Service {
	ret := &Service{
		Package:    pkg,
		Desc:       desc,
		Methods:    &Methods{},
		AllStructs: allStructs,
		File:       file,
	}
	ret.ProcessMethods()
	logrus.Debugf("created a service: %s", ret)
	*s = append(*s, ret)
	return ret
}

func (s *Services) Process() error {
	for _, srv := range *s {
		err := srv.Process()
		if err != nil {
			return err
		}
	}
	return nil
}

func (s *Services) PreGenerate() error {
	for _, srv := range *s {
		err := srv.Methods.PreGenerate()
		if err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"							//used for unifrom database access
	"fmt"									//print statements
	"github.com/go-martini/martini"			//extra frame work build on net/http
	_ "github.com/lib/pq"					//go sql driver
	"net/http"								//framework
	"os"
)

func SetupDB() *sql.DB {
	//POSTGRESDB_PORT_5432_TCP_PORT  10.254.76.103
	db, err := sql.Open("postgres", "host=10.254.177.139 user=postgres dbname=postgres sslmode=disable") 		//my only lib/pq usage? login into postgres database
	PanicIf(err)

	return db
}

func PanicIf(err error) {
	if err != nil {
		panic(err)
	}
}

func ShowDB(db *sql.DB, r *http.Request, rw http.ResponseWriter) { //localhost:3000/?search=name
		search := "%" + r.URL.Query().Get("search") + "%"
		rows, err := db.Query(`SELECT fname, LName, cost, city
                           FROM custauth
                           WHERE FName ILIKE $1
                           OR LName ILIKE $1
                           OR city ILIKE $1`, search)
		PanicIf(err)
		defer rows.Close()

		var FirstName, LastName, cost, city string
		for rows.Next() {
			err := rows.Scan(&FirstName, &LastName, &cost, &city)
			PanicIf(err)
			fmt.Fprintf(rw, "First Name: %s\nLast Name: %s\nCost: %s\nCity: %s\n\n", FirstName, LastName, cost, city)
		}
	}

func InsertPur(r *http.Request, db *sql.DB){
//	_, err := db.Query("INSERT INTO custauth (custid, fname, lname, city,state, country,email,cost,errorflag) VALUES ($1, $2, $3, $4, $5, $6, $7, $8,$9)",
	_, err := db.Exec("INSERT INTO custauth (custid, fname, lname, city,state, country,email,cost,errorflag) VALUES ($1, $2, $3, $4, $5, $6, $7, $8,$9)",
	r.FormValue("custid"),
		r.FormValue("fname"),
		r.FormValue("lname"),
		r.FormValue("city"),
		r.FormValue("state"),
		r.FormValue("country"),
		r.FormValue("email"),
		r.FormValue("cost"),
		r.FormValue("errorflag"))

	PanicIf(err)
}

func main() {
	m := martini.Classic()
	m.Map(SetupDB())
	m.Get("/", func() string {return  "Hello to GoSQL database v2"})
  	m.Get("/var", func() []string {return  os.Environ() })
	m.Get("/show", ShowDB)
	m.Post("/add", InsertPur)
	m.Run()
}
<commit_msg>reading env vars<commit_after>package main

import (
	"database/sql"							//used for unifrom database access
	"fmt"									//print statements
	"github.com/go-martini/martini"			//extra frame work build on net/http
	_ "github.com/lib/pq"					//go sql driver
	"net/http"								//framework
	"strings"
	"os"
)

func SetupDB() *sql.DB {
	//POSTGRESDB_PORT_5432_TCP_PORT  10.254.76.103
	db, err := sql.Open("postgres", "host=os.Getenv(POSTGRESDB_PORT_5432_TCP_PORT) user=postgres dbname=postgres sslmode=disable") 		//my only lib/pq usage? login into postgres database
	PanicIf(err)

	return db
}

func PanicIf(err error) {
	if err != nil {
		panic(err)
	}
}

func ShowDB(db *sql.DB, r *http.Request, rw http.ResponseWriter) { //localhost:3000/?search=name
		search := "%" + r.URL.Query().Get("search") + "%"
		rows, err := db.Query(`SELECT fname, LName, cost, city
                           FROM custauth
                           WHERE FName ILIKE $1
                           OR LName ILIKE $1
                           OR city ILIKE $1`, search)
		PanicIf(err)
		defer rows.Close()

		var FirstName, LastName, cost, city string
		for rows.Next() {
			err := rows.Scan(&FirstName, &LastName, &cost, &city)
			PanicIf(err)
			fmt.Fprintf(rw, "First Name: %s\nLast Name: %s\nCost: %s\nCity: %s\n\n", FirstName, LastName, cost, city)
		}
	}

func InsertPur(r *http.Request, db *sql.DB){
//	_, err := db.Query("INSERT INTO custauth (custid, fname, lname, city,state, country,email,cost,errorflag) VALUES ($1, $2, $3, $4, $5, $6, $7, $8,$9)",
	_, err := db.Exec("INSERT INTO custauth (custid, fname, lname, city,state, country,email,cost,errorflag) VALUES ($1, $2, $3, $4, $5, $6, $7, $8,$9)",
	r.FormValue("custid"),
		r.FormValue("fname"),
		r.FormValue("lname"),
		r.FormValue("city"),
		r.FormValue("state"),
		r.FormValue("country"),
		r.FormValue("email"),
		r.FormValue("cost"),
		r.FormValue("errorflag"))

	PanicIf(err)
}

func main() {
	m := martini.Classic()
	m.Map(SetupDB())
	m.Get("/", func() string {return  "Hello to GoSQL database v3"})
  	m.Get("/var", func() string {
	for _, e := range os.Environ() {
        pair := strings.Split(e, "=")
		 fmt.Println(pair[0])}
		 return "yo"
	})
	m.Get("/show", ShowDB)
	m.Post("/add", InsertPur)
	m.Run()
}
<|endoftext|>