<commit_before>package main

import (
	"fmt"
	"github.com/gorilla/mux"
	"github.com/minotar/minecraft"
	"net/http"
	"strconv"
	"strings"
)

type Router struct {
	Mux *mux.Router
}

type NotFoundHandler struct{}

// Handles 404 errors
func (h NotFoundHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(404)
	fmt.Fprintf(w, "404 not found")
}

// Converts and sanitizes the string for the avatar size.
func (r *Router) GetSize(inp string) uint {
	out64, err := strconv.ParseUint(inp, 10, 0)
	out := uint(out64)
	if err != nil {
		return DefaultSize
	} else if out > MaxSize {
		return MaxSize
	} else if out < MinSize {
		return MinSize
	}
	return out

}

// Shows only the user's skin.
func (router *Router) SkinPage(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)

	username := vars["username"]

	skin := fetchSkin(username)

	w.Header().Add("Content-Type", "image/png")
	w.Header().Add("X-Requested", "skin")
	w.Header().Add("X-Result", "ok")

	skin.WriteSkin(w)
}

// Shows the skin and tells the browser to attempt to download it.
func (router *Router) DownloadPage(w http.ResponseWriter, r *http.Request) {
	w.Header().Add("Content-Disposition", "attachment; filename=\"skin.png\"")
	router.SkinPage(w, r)
}

// Pull the Get<resource> method from the skin. Originally this used
// reflection, but that was slow.
func (router *Router) ResolveMethod(skin *mcSkin, resource string) func(int) error {
	stats.Served(resource)

	switch resource {
	case "Avatar":
		return skin.GetHead
	case "Helm":
		return skin.GetHelm
	case "Cube":
		return skin.GetCube
	case "Bust":
		return skin.GetBust
	case "Body":
		return skin.GetBody
	case "Armor/Bust":
		return skin.GetArmorBust
	case "Armour/Bust":
		return skin.GetArmorBust
	case "Armor/Body":
		return skin.GetArmorBody
	case "Armour/Body":
		return skin.GetArmorBody
	default:
		return skin.GetHelm
	}
}

// Binds the route and makes a handler function for the requested resource.
func (router *Router) Serve(resource string) {
	fn := func(w http.ResponseWriter, r *http.Request) {
		vars := mux.Vars(r)
		size := router.GetSize(vars["size"])
		skin := fetchSkin(vars["username"])

		err := router.ResolveMethod(skin, resource)(int(size))
		if err != nil {
			w.WriteHeader(500)
			fmt.Fprintf(w, "500 internal server error")
			return
		}

		w.Header().Add("Content-Type", "image/png")
		w.Header().Add("Cache-Control", fmt.Sprintf("public, max-age=%d", TimeoutActualSkin))
		w.Header().Add("ETag", skin.Hash)
		skin.WritePNG(w)
	}

	router.Mux.HandleFunc("/"+strings.ToLower(resource)+"/{username:"+minecraft.ValidUsernameRegex+"}{extension:(.png)?}", fn)
	router.Mux.HandleFunc("/"+strings.ToLower(resource)+"/{username:"+minecraft.ValidUsernameRegex+"}/{size:[0-9]+}{extension:(.png)?}", fn)
}

// Binds routes to the ServerMux.
func (router *Router) Bind() {

	router.Mux.NotFoundHandler = NotFoundHandler{}

	router.Serve("Avatar")
	router.Serve("Helm")
	router.Serve("Cube")
	router.Serve("Bust")
	router.Serve("Body")
	router.Serve("Armor/Bust")
	router.Serve("Armour/Bust")
	router.Serve("Armor/Body")
	router.Serve("Armour/Body")

	router.Mux.HandleFunc("/download/{username:"+minecraft.ValidUsernameRegex+"}{extension:(.png)?}", router.DownloadPage)
	router.Mux.HandleFunc("/skin/{username:"+minecraft.ValidUsernameRegex+"}{extension:(.png)?}", router.SkinPage)

	router.Mux.HandleFunc("/version", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "%s", MinotarVersion)
	})

	router.Mux.HandleFunc("/stats", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		w.Write(stats.ToJSON())
	})

	router.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		http.Redirect(w, r, "https://minotar.net/", 302)
	})
}

func fetchSkin(username string) *mcSkin {
	if cache.has(strings.ToLower(username)) {
		stats.HitCache()
		return &mcSkin{Processed: nil, Skin: cache.pull(strings.ToLower(username))}
	}

	skin, err := minecraft.FetchSkinFromMojang(username)
	if err != nil {
		log.Error("Failed Skin Mojang: " + username + " (" + err.Error() + ")")
		// Let's fallback to S3 and try and serve at least an old skin...
		skin, err = minecraft.FetchSkinFromS3(username)
		if err != nil {
			log.Error("Failed Skin S3: " + username + " (" + err.Error() + ")")
			// Well, looks like they don't exist after all.
			skin, _ = minecraft.FetchSkinForChar()
		}
	}

	stats.MissCache()
	cache.add(strings.ToLower(username), skin)

	return &mcSkin{Processed: nil, Skin: skin}
}
<commit_msg>Send not modified if on matching hash<commit_after>package main

import (
	"fmt"
	"github.com/gorilla/mux"
	"github.com/minotar/minecraft"
	"net/http"
	"strconv"
	"strings"
)

type Router struct {
	Mux *mux.Router
}

type NotFoundHandler struct{}

// Handles 404 errors
func (h NotFoundHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(404)
	fmt.Fprintf(w, "404 not found")
}

// Converts and sanitizes the string for the avatar size.
func (r *Router) GetSize(inp string) uint {
	out64, err := strconv.ParseUint(inp, 10, 0)
	out := uint(out64)
	if err != nil {
		return DefaultSize
	} else if out > MaxSize {
		return MaxSize
	} else if out < MinSize {
		return MinSize
	}
	return out

}

// Shows only the user's skin.
func (router *Router) SkinPage(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)

	username := vars["username"]

	skin := fetchSkin(username)

	w.Header().Add("Content-Type", "image/png")
	w.Header().Add("X-Requested", "skin")
	w.Header().Add("X-Result", "ok")

	skin.WriteSkin(w)
}

// Shows the skin and tells the browser to attempt to download it.
func (router *Router) DownloadPage(w http.ResponseWriter, r *http.Request) {
	w.Header().Add("Content-Disposition", "attachment; filename=\"skin.png\"")
	router.SkinPage(w, r)
}

// Pull the Get<resource> method from the skin. Originally this used
// reflection, but that was slow.
func (router *Router) ResolveMethod(skin *mcSkin, resource string) func(int) error {
	stats.Served(resource)

	switch resource {
	case "Avatar":
		return skin.GetHead
	case "Helm":
		return skin.GetHelm
	case "Cube":
		return skin.GetCube
	case "Bust":
		return skin.GetBust
	case "Body":
		return skin.GetBody
	case "Armor/Bust":
		return skin.GetArmorBust
	case "Armour/Bust":
		return skin.GetArmorBust
	case "Armor/Body":
		return skin.GetArmorBody
	case "Armour/Body":
		return skin.GetArmorBody
	default:
		return skin.GetHelm
	}
}

// Binds the route and makes a handler function for the requested resource.
func (router *Router) Serve(resource string) {
	fn := func(w http.ResponseWriter, r *http.Request) {
		vars := mux.Vars(r)
		size := router.GetSize(vars["size"])
		skin := fetchSkin(vars["username"])

		if r.Header.Get("If-None-Match") == skin.Skin.Hash {
			w.WriteHeader(http.StatusNotModified)
			return
		}

		err := router.ResolveMethod(skin, resource)(int(size))
		if err != nil {
			w.WriteHeader(500)
			fmt.Fprintf(w, "500 internal server error")
			return
		}

		w.Header().Add("Content-Type", "image/png")
		w.Header().Add("Cache-Control", fmt.Sprintf("public, max-age=%d", TimeoutActualSkin))
		w.Header().Add("ETag", skin.Hash)
		skin.WritePNG(w)
	}

	router.Mux.HandleFunc("/"+strings.ToLower(resource)+"/{username:"+minecraft.ValidUsernameRegex+"}{extension:(.png)?}", fn)
	router.Mux.HandleFunc("/"+strings.ToLower(resource)+"/{username:"+minecraft.ValidUsernameRegex+"}/{size:[0-9]+}{extension:(.png)?}", fn)
}

// Binds routes to the ServerMux.
func (router *Router) Bind() {

	router.Mux.NotFoundHandler = NotFoundHandler{}

	router.Serve("Avatar")
	router.Serve("Helm")
	router.Serve("Cube")
	router.Serve("Bust")
	router.Serve("Body")
	router.Serve("Armor/Bust")
	router.Serve("Armour/Bust")
	router.Serve("Armor/Body")
	router.Serve("Armour/Body")

	router.Mux.HandleFunc("/download/{username:"+minecraft.ValidUsernameRegex+"}{extension:(.png)?}", router.DownloadPage)
	router.Mux.HandleFunc("/skin/{username:"+minecraft.ValidUsernameRegex+"}{extension:(.png)?}", router.SkinPage)

	router.Mux.HandleFunc("/version", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "%s", MinotarVersion)
	})

	router.Mux.HandleFunc("/stats", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		w.Write(stats.ToJSON())
	})

	router.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		http.Redirect(w, r, "https://minotar.net/", 302)
	})
}

func fetchSkin(username string) *mcSkin {
	if cache.has(strings.ToLower(username)) {
		stats.HitCache()
		return &mcSkin{Processed: nil, Skin: cache.pull(strings.ToLower(username))}
	}

	skin, err := minecraft.FetchSkinFromMojang(username)
	if err != nil {
		log.Error("Failed Skin Mojang: " + username + " (" + err.Error() + ")")
		// Let's fallback to S3 and try and serve at least an old skin...
		skin, err = minecraft.FetchSkinFromS3(username)
		if err != nil {
			log.Error("Failed Skin S3: " + username + " (" + err.Error() + ")")
			// Well, looks like they don't exist after all.
			skin, _ = minecraft.FetchSkinForChar()
		}
	}

	stats.MissCache()
	cache.add(strings.ToLower(username), skin)

	return &mcSkin{Processed: nil, Skin: skin}
}
<|endoftext|>


<commit_before>package cluster

import (
	"strings"

	"github.com/docker/docker/pkg/stringid"
	"github.com/docker/engine-api/types"
)

// Network is exported
type Network struct {
	types.NetworkResource

	Engine *Engine
}

func (network *Network) isPreDefined() bool {
	return (network.Name == "none" || network.Name == "host" || network.Name == "bridge")
}

// Networks represents an array of networks
type Networks []*Network

// Uniq returns all uniq networks
func (networks Networks) Uniq() Networks {
	tmp := make(map[string]*Network)
	for _, network := range networks {
		if _, ok := tmp[network.ID]; ok {
			for id, endpoint := range network.Containers {
				tmp[network.ID].Containers[id] = endpoint
			}
		} else {
			tmp[network.ID] = network
		}
	}
	uniq := Networks{}
	for _, network := range tmp {
		uniq = append(uniq, network)
	}
	return uniq
}

// Filter returns networks filtered by names or ids
func (networks Networks) Filter(names []string, ids []string, types []string) Networks {
	typeFilter := func(network *Network) bool {
		if len(types) > 0 {
			for _, typ := range types {
				if typ == "custom" && !network.isPreDefined() {
					return true
				}
				if typ == "builtin" && network.isPreDefined() {
					return true
				}
			}
		} else {
			return true
		}
		return false
	}

	out := Networks{}
	if len(names) == 0 && len(ids) == 0 {
		for _, network := range networks.Uniq() {
			if typeFilter(network) {
				out = append(out, network)
			}
		}
	} else {
		for _, idOrName := range append(names, ids...) {
			if network := networks.Get(idOrName); network != nil {
				if typeFilter(network) {
					out = append(out, network)
				}
			}
		}
	}

	return out
}

// RemoveDuplicateEndpoints returns a copy of input network
// where duplicate container endpoints in the network are removed.
// See https://github.com/docker/swarm/issues/1969
// This function should be disabled when the bug is fixed in Docker network
func (network *Network) RemoveDuplicateEndpoints() *Network {
	// build a map from endpointID -> endpointIndex
	endpointMap := make(map[string]string)
	// traverse the endpoints to find the correct endpointIndex for each endpointID
	for endpointIndex, endpointResource := range network.NetworkResource.Containers {
		endpointID := endpointResource.EndpointID
		// if this endpointID doesn't exist yet, add it
		// if this endpointID exists, but endpointIndex is not a duplicate, use
		// this endpointIndex
		if _, ok := endpointMap[endpointID]; !ok || !strings.Contains(endpointIndex, endpointID) {
			endpointMap[endpointID] = endpointIndex
		}
	}
	// Make a copy of the network
	netCopy := *network
	// clean up existing endpoints
	netCopy.Containers = make(map[string]types.EndpointResource)
	// add the endpoint index from endpointMap
	for _, index := range endpointMap {
		netCopy.Containers[index] = network.Containers[index]
	}
	return &netCopy
}

// Get returns a network using its ID or Name
func (networks Networks) Get(IDOrName string) *Network {
	// Abort immediately if the name is empty.
	if len(IDOrName) == 0 {
		return nil
	}

	// Match exact or short Network ID.
	for _, network := range networks {
		if network.ID == IDOrName || stringid.TruncateID(network.ID) == IDOrName {
			return network
		}
	}

	candidates := Networks{}

	// Match name or engine/name.
	for _, network := range networks {
		if network.Name == IDOrName || network.Engine.ID+"/"+network.Name == IDOrName || network.Engine.Name+"/"+network.Name == IDOrName {
			candidates = append(candidates, network)
		}
	}

	// Return if we found a unique match.
	if size := len(candidates.Uniq()); size == 1 {
		return candidates[0]
	} else if size > 1 {
		return nil
	}

	// Match /name and return as soon as we find one.
	for _, network := range networks {
		if network.Name == "/"+IDOrName {
			return network
		}
	}

	// Match Network ID prefix.
	for _, network := range networks {
		if strings.HasPrefix(network.ID, IDOrName) {
			candidates = append(candidates, network)
		}
	}

	if len(candidates.Uniq()) == 1 {
		return candidates[0]
	}

	return nil
}
<commit_msg>Fix network uniq method concurrent map writes problem<commit_after>package cluster

import (
	"strings"

	"github.com/docker/docker/pkg/stringid"
	"github.com/docker/engine-api/types"
)

// Network is exported
type Network struct {
	types.NetworkResource

	Engine *Engine
}

func (network *Network) isPreDefined() bool {
	return (network.Name == "none" || network.Name == "host" || network.Name == "bridge")
}

// Networks represents an array of networks
type Networks []*Network

// Uniq returns all uniq networks
func (networks Networks) Uniq() Networks {
	tmp := make(map[string]*Network)
	for _, network := range networks {
		if _, ok := tmp[network.ID]; ok {
			for id, endpoint := range network.Containers {
				tmp[network.ID].Containers[id] = endpoint
			}
		} else {
			netCopy := *network
			netCopy.Containers = make(map[string]types.EndpointResource)
			for key, value := range network.Containers {
				netCopy.Containers[key] = value
			}
			tmp[network.ID] = &netCopy
		}
	}
	uniq := Networks{}
	for _, network := range tmp {
		uniq = append(uniq, network)
	}
	return uniq
}

// Filter returns networks filtered by names or ids
func (networks Networks) Filter(names []string, ids []string, types []string) Networks {
	typeFilter := func(network *Network) bool {
		if len(types) > 0 {
			for _, typ := range types {
				if typ == "custom" && !network.isPreDefined() {
					return true
				}
				if typ == "builtin" && network.isPreDefined() {
					return true
				}
			}
		} else {
			return true
		}
		return false
	}

	out := Networks{}
	if len(names) == 0 && len(ids) == 0 {
		for _, network := range networks.Uniq() {
			if typeFilter(network) {
				out = append(out, network)
			}
		}
	} else {
		for _, idOrName := range append(names, ids...) {
			if network := networks.Get(idOrName); network != nil {
				if typeFilter(network) {
					out = append(out, network)
				}
			}
		}
	}

	return out
}

// RemoveDuplicateEndpoints returns a copy of input network
// where duplicate container endpoints in the network are removed.
// See https://github.com/docker/swarm/issues/1969
// This function should be disabled when the bug is fixed in Docker network
func (network *Network) RemoveDuplicateEndpoints() *Network {
	// build a map from endpointID -> endpointIndex
	endpointMap := make(map[string]string)
	// traverse the endpoints to find the correct endpointIndex for each endpointID
	for endpointIndex, endpointResource := range network.NetworkResource.Containers {
		endpointID := endpointResource.EndpointID
		// if this endpointID doesn't exist yet, add it
		// if this endpointID exists, but endpointIndex is not a duplicate, use
		// this endpointIndex
		if _, ok := endpointMap[endpointID]; !ok || !strings.Contains(endpointIndex, endpointID) {
			endpointMap[endpointID] = endpointIndex
		}
	}
	// Make a copy of the network
	netCopy := *network
	// clean up existing endpoints
	netCopy.Containers = make(map[string]types.EndpointResource)
	// add the endpoint index from endpointMap
	for _, index := range endpointMap {
		netCopy.Containers[index] = network.Containers[index]
	}
	return &netCopy
}

// Get returns a network using its ID or Name
func (networks Networks) Get(IDOrName string) *Network {
	// Abort immediately if the name is empty.
	if len(IDOrName) == 0 {
		return nil
	}

	// Match exact or short Network ID.
	for _, network := range networks {
		if network.ID == IDOrName || stringid.TruncateID(network.ID) == IDOrName {
			return network
		}
	}

	candidates := Networks{}

	// Match name or engine/name.
	for _, network := range networks {
		if network.Name == IDOrName || network.Engine.ID+"/"+network.Name == IDOrName || network.Engine.Name+"/"+network.Name == IDOrName {
			candidates = append(candidates, network)
		}
	}

	// Return if we found a unique match.
	if size := len(candidates.Uniq()); size == 1 {
		return candidates[0]
	} else if size > 1 {
		return nil
	}

	// Match /name and return as soon as we find one.
	for _, network := range networks {
		if network.Name == "/"+IDOrName {
			return network
		}
	}

	// Match Network ID prefix.
	for _, network := range networks {
		if strings.HasPrefix(network.ID, IDOrName) {
			candidates = append(candidates, network)
		}
	}

	if len(candidates.Uniq()) == 1 {
		return candidates[0]
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"math/rand"
	"strings"
	"time"

	derpiSearch "github.com/PonyvilleFM/aura/cmd/aerial/derpi"
	"github.com/PonyvilleFM/aura/pvfm"
	"github.com/PonyvilleFM/aura/pvfm/pvl"
	pvfmschedule "github.com/PonyvilleFM/aura/pvfm/schedule"
	"github.com/PonyvilleFM/aura/pvfm/station"
	"github.com/bwmarrin/discordgo"
	"github.com/tebeka/strftime"
)

// randomRange gives a random whole integer between the given integers [min, max)
func randomRange(min, max int) int {
	rand.Seed(time.Now().Unix())
	return rand.Intn(max-min) + min
}

func pesterLink(s *discordgo.Session, m *discordgo.MessageCreate) {
	if musicLinkRegex.Match([]byte(m.Content)) {
		i, err := pvfm.GetStats()
		if err != nil {
			log.Println(err)
			return
		}

		if i.IsDJLive() && m.ChannelID == youtubeSpamRoomID {
			s.ChannelMessageSend(m.ChannelID, "Please be mindful sharing links to music when a DJ is performing. Thanks!")
		}
	}
}

func np(s *discordgo.Session, m *discordgo.Message, parv []string) error {
	i, err := pvfm.GetStats()
	if err != nil {
		log.Printf("Can't get info: %v, failing over to plan b", err)
		return doStationRequest(s, m, parv)
	}

	result := []string{}

	if i.Main.Nowplaying == "Fetching info..." {
		log.Println("Main information was bad, fetching from station directly...")

		err := doStationRequest(s, m, parv)
		if err != nil {
			return err
		}

		return nil
	} else {
		result = append(result, "📻 **Now Playing on PVFM**\n")

		result = append(result, fmt.Sprintf(
			"Main 🎵 %s\n",
			i.Main.Nowplaying,
		))
		result = append(result, fmt.Sprintf(
			"Chill 🎵 %s\n",
			i.Secondary.Nowplaying,
		))
		result = append(result, fmt.Sprintf(
			"Free! 🎵 %s",
			i.MusicOnly.Nowplaying,
		))
	}

	s.ChannelMessageSend(m.ChannelID, strings.Join(result, "\n"))
	return nil
}

func dj(s *discordgo.Session, m *discordgo.Message, parv []string) error {
	cal, err := pvl.Get()
	if err != nil {
		return err
	}

	now := cal.Result[0]
	result := []string{}

	localTime := time.Now()
	thentime := time.Unix(now.StartTime, 0)
	if thentime.Unix() < localTime.Unix() {
		result = append(result, fmt.Sprintf("Currently live: %s\n", now.Title))
		now = cal.Result[1]
	}

	nowTime := time.Unix(now.StartTime, 0).UTC()
	zone, _ := nowTime.Zone()
	fmttime, _ := strftime.Format("%Y-%m-%d %H:%M:%S", nowTime)

	result = append(result, fmt.Sprintf("Next event: %s at %s \x02%s\x02",
		now.Title,
		fmttime,
		zone,
	))

	s.ChannelMessageSend(m.ChannelID, strings.Join(result, "\n"))
	return nil
}

func stats(s *discordgo.Session, m *discordgo.Message, parv []string) error {
	i, err := pvfm.GetStats()
	if err != nil {
		log.Printf("Error getting the station info: %v, falling back to plan b", err)
		return doStatsFromStation(s, m, parv)
	}

	st, err := station.GetStats()
	if err != nil {
		return err
	}

	var l int
	var peak int

	for _, source := range st.Icestats.Source {
		l = l + source.Listeners
		peak = peak + source.ListenerPeak
	}

	result := []string{
		fmt.Sprintf(
			"Current listeners across all streams: %d with a maximum of %d!",
			i.Listeners.Listeners, peak,
		),
		fmt.Sprintf(
			"Detailed: Main: %d listeners, Two: %d listeners, Free: %d listeners",
			i.Main.Listeners, i.Secondary.Listeners, i.MusicOnly.Listeners,
		),
	}

	s.ChannelMessageSend(m.ChannelID, strings.Join(result, "\n"))

	return nil
}

func schedule(s *discordgo.Session, m *discordgo.Message, parv []string) error {
	result := []string{}
	schEntries, err := pvfmschedule.Get()
	if err != nil {
		return err
	}

	for _, entry := range schEntries {
		result = append(result, entry.String())
	}

	s.ChannelMessageSend(m.ChannelID, strings.Join(result, "\n"))
	return nil
}

func doStationRequest(s *discordgo.Session, m *discordgo.Message, parv []string) error {
	stats, err := station.GetStats()
	if err != nil {
		return err
	}

	result := fmt.Sprintf(
		"Now playing: %s - %s on Ponyville FM!",
		stats.Icestats.Source[0].Title,
		stats.Icestats.Source[0].Artist,
	)

	s.ChannelMessageSend(m.ChannelID, result)
	return nil
}

func doStatsFromStation(s *discordgo.Session, m *discordgo.Message, parv []string) error {
	st, err := station.GetStats()
	if err != nil {
		return err
	}

	var l int
	var peak int

	for _, source := range st.Icestats.Source {
		l = l + source.Listeners
		peak = peak + source.ListenerPeak
	}

	result := []string{
		fmt.Sprintf("Current listeners: %d with a maximum of %d!", l, peak),
	}

	s.ChannelMessageSend(m.ChannelID, strings.Join(result, "\n"))
	return nil
}

func curTime(s *discordgo.Session, m *discordgo.Message, parv []string) error {
	s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("The time currently is %s", time.Now().UTC().Format("2006-01-02 15:04:05 UTC")))

	return nil
}

func streams(s *discordgo.Session, m *discordgo.Message, parv []string) error {
	currentMeta, metaErr := station.GetStats()
	if metaErr != nil {
		s.ChannelMessageSend(m.ChannelID, "Error receiving pvfm metadata")
		return metaErr
	}

	outputString := "**PVFM Servers:**\n"

	for _, element := range currentMeta.Icestats.Source {
		outputString += ":musical_note: " + element.ServerDescription + ":\n<" + strings.Replace(element.Listenurl, "aerial", "dj.bronyradio.com", -1) + ">\n"
	}

	outputString += "\n:cd: DJ Recordings:\n<http://darkling.darkwizards.com/wang/BronyRadio/?M=D>"

	s.ChannelMessageSend(m.ChannelID, outputString)

	return nil
}

func derpi(s *discordgo.Session, m *discordgo.Message, parv []string) error {
	searchResults, err := derpiSearch.SearchDerpi(m.Content[6:len(m.Content)])
	if err != nil {
		return err
	}
	s.ChannelMessageSend(m.ChannelID, searchResults.Search[randomRange(0, len(searchResults.Search))].Image)
	return nil
}
<commit_msg>Shifted index of command slice to fix derpi<commit_after>package main

import (
	"fmt"
	"log"
	"math/rand"
	"strings"
	"time"

	derpiSearch "github.com/PonyvilleFM/aura/cmd/aerial/derpi"
	"github.com/PonyvilleFM/aura/pvfm"
	"github.com/PonyvilleFM/aura/pvfm/pvl"
	pvfmschedule "github.com/PonyvilleFM/aura/pvfm/schedule"
	"github.com/PonyvilleFM/aura/pvfm/station"
	"github.com/bwmarrin/discordgo"
	"github.com/tebeka/strftime"
)

// randomRange gives a random whole integer between the given integers [min, max)
func randomRange(min, max int) int {
	rand.Seed(time.Now().Unix())
	return rand.Intn(max-min) + min
}

func pesterLink(s *discordgo.Session, m *discordgo.MessageCreate) {
	if musicLinkRegex.Match([]byte(m.Content)) {
		i, err := pvfm.GetStats()
		if err != nil {
			log.Println(err)
			return
		}

		if i.IsDJLive() && m.ChannelID == youtubeSpamRoomID {
			s.ChannelMessageSend(m.ChannelID, "Please be mindful sharing links to music when a DJ is performing. Thanks!")
		}
	}
}

func np(s *discordgo.Session, m *discordgo.Message, parv []string) error {
	i, err := pvfm.GetStats()
	if err != nil {
		log.Printf("Can't get info: %v, failing over to plan b", err)
		return doStationRequest(s, m, parv)
	}

	result := []string{}

	if i.Main.Nowplaying == "Fetching info..." {
		log.Println("Main information was bad, fetching from station directly...")

		err := doStationRequest(s, m, parv)
		if err != nil {
			return err
		}

		return nil
	} else {
		result = append(result, "📻 **Now Playing on PVFM**\n")

		result = append(result, fmt.Sprintf(
			"Main 🎵 %s\n",
			i.Main.Nowplaying,
		))
		result = append(result, fmt.Sprintf(
			"Chill 🎵 %s\n",
			i.Secondary.Nowplaying,
		))
		result = append(result, fmt.Sprintf(
			"Free! 🎵 %s",
			i.MusicOnly.Nowplaying,
		))
	}

	s.ChannelMessageSend(m.ChannelID, strings.Join(result, "\n"))
	return nil
}

func dj(s *discordgo.Session, m *discordgo.Message, parv []string) error {
	cal, err := pvl.Get()
	if err != nil {
		return err
	}

	now := cal.Result[0]
	result := []string{}

	localTime := time.Now()
	thentime := time.Unix(now.StartTime, 0)
	if thentime.Unix() < localTime.Unix() {
		result = append(result, fmt.Sprintf("Currently live: %s\n", now.Title))
		now = cal.Result[1]
	}

	nowTime := time.Unix(now.StartTime, 0).UTC()
	zone, _ := nowTime.Zone()
	fmttime, _ := strftime.Format("%Y-%m-%d %H:%M:%S", nowTime)

	result = append(result, fmt.Sprintf("Next event: %s at %s \x02%s\x02",
		now.Title,
		fmttime,
		zone,
	))

	s.ChannelMessageSend(m.ChannelID, strings.Join(result, "\n"))
	return nil
}

func stats(s *discordgo.Session, m *discordgo.Message, parv []string) error {
	i, err := pvfm.GetStats()
	if err != nil {
		log.Printf("Error getting the station info: %v, falling back to plan b", err)
		return doStatsFromStation(s, m, parv)
	}

	st, err := station.GetStats()
	if err != nil {
		return err
	}

	var l int
	var peak int

	for _, source := range st.Icestats.Source {
		l = l + source.Listeners
		peak = peak + source.ListenerPeak
	}

	result := []string{
		fmt.Sprintf(
			"Current listeners across all streams: %d with a maximum of %d!",
			i.Listeners.Listeners, peak,
		),
		fmt.Sprintf(
			"Detailed: Main: %d listeners, Two: %d listeners, Free: %d listeners",
			i.Main.Listeners, i.Secondary.Listeners, i.MusicOnly.Listeners,
		),
	}

	s.ChannelMessageSend(m.ChannelID, strings.Join(result, "\n"))

	return nil
}

func schedule(s *discordgo.Session, m *discordgo.Message, parv []string) error {
	result := []string{}
	schEntries, err := pvfmschedule.Get()
	if err != nil {
		return err
	}

	for _, entry := range schEntries {
		result = append(result, entry.String())
	}

	s.ChannelMessageSend(m.ChannelID, strings.Join(result, "\n"))
	return nil
}

func doStationRequest(s *discordgo.Session, m *discordgo.Message, parv []string) error {
	stats, err := station.GetStats()
	if err != nil {
		return err
	}

	result := fmt.Sprintf(
		"Now playing: %s - %s on Ponyville FM!",
		stats.Icestats.Source[0].Title,
		stats.Icestats.Source[0].Artist,
	)

	s.ChannelMessageSend(m.ChannelID, result)
	return nil
}

func doStatsFromStation(s *discordgo.Session, m *discordgo.Message, parv []string) error {
	st, err := station.GetStats()
	if err != nil {
		return err
	}

	var l int
	var peak int

	for _, source := range st.Icestats.Source {
		l = l + source.Listeners
		peak = peak + source.ListenerPeak
	}

	result := []string{
		fmt.Sprintf("Current listeners: %d with a maximum of %d!", l, peak),
	}

	s.ChannelMessageSend(m.ChannelID, strings.Join(result, "\n"))
	return nil
}

func curTime(s *discordgo.Session, m *discordgo.Message, parv []string) error {
	s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("The time currently is %s", time.Now().UTC().Format("2006-01-02 15:04:05 UTC")))

	return nil
}

func streams(s *discordgo.Session, m *discordgo.Message, parv []string) error {
	currentMeta, metaErr := station.GetStats()
	if metaErr != nil {
		s.ChannelMessageSend(m.ChannelID, "Error receiving pvfm metadata")
		return metaErr
	}

	outputString := "**PVFM Servers:**\n"

	for _, element := range currentMeta.Icestats.Source {
		outputString += ":musical_note: " + element.ServerDescription + ":\n<" + strings.Replace(element.Listenurl, "aerial", "dj.bronyradio.com", -1) + ">\n"
	}

	outputString += "\n:cd: DJ Recordings:\n<http://darkling.darkwizards.com/wang/BronyRadio/?M=D>"

	s.ChannelMessageSend(m.ChannelID, outputString)

	return nil
}

func derpi(s *discordgo.Session, m *discordgo.Message, parv []string) error {
	searchResults, err := derpiSearch.SearchDerpi(m.Content[7:len(m.Content)])
	if err != nil {
		return err
	}
	s.ChannelMessageSend(m.ChannelID, searchResults.Search[randomRange(0, len(searchResults.Search))].Image)
	return nil
}
<|endoftext|>


<commit_before>// Copyright 2018 Google LLC
//
// 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
//
//     https://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.

// TODO(twifkak): Improve error messages everywhere.
// TODO(twifkak): Test this.
// TODO(twifkak): Document code.
package main

import (
	"bytes"
	"encoding/asn1"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"path"
	"time"

	"github.com/WICG/webpackage/go/signedexchange"
	"github.com/julienschmidt/httprouter"
	"github.com/pkg/errors"

	amppkg "github.com/ampproject/amppackager/packager"
	"github.com/ampproject/amppackager/packager/rtv"
)

var flagConfig = flag.String("config", "amppkg.toml", "Path to the config toml file.")
var flagDevelopment = flag.Bool("development", false, "True if this is a development server.")

// Prints errors returned by pkg/errors with stack traces.
func die(err interface{}) { log.Fatalf("%+v", err) }

type logIntercept struct {
	handler http.Handler
}

func (this logIntercept) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
	// TODO(twifkak): Adopt whatever the standard format is nowadays.
	log.Println("Serving", req.URL, "to", req.RemoteAddr)
	this.handler.ServeHTTP(resp, req)
	// TODO(twifkak): Get status code from resp. This requires making a ResponseWriter wrapper.
	// TODO(twifkak): Separate the typical weblog from the detailed error log.
}

// Exposes an HTTP server. Don't run this on the open internet, for at least two reasons:
//  - It exposes an API that allows people to sign any URL as any other URL.
//  - It is in cleartext.
func main() {
	flag.Parse()
	config, err := amppkg.ReadConfig(*flagConfig)
	if err != nil {
		die(errors.Wrap(err, "reading config"))
	}

	// TODO(twifkak): Document what cert/key storage formats this accepts.
	certPem, err := ioutil.ReadFile(config.CertFile)
	if err != nil {
		die(errors.Wrapf(err, "reading %s", config.CertFile))
	}
	keyPem, err := ioutil.ReadFile(config.KeyFile)
	if err != nil {
		die(errors.Wrapf(err, "reading %s", config.KeyFile))
	}

	certs, err := signedexchange.ParseCertificates(certPem)
	if err != nil {
		die(errors.Wrapf(err, "parsing %s", config.CertFile))
	}
	if certs == nil || len(certs) == 0 {
		die(fmt.Sprintf("no cert found in %s", config.CertFile))
	}
	if !*flagDevelopment && !amppkg.CanSignHttpExchanges(certs[0]) {
		die("cert is missing CanSignHttpExchanges extension")
	}
	// TODO(twifkak): Verify that certs[0] covers all the signing domains in the config.

	key, err := amppkg.ParsePrivateKey(keyPem)
	if err != nil {
		die(errors.Wrapf(err, "parsing %s", config.KeyFile))
	}
	// TODO(twifkak): Verify that key matches certs[0].

	validityMap, err := amppkg.NewValidityMap()
	if err != nil {
		die(errors.Wrap(err, "building validity map"))
	}

	certCache := amppkg.NewCertCache(certs, config.OCSPCache)
	if err = certCache.Init(nil); err != nil {
		die(errors.Wrap(err, "building cert cache"))
	}
	rtvCache, err := rtv.New()
	if err != nil {
		die(errors.Wrap(err, "initializing rtv cache"))
	}
	err = rtvCache.StartCron("")
	if err != nil {
		die(errors.Wrap(err, "starting rtv cron"))
	}
	defer rtvCache.StopCron()

	var overrideBaseURL *url.URL
	if *flagDevelopment {
		overrideBaseURL, err = url.Parse(fmt.Sprintf("https://localhost:%d/", config.Port))
		if err != nil {
			die(errors.Wrap(err, "parsing development base URL"))
		}
	}

	packager, err := amppkg.NewPackager(certs[0], key, config.URLSet, rtvCache, certCache.IsHealthy, overrideBaseURL)
	if err != nil {
		die(errors.Wrap(err, "building packager"))
	}

	// TODO(twifkak): Make log output configurable.
	mux := httprouter.New()
	mux.RedirectTrailingSlash = false
	mux.RedirectFixedPath = false
	mux.GET(amppkg.ValidityMapPath, validityMap.ServeHTTP)
	mux.GET("/priv/doc", packager.ServeHTTP)
	mux.GET("/priv/doc/*signURL", packager.ServeHTTP)
	mux.GET(path.Join(amppkg.CertURLPrefix, ":certName"), certCache.ServeHTTP)
	addr := ""
	if config.LocalOnly {
		addr = "localhost"
	}
	addr += fmt.Sprint(":", config.Port)
	server := http.Server{
		Addr: addr,
		// Don't use DefaultServeMux, per
		// https://blog.cloudflare.com/exposing-go-on-the-internet/.
		Handler:           logIntercept{mux},
		ReadTimeout:       10 * time.Second,
		ReadHeaderTimeout: 5 * time.Second,
		// If needing to stream the response, disable WriteTimeout and
		// use TimeoutHandler instead, per
		// https://blog.cloudflare.com/the-complete-guide-to-golang-net-http-timeouts/.
		WriteTimeout: 60 * time.Second,
		// Needs Go 1.8.
		IdleTimeout: 120 * time.Second,
		// TODO(twifkak): Specify ErrorLog?
	}

	// TODO(twifkak): Add monitoring (e.g. per the above Cloudflare blog).

	log.Println("Serving on port", config.Port)

	// TCP keep-alive timeout on ListenAndServe is 3 minutes. To shorten,
	// follow the above Cloudflare blog.

	if *flagDevelopment {
		log.Println("WARNING: Running in development, using SXG key for TLS. This won't work in production.")
		log.Fatal(server.ListenAndServeTLS(config.CertFile, config.KeyFile))
	} else {
		log.Fatal(server.ListenAndServe())
	}
}
<commit_msg>Delete unused imports in cmd/amppkg. (#117)<commit_after>// Copyright 2018 Google LLC
//
// 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
//
//     https://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.

// TODO(twifkak): Improve error messages everywhere.
// TODO(twifkak): Test this.
// TODO(twifkak): Document code.
package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"path"
	"time"

	"github.com/WICG/webpackage/go/signedexchange"
	"github.com/julienschmidt/httprouter"
	"github.com/pkg/errors"

	amppkg "github.com/ampproject/amppackager/packager"
	"github.com/ampproject/amppackager/packager/rtv"
)

var flagConfig = flag.String("config", "amppkg.toml", "Path to the config toml file.")
var flagDevelopment = flag.Bool("development", false, "True if this is a development server.")

// Prints errors returned by pkg/errors with stack traces.
func die(err interface{}) { log.Fatalf("%+v", err) }

type logIntercept struct {
	handler http.Handler
}

func (this logIntercept) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
	// TODO(twifkak): Adopt whatever the standard format is nowadays.
	log.Println("Serving", req.URL, "to", req.RemoteAddr)
	this.handler.ServeHTTP(resp, req)
	// TODO(twifkak): Get status code from resp. This requires making a ResponseWriter wrapper.
	// TODO(twifkak): Separate the typical weblog from the detailed error log.
}

// Exposes an HTTP server. Don't run this on the open internet, for at least two reasons:
//  - It exposes an API that allows people to sign any URL as any other URL.
//  - It is in cleartext.
func main() {
	flag.Parse()
	config, err := amppkg.ReadConfig(*flagConfig)
	if err != nil {
		die(errors.Wrap(err, "reading config"))
	}

	// TODO(twifkak): Document what cert/key storage formats this accepts.
	certPem, err := ioutil.ReadFile(config.CertFile)
	if err != nil {
		die(errors.Wrapf(err, "reading %s", config.CertFile))
	}
	keyPem, err := ioutil.ReadFile(config.KeyFile)
	if err != nil {
		die(errors.Wrapf(err, "reading %s", config.KeyFile))
	}

	certs, err := signedexchange.ParseCertificates(certPem)
	if err != nil {
		die(errors.Wrapf(err, "parsing %s", config.CertFile))
	}
	if certs == nil || len(certs) == 0 {
		die(fmt.Sprintf("no cert found in %s", config.CertFile))
	}
	if !*flagDevelopment && !amppkg.CanSignHttpExchanges(certs[0]) {
		die("cert is missing CanSignHttpExchanges extension")
	}
	// TODO(twifkak): Verify that certs[0] covers all the signing domains in the config.

	key, err := amppkg.ParsePrivateKey(keyPem)
	if err != nil {
		die(errors.Wrapf(err, "parsing %s", config.KeyFile))
	}
	// TODO(twifkak): Verify that key matches certs[0].

	validityMap, err := amppkg.NewValidityMap()
	if err != nil {
		die(errors.Wrap(err, "building validity map"))
	}

	certCache := amppkg.NewCertCache(certs, config.OCSPCache)
	if err = certCache.Init(nil); err != nil {
		die(errors.Wrap(err, "building cert cache"))
	}
	rtvCache, err := rtv.New()
	if err != nil {
		die(errors.Wrap(err, "initializing rtv cache"))
	}
	err = rtvCache.StartCron("")
	if err != nil {
		die(errors.Wrap(err, "starting rtv cron"))
	}
	defer rtvCache.StopCron()

	var overrideBaseURL *url.URL
	if *flagDevelopment {
		overrideBaseURL, err = url.Parse(fmt.Sprintf("https://localhost:%d/", config.Port))
		if err != nil {
			die(errors.Wrap(err, "parsing development base URL"))
		}
	}

	packager, err := amppkg.NewPackager(certs[0], key, config.URLSet, rtvCache, certCache.IsHealthy, overrideBaseURL)
	if err != nil {
		die(errors.Wrap(err, "building packager"))
	}

	// TODO(twifkak): Make log output configurable.
	mux := httprouter.New()
	mux.RedirectTrailingSlash = false
	mux.RedirectFixedPath = false
	mux.GET(amppkg.ValidityMapPath, validityMap.ServeHTTP)
	mux.GET("/priv/doc", packager.ServeHTTP)
	mux.GET("/priv/doc/*signURL", packager.ServeHTTP)
	mux.GET(path.Join(amppkg.CertURLPrefix, ":certName"), certCache.ServeHTTP)
	addr := ""
	if config.LocalOnly {
		addr = "localhost"
	}
	addr += fmt.Sprint(":", config.Port)
	server := http.Server{
		Addr: addr,
		// Don't use DefaultServeMux, per
		// https://blog.cloudflare.com/exposing-go-on-the-internet/.
		Handler:           logIntercept{mux},
		ReadTimeout:       10 * time.Second,
		ReadHeaderTimeout: 5 * time.Second,
		// If needing to stream the response, disable WriteTimeout and
		// use TimeoutHandler instead, per
		// https://blog.cloudflare.com/the-complete-guide-to-golang-net-http-timeouts/.
		WriteTimeout: 60 * time.Second,
		// Needs Go 1.8.
		IdleTimeout: 120 * time.Second,
		// TODO(twifkak): Specify ErrorLog?
	}

	// TODO(twifkak): Add monitoring (e.g. per the above Cloudflare blog).

	log.Println("Serving on port", config.Port)

	// TCP keep-alive timeout on ListenAndServe is 3 minutes. To shorten,
	// follow the above Cloudflare blog.

	if *flagDevelopment {
		log.Println("WARNING: Running in development, using SXG key for TLS. This won't work in production.")
		log.Fatal(server.ListenAndServeTLS(config.CertFile, config.KeyFile))
	} else {
		log.Fatal(server.ListenAndServe())
	}
}
<|endoftext|>


<commit_before>package control

import (
	"os"

	"github.com/codegangsta/cli"
	"github.com/rancherio/os/config"
)

func Main() {
	app := cli.NewApp()

	app.Name = os.Args[0]
	app.Usage = "Control and configure RancherOS"
	app.Version = config.VERSION
	app.Author = "Rancher Labs, Inc."
	app.Email = "darren@rancher.com"
	app.EnableBashCompletion = true

	app.Commands = []cli.Command{
		{
			Name:        "config",
			ShortName:   "c",
			Usage:       "configure settings",
			Subcommands: configSubcommands(),
		},
		{
			Name:        "addon",
			ShortName:   "a",
			Usage:       "addon settings",
			Subcommands: addonSubCommands(),
		},
		//{
		//	Name:      "reload",
		//	ShortName: "a",
		//	Usage:     "reload configuration of a service and restart the container",
		//	Action:    reload,
		//},
		{
			Name:        "os",
			Usage:       "operating system upgrade/downgrade",
			Subcommands: osSubcommands(),
		},
		{
			Name:        "tlsconf",
			Usage:       "setup tls configuration",
			Subcommands: tlsConfCommands(),
		},
	}

	app.Run(os.Args)
}
<commit_msg>Refactor TLS command<commit_after>package control

import (
	"os"

	"github.com/codegangsta/cli"
	"github.com/rancherio/os/config"
)

func Main() {
	app := cli.NewApp()

	app.Name = os.Args[0]
	app.Usage = "Control and configure RancherOS"
	app.Version = config.VERSION
	app.Author = "Rancher Labs, Inc."
	app.Email = "darren@rancher.com"
	app.EnableBashCompletion = true

	app.Commands = []cli.Command{
		{
			Name:        "config",
			ShortName:   "c",
			Usage:       "configure settings",
			Subcommands: configSubcommands(),
		},
		{
			Name:        "addon",
			ShortName:   "a",
			Usage:       "addon settings",
			Subcommands: addonSubCommands(),
		},
		//{
		//	Name:      "reload",
		//	ShortName: "a",
		//	Usage:     "reload configuration of a service and restart the container",
		//	Action:    reload,
		//},
		{
			Name:        "os",
			Usage:       "operating system upgrade/downgrade",
			Subcommands: osSubcommands(),
		},
		{
			Name:        "tls",
			Usage:       "setup tls configuration",
			HideHelp:    true,
			Subcommands: tlsConfCommands(),
		},
	}

	app.Run(os.Args)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"io"
	"os"
	"os/exec"
	"strings"
	"time"

	"golang.org/x/mobile/event/lifecycle"
	"sigint.ca/graphics/editor/address"
)

func findInEditor(s string) {
	if s == "" {
		return
	}
	switch s[1] {
	case ':':
		mainWidget.ed.JumpTo(s[1:])
	default:
		mainWidget.ed.FindNext(s)
	}
}

func executeCmd(cmd string) {
	cmd = strings.TrimSpace(cmd)
	if cmd == "" {
		return
	}

	switch cmd {
	case "Put":
		if !dir {
			save()
		}
	case "Undo":
		mainWidget.ed.SendUndo()
	case "Redo":
		mainWidget.ed.SendRedo()
	case "Exit":
		if confirmUnsaved() {
			win.Send(lifecycle.Event{To: lifecycle.StageDead})
		} else {
			return
		}
	case "Get":
		if confirmUnsaved() {
			load(savedPath)
		} else {
			return
		}
	default:
		switch cmd[0] {
		case '|':
			pipe(cmd[1:])
		default:
			run(cmd)
		}
	}

	end := tagWidget.ed.LastAddress()
	tagWidget.ed.SetDot(address.Selection{From: end, To: end})
}

var confirmTime time.Time

func confirmUnsaved() bool {
	if _, ok := tagWidget.ed.FindNext("Put"); !ok {
		return true // already saved
	}

	confirmed := time.Since(confirmTime) < 3*time.Second
	confirmTime = time.Now()
	return confirmed
}

func pipe(cmd string) {
	ed := mainWidget.ed

	in := bytes.NewBufferString(ed.GetDotContents())
	out := new(bytes.Buffer)
	args := strings.Fields(cmd)
	c := exec.Command(args[0], args[1:]...)
	c.Stdin = in
	c.Stdout = out

	c.Run()

	ed.Replace(out.String())
}

func run(cmd string) {
	args := strings.Fields(cmd)
	execCmd := exec.Command(args[0], args[1:]...)
	editorCmd := exec.Command(os.Args[0], "/dev/stdin")

	r, w := io.Pipe()

	execCmd.Stdout = w
	execCmd.Stderr = w
	editorCmd.Stdin = r

	if err := execCmd.Start(); err != nil {
		return
	}
	go func() { execCmd.Wait(); w.Close() }()
	go editorCmd.Run()
}
<commit_msg>cmd/edit: simplify run and fix for commands with no output<commit_after>package main

import (
	"bytes"
	"os"
	"os/exec"
	"strings"
	"time"

	"golang.org/x/mobile/event/lifecycle"
	"sigint.ca/graphics/editor/address"
)

func findInEditor(s string) {
	if s == "" {
		return
	}
	switch s[1] {
	case ':':
		mainWidget.ed.JumpTo(s[1:])
	default:
		mainWidget.ed.FindNext(s)
	}
}

func executeCmd(cmd string) {
	cmd = strings.TrimSpace(cmd)
	if cmd == "" {
		return
	}

	switch cmd {
	case "Put":
		if !dir {
			save()
		}
	case "Undo":
		mainWidget.ed.SendUndo()
	case "Redo":
		mainWidget.ed.SendRedo()
	case "Exit":
		if confirmUnsaved() {
			win.Send(lifecycle.Event{To: lifecycle.StageDead})
		} else {
			return
		}
	case "Get":
		if confirmUnsaved() {
			load(savedPath)
		} else {
			return
		}
	default:
		switch cmd[0] {
		case '|':
			pipe(cmd[1:])
		default:
			run(cmd)
		}
	}

	end := tagWidget.ed.LastAddress()
	tagWidget.ed.SetDot(address.Selection{From: end, To: end})
}

var confirmTime time.Time

func confirmUnsaved() bool {
	if _, ok := tagWidget.ed.FindNext("Put"); !ok {
		return true // already saved
	}

	confirmed := time.Since(confirmTime) < 3*time.Second
	confirmTime = time.Now()
	return confirmed
}

func pipe(cmd string) {
	ed := mainWidget.ed

	in := bytes.NewBufferString(ed.GetDotContents())
	out := new(bytes.Buffer)
	args := strings.Fields(cmd)
	c := exec.Command(args[0], args[1:]...)
	c.Stdin = in
	c.Stdout = out

	c.Run()

	ed.Replace(out.String())
}

// BUG: only works if the command exits.
func run(cmd string) {
	args := strings.Fields(cmd)
	go func() {
		out, err := exec.Command(args[0], args[1:]...).CombinedOutput()
		if err != nil || len(out) == 0 {
			return
		}
		editor := exec.Command(os.Args[0], "/dev/stdin")
		editor.Stdin = bytes.NewBuffer(out)
		editor.Run()
	}()
}
<|endoftext|>


<commit_before>// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package test

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

	"v.io/x/devtools/internal/collect"
	"v.io/x/devtools/internal/test"
	"v.io/x/devtools/internal/tool"
	"v.io/x/devtools/internal/util"
)

// vanadiumGoBinaries uploads Vanadium binaries to Google Storage.
func vanadiumGoBinaries(ctx *tool.Context, testName string, _ ...Opt) (_ *test.Result, e error) {
	// Initialize the test.
	cleanup, err := initTest(ctx, testName, nil)
	if err != nil {
		return nil, internalTestError{err, "Init"}
	}
	defer collect.Error(func() error { return cleanup() }, &e)

	// Fetch the latest stable Go snapshot.
	if err := ctx.Run().Command("v23", "update", "-manifest=snapshot/stable-go"); err != nil {
		return nil, internalTestError{err, "Update"}
	}

	// Build all v.io binaries.
	if err := ctx.Run().Command("v23", "go", "install", "v.io/..."); err != nil {
		return nil, internalTestError{err, "Install"}
	}

	// Compute the timestamp for the build snapshot.
	labelFile, err := util.ManifestFile("snapshot/stable-go")
	if err != nil {
		return nil, internalTestError{err, "ManifestFile"}
	}
	snapshotFile, err := filepath.EvalSymlinks(labelFile)
	if err != nil {
		return nil, internalTestError{err, "EvalSymlinks"}
	}
	timestamp := filepath.Base(snapshotFile)

	// Upload all v.io binaries to Google Storage.
	bucket := fmt.Sprintf("gs://vanadium-binaries/%s_%s/", runtime.GOOS, runtime.GOARCH)
	root, err := util.V23Root()
	if err != nil {
		return nil, internalTestError{err, "V23Root"}
	}
	binaries := filepath.Join(root, "release", "go", "bin", "*")
	if err := ctx.Run().Command("gsutil", "-m", "-q", "cp", binaries, bucket+timestamp); err != nil {
		return nil, internalTestError{err, "Upload"}
	}

	// Upload two files: 1) a file that identifies the directory
	// containing the latest set of binaries and 2) a file that
	// indicates that the upload of binaries succeeded.
	tmpDir, err := ctx.Run().TempDir("", "")
	if err != nil {
		return nil, internalTestError{err, "TempDir"}
	}
	defer collect.Error(func() error { return ctx.Run().RemoveAll(tmpDir) }, &e)
	doneFile := filepath.Join(tmpDir, ".done")
	if err := ctx.Run().WriteFile(doneFile, nil, os.FileMode(0600)); err != nil {
		return nil, internalTestError{err, "WriteFile"}
	}
	if err := ctx.Run().Command("gsutil", "-q", "cp", doneFile, bucket+timestamp); err != nil {
		return nil, internalTestError{err, "Upload"}
	}
	latestFile := filepath.Join(tmpDir, "latest")
	if err := ctx.Run().WriteFile(latestFile, []byte(timestamp), os.FileMode(0600)); err != nil {
		return nil, internalTestError{err, "WriteFile"}
	}
	if err := ctx.Run().Command("gsutil", "-q", "cp", latestFile, bucket); err != nil {
		return nil, internalTestError{err, "Upload"}
	}

	return &test.Result{Status: test.Passed}, nil
}
<commit_msg>devtools: make sure vanadium-go-binaries installs the syncbase profile as it is now needed to build v.io/...<commit_after>// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package test

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

	"v.io/x/devtools/internal/collect"
	"v.io/x/devtools/internal/test"
	"v.io/x/devtools/internal/tool"
	"v.io/x/devtools/internal/util"
)

// vanadiumGoBinaries uploads Vanadium binaries to Google Storage.
func vanadiumGoBinaries(ctx *tool.Context, testName string, _ ...Opt) (_ *test.Result, e error) {
	// Initialize the test.
	cleanup, err := initTest(ctx, testName, []string{"syncbase"})
	if err != nil {
		return nil, internalTestError{err, "Init"}
	}
	defer collect.Error(func() error { return cleanup() }, &e)

	// Fetch the latest stable Go snapshot.
	if err := ctx.Run().Command("v23", "update", "-manifest=snapshot/stable-go"); err != nil {
		return nil, internalTestError{err, "Update"}
	}

	// Build all v.io binaries.
	if err := ctx.Run().Command("v23", "go", "install", "v.io/..."); err != nil {
		return nil, internalTestError{err, "Install"}
	}

	// Compute the timestamp for the build snapshot.
	labelFile, err := util.ManifestFile("snapshot/stable-go")
	if err != nil {
		return nil, internalTestError{err, "ManifestFile"}
	}
	snapshotFile, err := filepath.EvalSymlinks(labelFile)
	if err != nil {
		return nil, internalTestError{err, "EvalSymlinks"}
	}
	timestamp := filepath.Base(snapshotFile)

	// Upload all v.io binaries to Google Storage.
	bucket := fmt.Sprintf("gs://vanadium-binaries/%s_%s/", runtime.GOOS, runtime.GOARCH)
	root, err := util.V23Root()
	if err != nil {
		return nil, internalTestError{err, "V23Root"}
	}
	binaries := filepath.Join(root, "release", "go", "bin", "*")
	if err := ctx.Run().Command("gsutil", "-m", "-q", "cp", binaries, bucket+timestamp); err != nil {
		return nil, internalTestError{err, "Upload"}
	}

	// Upload two files: 1) a file that identifies the directory
	// containing the latest set of binaries and 2) a file that
	// indicates that the upload of binaries succeeded.
	tmpDir, err := ctx.Run().TempDir("", "")
	if err != nil {
		return nil, internalTestError{err, "TempDir"}
	}
	defer collect.Error(func() error { return ctx.Run().RemoveAll(tmpDir) }, &e)
	doneFile := filepath.Join(tmpDir, ".done")
	if err := ctx.Run().WriteFile(doneFile, nil, os.FileMode(0600)); err != nil {
		return nil, internalTestError{err, "WriteFile"}
	}
	if err := ctx.Run().Command("gsutil", "-q", "cp", doneFile, bucket+timestamp); err != nil {
		return nil, internalTestError{err, "Upload"}
	}
	latestFile := filepath.Join(tmpDir, "latest")
	if err := ctx.Run().WriteFile(latestFile, []byte(timestamp), os.FileMode(0600)); err != nil {
		return nil, internalTestError{err, "WriteFile"}
	}
	if err := ctx.Run().Command("gsutil", "-q", "cp", latestFile, bucket); err != nil {
		return nil, internalTestError{err, "Upload"}
	}

	return &test.Result{Status: test.Passed}, nil
}
<|endoftext|>


<commit_before>package cmd

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"runtime"
	"strconv"
	"strings"
	"text/template"

	"github.com/MakeNowJust/heredoc/v2"
	"github.com/zaquestion/lab/internal/git"
)

// GetUpdateUsers returns an int slice of user IDs based on the
// current users and flags from the command line, and a bool
// indicating whether the users have changed
func getUpdateUsers(currentUsers []string, users []string, remove []string) ([]int, bool, error) {
	// add the new users to the current users, then remove the "remove" group
	users = difference(union(currentUsers, users), remove)
	usersChanged := !same(currentUsers, users)

	// turn the new user list into a list of user IDs
	var userIDs []int
	if usersChanged && len(users) == 0 {
		// if we're removing all users, we have to use []int{0}
		// see https://github.com/xanzy/go-gitlab/issues/427
		userIDs = []int{0}
	} else {
		userIDs = make([]int, len(users))
		for i, a := range users {
			if getUserID(a) == nil {
				return nil, false, fmt.Errorf("%s is not a valid username", a)
			}
			userIDs[i] = *getUserID(a)
		}
	}

	return userIDs, usersChanged, nil
}

// editDescription returns a title and description based on the
// current issue title and description and various flags from the command
// line
func editDescription(title string, body string, msgs []string, filename string) (string, string, error) {
	if len(msgs) > 0 {
		title = msgs[0]

		if len(msgs) > 1 {
			body = strings.Join(msgs[1:], "\n\n")
		}

		return title, body, nil
	}

	if filename != "" {
		var lines []string

		content, err := ioutil.ReadFile(filename)
		if err != nil {
			return "", "", nil
		}
		lines = strings.Split(string(content), "\n")

		title = lines[0]
		body = strings.Join(lines[1:], "\n")

		return title, body, nil
	}

	text, err := editText(title, body)
	if err != nil {
		return "", "", err
	}

	title, body, err = git.Edit("EDIT", text)
	if err != nil {
		_, f, l, _ := runtime.Caller(0)
		log.Fatal(f+":"+strconv.Itoa(l)+" ", err)
	}

	return title, body, nil
}

// editText places the text title and body in a specific template following Git
// standards.
func editText(title string, body string) (string, error) {
	tmpl := heredoc.Doc(`
		{{.InitMsg}}

		{{.CommentChar}} Edit the title and/or description. The first block of text
		{{.CommentChar}} is the title and the rest is the description.`)

	msg := &struct {
		InitMsg     string
		CommentChar string
	}{
		InitMsg:     title + "\n\n" + body,
		CommentChar: git.CommentChar(),
	}

	t, err := template.New("tmpl").Parse(tmpl)
	if err != nil {
		return "", err
	}

	var b bytes.Buffer
	err = t.Execute(&b, msg)
	if err != nil {
		return "", err
	}

	return b.String(), nil
}
<commit_msg>cmd/edit: fix return error value<commit_after>package cmd

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"runtime"
	"strconv"
	"strings"
	"text/template"

	"github.com/MakeNowJust/heredoc/v2"
	"github.com/zaquestion/lab/internal/git"
)

// GetUpdateUsers returns an int slice of user IDs based on the
// current users and flags from the command line, and a bool
// indicating whether the users have changed
func getUpdateUsers(currentUsers []string, users []string, remove []string) ([]int, bool, error) {
	// add the new users to the current users, then remove the "remove" group
	users = difference(union(currentUsers, users), remove)
	usersChanged := !same(currentUsers, users)

	// turn the new user list into a list of user IDs
	var userIDs []int
	if usersChanged && len(users) == 0 {
		// if we're removing all users, we have to use []int{0}
		// see https://github.com/xanzy/go-gitlab/issues/427
		userIDs = []int{0}
	} else {
		userIDs = make([]int, len(users))
		for i, a := range users {
			if getUserID(a) == nil {
				return nil, false, fmt.Errorf("%s is not a valid username", a)
			}
			userIDs[i] = *getUserID(a)
		}
	}

	return userIDs, usersChanged, nil
}

// editDescription returns a title and description based on the
// current issue title and description and various flags from the command
// line
func editDescription(title string, body string, msgs []string, filename string) (string, string, error) {
	if len(msgs) > 0 {
		title = msgs[0]

		if len(msgs) > 1 {
			body = strings.Join(msgs[1:], "\n\n")
		}

		return title, body, nil
	}

	if filename != "" {
		var lines []string

		content, err := ioutil.ReadFile(filename)
		if err != nil {
			return "", "", err
		}
		lines = strings.Split(string(content), "\n")

		title = lines[0]
		body = strings.Join(lines[1:], "\n")

		return title, body, nil
	}

	text, err := editText(title, body)
	if err != nil {
		return "", "", err
	}

	title, body, err = git.Edit("EDIT", text)
	if err != nil {
		_, f, l, _ := runtime.Caller(0)
		log.Fatal(f+":"+strconv.Itoa(l)+" ", err)
	}

	return title, body, nil
}

// editText places the text title and body in a specific template following Git
// standards.
func editText(title string, body string) (string, error) {
	tmpl := heredoc.Doc(`
		{{.InitMsg}}

		{{.CommentChar}} Edit the title and/or description. The first block of text
		{{.CommentChar}} is the title and the rest is the description.`)

	msg := &struct {
		InitMsg     string
		CommentChar string
	}{
		InitMsg:     title + "\n\n" + body,
		CommentChar: git.CommentChar(),
	}

	t, err := template.New("tmpl").Parse(tmpl)
	if err != nil {
		return "", err
	}

	var b bytes.Buffer
	err = t.Execute(&b, msg)
	if err != nil {
		return "", err
	}

	return b.String(), nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
	"regexp"
	"strings"

	"github.com/motemen/gompatible"
	"github.com/motemen/gompatible/internal/util"

	"github.com/daviddengcn/go-colortext"
)

func usage() {
	fmt.Printf("Usage: %s [-a] [-r] <rev1>[..<rev2>] [<import path>[...]]\n", os.Args[0])
	flag.PrintDefaults()
	os.Exit(1)
}

func main() {
	var (
		flagAll     = flag.Bool("a", false, "show also unchanged APIs")
		flagRecurse = flag.Bool("r", false, "recurse into subdirectories")
		flagDiff    = flag.Bool("d", false, "run `diff` on multi-line changes")
	)
	flag.Parse()
	flag.Usage = usage

	args := flag.Args()
	if len(args) < 1 {
		usage()
	}

	// TODO: support mercurial and other vcs
	vcsType := "git"

	revs := strings.SplitN(args[0], "..", 2)
	if len(revs) == 1 {
		revs = []string{revs[0] + "~1", revs[0]}
	} else if revs[1] == "" {
		revs = []string{revs[0], ""}
	}

	path := "."
	if len(args) >= 2 {
		path = args[1]

		if strings.HasSuffix(path, "...") {
			path = strings.TrimSuffix(path, "...")
			*flagRecurse = true
		}
	}

	dir1, err := gompatible.NewDirSpec(path, vcsType, revs[0])
	dieIf(err)

	pkgs1, err := gompatible.LoadDir(dir1, *flagRecurse)
	dieIf(err)

	dir2, err := gompatible.NewDirSpec(path, vcsType, revs[1])
	dieIf(err)

	pkgs2, err := gompatible.LoadDir(dir2, *flagRecurse)
	dieIf(err)

	diffs := map[string]gompatible.PackageChanges{}

	for _, name := range util.SortedStringSet(util.MapKeys(pkgs1), util.MapKeys(pkgs2)) {
		diffs[name] = gompatible.DiffPackages(
			pkgs1[name], pkgs2[name],
		)
	}

	var packageIndex int
	for _, name := range util.SortedStringSet(util.MapKeys(diffs)) {
		diff := diffs[name]

		var headerShown bool
		printHeader := func() {
			if *flagRecurse == false {
				return
			}

			if !headerShown {
				// FIXME strictly not a package if inspecting local import
				if packageIndex > 0 {
					fmt.Println()
				}
				fmt.Printf("package %s\n", name)
				headerShown = true
				packageIndex++
			}
		}

		funcs := diff.Funcs()
		for _, name := range util.SortedStringSet(util.MapKeys(funcs)) {
			change := funcs[name]
			if *flagAll || change.Kind() != gompatible.ChangeUnchanged {
				printHeader()
				printChange(change, *flagDiff)
			}
		}

		types := diff.Types()
		for _, name := range util.SortedStringSet(util.MapKeys(types)) {
			change := types[name]
			if *flagAll || change.Kind() != gompatible.ChangeUnchanged {
				printHeader()
				printChange(change, *flagDiff)
			}
		}

		values := diff.Values()
		for _, name := range util.SortedStringSet(util.MapKeys(values)) {
			change := values[name]
			if *flagAll || change.Kind() != gompatible.ChangeUnchanged {
				printHeader()
				printChange(change, *flagDiff)
			}
		}
	}
}

type changeMark struct {
	mark  string // should have length == 2
	color ct.Color
}

var (
	markAdded      = changeMark{"+ ", ct.Green}
	markRemoved    = changeMark{"- ", ct.Red}
	markUnchanged  = changeMark{"= ", ct.Blue}
	markCompatible = changeMark{"* ", ct.Yellow}
	markBreaking   = changeMark{"! ", ct.Red}
	markConfer     = changeMark{". ", ct.None}
)

var rxDiffThunkStart = regexp.MustCompile(`^(?:\x1b\[\d+m)?@@ `)

func printChange(c gompatible.Change, doDiff bool) {
	show := func(mark changeMark, s string) {
		lines := strings.Split(s, "\n")
		for i := range lines {
			if i == 0 {
				ct.ChangeColor(mark.color, false, ct.None, false)
				fmt.Print(mark.mark)
				ct.ResetColor()
				fmt.Println(lines[i])
			} else {
				fmt.Println(" ", lines[i])
			}
		}
	}

	switch c.Kind() {
	case gompatible.ChangeAdded:
		show(markAdded, c.ShowAfter())
	case gompatible.ChangeRemoved:
		show(markRemoved, c.ShowBefore())
	case gompatible.ChangeUnchanged:
		show(markUnchanged, c.ShowBefore())
	case gompatible.ChangeCompatible:
		showCompare(markCompatible, c, show, doDiff)
	case gompatible.ChangeBreaking:
		showCompare(markBreaking, c, show, doDiff)
	}
}

func showCompare(mark changeMark, c gompatible.Change, show func(changeMark, string), doDiff bool) {
	if doDiff == false {
		show(mark, c.ShowBefore())
		show(markConfer, c.ShowAfter())
		return
	}

	d, err := diff([]byte(c.ShowBefore()), []byte(c.ShowAfter()))
	dieIf(err)

	ct.ChangeColor(mark.color, false, ct.None, false)
	fmt.Print(mark.mark)
	ct.ResetColor()

	fmt.Println(typesObjectString(c.TypesObject()))

	lines := strings.Split(string(d), "\n")
	inHeader := true
	for _, line := range lines {
		if inHeader {
			if rxDiffThunkStart.MatchString(line) {
				inHeader = false
			} else {
				continue
			}
		}
		fmt.Println("  " + line)
	}
}
<commit_msg>exit with 1 if there are breaking changes<commit_after>// gompat takes Go package and revision range to show
// API changes between two revisions.
package main

import (
	"flag"
	"fmt"
	"os"
	"regexp"
	"strings"

	"github.com/motemen/gompatible"
	"github.com/motemen/gompatible/internal/util"

	"github.com/daviddengcn/go-colortext"
)

func usage() {
	fmt.Printf("Usage: %s [-a] [-r] <rev1>[..<rev2>] [<import path>[/...]]\n", os.Args[0])
	flag.PrintDefaults()
	os.Exit(1)
}

func main() {
	var (
		flagAll     = flag.Bool("a", false, "show also unchanged APIs")
		flagRecurse = flag.Bool("r", false, `recurse into subdirectories (can be specified by "/..." suffix to the import path)`)
		flagDiff    = flag.Bool("d", false, "run diff on multi-line changes")
	)
	flag.Parse()
	flag.Usage = usage

	args := flag.Args()
	if len(args) < 1 {
		usage()
	}

	// TODO: support mercurial and other vcs
	vcsType := "git"

	revs := strings.SplitN(args[0], "..", 2)
	if len(revs) == 1 {
		revs = []string{revs[0] + "~1", revs[0]}
	} else if revs[1] == "" {
		revs = []string{revs[0], ""}
	}

	path := "."
	if len(args) >= 2 {
		path = args[1]

		if strings.HasSuffix(path, "...") {
			path = strings.TrimSuffix(path, "...")
			*flagRecurse = true
		}
	}

	dir1, err := gompatible.NewDirSpec(path, vcsType, revs[0])
	dieIf(err)

	pkgs1, err := gompatible.LoadDir(dir1, *flagRecurse)
	dieIf(err)

	dir2, err := gompatible.NewDirSpec(path, vcsType, revs[1])
	dieIf(err)

	pkgs2, err := gompatible.LoadDir(dir2, *flagRecurse)
	dieIf(err)

	diffs := map[string]gompatible.PackageChanges{}

	for _, name := range util.SortedStringSet(util.MapKeys(pkgs1), util.MapKeys(pkgs2)) {
		diffs[name] = gompatible.DiffPackages(
			pkgs1[name], pkgs2[name],
		)
	}

	var packageIndex int
	var hasBreaking bool
	for _, name := range util.SortedStringSet(util.MapKeys(diffs)) {
		diff := diffs[name]

		var headerShown bool
		printHeader := func() {
			if *flagRecurse == false {
				return
			}

			if !headerShown {
				// FIXME strictly not a package if inspecting local import
				if packageIndex > 0 {
					fmt.Println()
				}
				fmt.Printf("package %s\n", name)
				headerShown = true
				packageIndex++
			}
		}

		funcs := diff.Funcs()
		for _, name := range util.SortedStringSet(util.MapKeys(funcs)) {
			change := funcs[name]
			if *flagAll || change.Kind() != gompatible.ChangeUnchanged {
				printHeader()
				printChange(change, *flagDiff)
			}
			if change.Kind() == gompatible.ChangeBreaking || change.Kind() == gompatible.ChangeRemoved {
				hasBreaking = true
			}
		}

		types := diff.Types()
		for _, name := range util.SortedStringSet(util.MapKeys(types)) {
			change := types[name]
			if *flagAll || change.Kind() != gompatible.ChangeUnchanged {
				printHeader()
				printChange(change, *flagDiff)
			}
			if change.Kind() == gompatible.ChangeBreaking || change.Kind() == gompatible.ChangeRemoved {
				hasBreaking = true
			}
		}

		values := diff.Values()
		for _, name := range util.SortedStringSet(util.MapKeys(values)) {
			change := values[name]
			if *flagAll || change.Kind() != gompatible.ChangeUnchanged {
				printHeader()
				printChange(change, *flagDiff)
			}
			if change.Kind() == gompatible.ChangeBreaking || change.Kind() == gompatible.ChangeRemoved {
				hasBreaking = true
			}
		}
	}

	if hasBreaking {
		os.Exit(1)
	}
}

type changeMark struct {
	mark  string // should have length == 2
	color ct.Color
}

var (
	markAdded      = changeMark{"+ ", ct.Green}
	markRemoved    = changeMark{"- ", ct.Red}
	markUnchanged  = changeMark{"= ", ct.Blue}
	markCompatible = changeMark{"* ", ct.Yellow}
	markBreaking   = changeMark{"! ", ct.Red}
	markConfer     = changeMark{". ", ct.None}
)

var rxDiffThunkStart = regexp.MustCompile(`^(?:\x1b\[\d+m)?@@ `)

func printChange(c gompatible.Change, doDiff bool) {
	show := func(mark changeMark, s string) {
		lines := strings.Split(s, "\n")
		for i := range lines {
			if i == 0 {
				ct.ChangeColor(mark.color, false, ct.None, false)
				fmt.Print(mark.mark)
				ct.ResetColor()
				fmt.Println(lines[i])
			} else {
				fmt.Println(" ", lines[i])
			}
		}
	}

	switch c.Kind() {
	case gompatible.ChangeAdded:
		show(markAdded, c.ShowAfter())
	case gompatible.ChangeRemoved:
		show(markRemoved, c.ShowBefore())
	case gompatible.ChangeUnchanged:
		show(markUnchanged, c.ShowBefore())
	case gompatible.ChangeCompatible:
		showCompare(markCompatible, c, show, doDiff)
	case gompatible.ChangeBreaking:
		showCompare(markBreaking, c, show, doDiff)
	}
}

func showCompare(mark changeMark, c gompatible.Change, show func(changeMark, string), doDiff bool) {
	if doDiff == false {
		show(mark, c.ShowBefore())
		show(markConfer, c.ShowAfter())
		return
	}

	d, err := diff([]byte(c.ShowBefore()), []byte(c.ShowAfter()))
	dieIf(err)

	ct.ChangeColor(mark.color, false, ct.None, false)
	fmt.Print(mark.mark)
	ct.ResetColor()

	fmt.Println(typesObjectString(c.TypesObject()))

	lines := strings.Split(string(d), "\n")
	inHeader := true
	for _, line := range lines {
		if inHeader {
			if rxDiffThunkStart.MatchString(line) {
				inHeader = false
			} else {
				continue
			}
		}
		fmt.Println("  " + line)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"time"

	"gopkg.in/alecthomas/kingpin.v2"
)

const (
	version = "master"
)

const (
	actionPush = "push"
	actionInit = "init"

	defaultTimeout = time.Second * 5
)

func main() {
	if len(os.Args) == 5 {
		runProxy(os.Args[4])
		return
	}

	cli := kingpin.New("helm s3", "")
	cli.Version(version)
	initCmd := cli.Command(actionInit, "Initialize empty repository on AWS S3.")
	initURI := initCmd.Arg("uri", "URI of repository, e.g. s3://awesome-bucket/charts").
		Required().
		String()
	pushCmd := cli.Command(actionPush, "Push chart to repository.")
	pushChartPath := pushCmd.Arg("chartPath", "Path to a chart, e.g. ./epicservice-0.5.1.tgz").
		Required().
		String()
	pushTargetRepository := pushCmd.Arg("repo", "Target repository to runPush").
		Required().
		String()
	action := kingpin.MustParse(cli.Parse(os.Args[1:]))
	if action == "" {
		cli.Usage(os.Args[1:])
		os.Exit(0)
	}

	switch action {

	case actionInit:
		runInit(*initURI)
		return

	case actionPush:
		runPush(*pushChartPath, *pushTargetRepository)
		return

	}
}
<commit_msg>Fix version variable<commit_after>package main

import (
	"os"
	"time"

	"gopkg.in/alecthomas/kingpin.v2"
)

var (
	version = "master"
)

const (
	actionPush = "push"
	actionInit = "init"

	defaultTimeout = time.Second * 5
)

func main() {
	if len(os.Args) == 5 {
		runProxy(os.Args[4])
		return
	}

	cli := kingpin.New("helm s3", "")
	cli.Version(version)
	initCmd := cli.Command(actionInit, "Initialize empty repository on AWS S3.")
	initURI := initCmd.Arg("uri", "URI of repository, e.g. s3://awesome-bucket/charts").
		Required().
		String()
	pushCmd := cli.Command(actionPush, "Push chart to repository.")
	pushChartPath := pushCmd.Arg("chartPath", "Path to a chart, e.g. ./epicservice-0.5.1.tgz").
		Required().
		String()
	pushTargetRepository := pushCmd.Arg("repo", "Target repository to runPush").
		Required().
		String()
	action := kingpin.MustParse(cli.Parse(os.Args[1:]))
	if action == "" {
		cli.Usage(os.Args[1:])
		os.Exit(0)
	}

	switch action {

	case actionInit:
		runInit(*initURI)
		return

	case actionPush:
		runPush(*pushChartPath, *pushTargetRepository)
		return

	}
}
<|endoftext|>


<commit_before>package cmd

import (
	"fmt"
	"net/url"

	"github.com/jmoiron/sqlx"
	"github.com/markbates/pop"
	"github.com/netlify/gotrue/conf"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
)

var migrateCmd = cobra.Command{
	Use:  "migrate",
	Long: "Migrate database strucutures. This will create new tables and add missing columns and indexes.",
	Run:  migrate,
}

func migrate(cmd *cobra.Command, args []string) {
	globalConfig, err := conf.LoadGlobal(configFile)
	if err != nil {
		logrus.Fatalf("Failed to load configuration: %+v", err)
	}
	if globalConfig.DB.Driver == "" && globalConfig.DB.URL != "" {
		u, err := url.Parse(globalConfig.DB.URL)
		if err != nil {
			logrus.Fatalf("%+v", errors.Wrap(err, "parsing db connection url"))
		}
		globalConfig.DB.Driver = u.Scheme
	}
	pop.Debug = true

	deets := &pop.ConnectionDetails{
		Dialect: globalConfig.DB.Driver,
		URL:     globalConfig.DB.URL,
	}
	if globalConfig.DB.Namespace != "" {
		deets.Options = map[string]string{
			"Namespace": globalConfig.DB.Namespace + "_",
		}
	}

	db, err := pop.NewConnection(deets)
	if err != nil {
		logrus.Fatalf("%+v", errors.Wrap(err, "opening db connection"))
	}
	defer db.Close()

	err = createDB(db)
	if err != nil {
		logrus.Fatalf("%+v", errors.Wrap(err, "creating database"))
	}

	if err := db.Open(); err != nil {
		logrus.Fatalf("%+v", errors.Wrap(err, "checking database connection"))
	}

	mig, err := pop.NewFileMigrator(globalConfig.DB.MigrationsPath, db)
	if err != nil {
		logrus.Fatalf("%+v", errors.Wrap(err, "creating db migrator"))
	}
	// turn off schema dump
	mig.SchemaPath = ""

	err = mig.Up()
	if err != nil {
		logrus.Fatalf("%+v", errors.Wrap(err, "running db migrations"))
	}
}

func createDB(conn *pop.Connection) error {
	deets := conn.Dialect.Details()
	s := "%s:%s@(%s:%s)/?parseTime=true&multiStatements=true&readTimeout=1s"
	urlWithoutDb := fmt.Sprintf(s, deets.User, deets.Password, deets.Host, deets.Port)

	db, err := sqlx.Open(deets.Dialect, urlWithoutDb)
	if err != nil {
		return errors.Wrapf(err, "error creating MySQL database %s", deets.Database)
	}
	defer db.Close()
	query := fmt.Sprintf("CREATE DATABASE IF NOT EXISTS `%s` DEFAULT COLLATE `utf8mb4_unicode_ci`", deets.Database)

	_, err = db.Exec(query)
	if err != nil {
		return errors.Wrapf(err, "error creating MySQL database %s", deets.Database)
	}
	return nil
}
<commit_msg>Remove db creation from migrate<commit_after>package cmd

import (
	"net/url"

	"github.com/markbates/pop"
	"github.com/netlify/gotrue/conf"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
)

var migrateCmd = cobra.Command{
	Use:  "migrate",
	Long: "Migrate database strucutures. This will create new tables and add missing columns and indexes.",
	Run:  migrate,
}

func migrate(cmd *cobra.Command, args []string) {
	globalConfig, err := conf.LoadGlobal(configFile)
	if err != nil {
		logrus.Fatalf("Failed to load configuration: %+v", err)
	}
	if globalConfig.DB.Driver == "" && globalConfig.DB.URL != "" {
		u, err := url.Parse(globalConfig.DB.URL)
		if err != nil {
			logrus.Fatalf("%+v", errors.Wrap(err, "parsing db connection url"))
		}
		globalConfig.DB.Driver = u.Scheme
	}
	pop.Debug = true

	deets := &pop.ConnectionDetails{
		Dialect: globalConfig.DB.Driver,
		URL:     globalConfig.DB.URL,
	}
	if globalConfig.DB.Namespace != "" {
		deets.Options = map[string]string{
			"Namespace": globalConfig.DB.Namespace + "_",
		}
	}

	db, err := pop.NewConnection(deets)
	if err != nil {
		logrus.Fatalf("%+v", errors.Wrap(err, "opening db connection"))
	}
	defer db.Close()

	if err := db.Open(); err != nil {
		logrus.Fatalf("%+v", errors.Wrap(err, "checking database connection"))
	}

	mig, err := pop.NewFileMigrator(globalConfig.DB.MigrationsPath, db)
	if err != nil {
		logrus.Fatalf("%+v", errors.Wrap(err, "creating db migrator"))
	}
	// turn off schema dump
	mig.SchemaPath = ""

	err = mig.Up()
	if err != nil {
		logrus.Fatalf("%+v", errors.Wrap(err, "running db migrations"))
	}
}
<|endoftext|>


<commit_before>// (c) Copyright IBM Corp. 2021
// (c) Copyright Instana Inc. 2020

package instana_test

import (
	"log"
	"net/http"

	instana "github.com/instana/go-sensor"
)

// This example shows how to instrument an HTTP server with Instana tracing
func Example_tracingHandlerFunc() {
	sensor := instana.NewSensor("my-http-server")

	// To instrument a handler function, pass it as an argument to instana.TracingHandlerFunc()
	http.HandleFunc("/", instana.TracingHandlerFunc(sensor, "/", func(w http.ResponseWriter, req *http.Request) {
		// Extract the parent span and use its tracer to initialize any child spans to trace the calls
		// inside the handler, e.g. database queries, 3rd-party API requests, etc.
		if parent, ok := instana.SpanFromContext(req.Context()); ok {
			sp := parent.Tracer().StartSpan("index")
			defer sp.Finish()
		}

		// ...

		w.Write([]byte("OK"))
	}))

	// In case your handler is implemented as an http.Handler, pass its ServeHTTP method instead
	http.HandleFunc("/files", instana.TracingHandlerFunc(sensor, "index", http.FileServer(http.Dir("./")).ServeHTTP))

	if err := http.ListenAndServe(":0", nil); err != nil {
		log.Fatalf("failed to start server: %s", err)
	}
}

// This example demonstrates how to instrument a 3rd-party HTTP router that uses pattern matching to make sure
// the original path template is forwarded to Instana
func Example_httpRoutePatternMatching() {
	sensor := instana.NewSensor("my-http-server")

	// Initialize your router. Here for simplicity we use stdlib http.ServeMux, however you
	// can use any router that supports http.Handler/http.HandlerFunc, such as github.com/gorilla/mux
	r := http.NewServeMux()

	// Wrap the handler using instana.TracingHandlerFunc() and pass the path template
	// used to route requests to it. This value will be attached to the span and displayed
	// in UI as `http.path_tpl` if the request path is different (we assume that this request
	// has been routed to the handler via a matched pattern)
	r.HandleFunc("/articles/{category}/{id:[0-9]+}", instana.TracingHandlerFunc(
		sensor,
		"/articles/{category}/{id:[0-9]+}",
		func(w http.ResponseWriter, req *http.Request) {
			// ...
		},
	))

	if err := http.ListenAndServe(":0", nil); err != nil {
		log.Fatalf("failed to start server: %s", err)
	}
}
<commit_msg>Update TracingHandlerFunc example with an instruction on how to propagate context inside the handler<commit_after>// (c) Copyright IBM Corp. 2021
// (c) Copyright Instana Inc. 2020

package instana_test

import (
	"log"
	"net/http"

	instana "github.com/instana/go-sensor"
	"github.com/opentracing/opentracing-go"
)

// This example shows how to instrument an HTTP server with Instana tracing
func Example_tracingHandlerFunc() {
	sensor := instana.NewSensor("my-http-server")

	// To instrument a handler function, pass it as an argument to instana.TracingHandlerFunc()
	http.HandleFunc("/", instana.TracingHandlerFunc(sensor, "/", func(w http.ResponseWriter, req *http.Request) {
		// Extract the parent span and use its tracer to initialize any child spans to trace the calls
		// inside the handler, e.g. database queries, 3rd-party API requests, etc.
		if parent, ok := instana.SpanFromContext(req.Context()); ok {
			sp := parent.Tracer().StartSpan("index", opentracing.ChildOf(parent.Context()))
			defer sp.Finish()
		}

		// ...

		w.Write([]byte("OK"))
	}))

	// In case your handler is implemented as an http.Handler, pass its ServeHTTP method instead
	http.HandleFunc("/files", instana.TracingHandlerFunc(sensor, "index", http.FileServer(http.Dir("./")).ServeHTTP))

	if err := http.ListenAndServe(":0", nil); err != nil {
		log.Fatalf("failed to start server: %s", err)
	}
}

// This example demonstrates how to instrument a 3rd-party HTTP router that uses pattern matching to make sure
// the original path template is forwarded to Instana
func Example_httpRoutePatternMatching() {
	sensor := instana.NewSensor("my-http-server")

	// Initialize your router. Here for simplicity we use stdlib http.ServeMux, however you
	// can use any router that supports http.Handler/http.HandlerFunc, such as github.com/gorilla/mux
	r := http.NewServeMux()

	// Wrap the handler using instana.TracingHandlerFunc() and pass the path template
	// used to route requests to it. This value will be attached to the span and displayed
	// in UI as `http.path_tpl` if the request path is different (we assume that this request
	// has been routed to the handler via a matched pattern)
	r.HandleFunc("/articles/{category}/{id:[0-9]+}", instana.TracingHandlerFunc(
		sensor,
		"/articles/{category}/{id:[0-9]+}",
		func(w http.ResponseWriter, req *http.Request) {
			// ...
		},
	))

	if err := http.ListenAndServe(":0", nil); err != nil {
		log.Fatalf("failed to start server: %s", err)
	}
}
<|endoftext|>


<commit_before>// Package driver holds the driver interface.
package driver

import (
	"errors"
	"flag"
	"fmt"
	"log"
	neturl "net/url"
	"os"
	"strings"

	"github.com/fedyakin/migrate/driver/bash"
	"github.com/fedyakin/migrate/driver/cassandra"
	"github.com/fedyakin/migrate/driver/mysql" // alias to allow `url string` func signature in New
	"github.com/fedyakin/migrate/driver/postgres"
	"github.com/fedyakin/migrate/file"
)

var transactionType = flag.String("txn", "", "")

type TxnType int

const (
	TxnNone TxnType = iota
	TxnPerFile
	TxnSingle
)

// Driver is the interface type that needs to implemented by all drivers.
type Driver interface {

	// Initialize is the first function to be called.
	// Check the url string and open and verify any connection
	// that has to be made.
	Initialize(url string) error

	// Close is the last function to be called.
	// Close any open connection here.
	Close() error

	// FilenameExtension returns the extension of the migration files.
	// The returned string must not begin with a dot.
	FilenameExtension() string

	// Migrate is the heart of the driver.
	// It will receive a file which the driver should apply
	// to its backend or whatever. The migration function should use
	// the pipe channel to return any errors or other useful information.
	Migrate(file file.File, pipe chan interface{})

	// Version returns the current migration version.
	Version() (uint64, error)
}

// New returns Driver and calls Initialize on it
func New(url string) (Driver, error) {
	u, err := neturl.Parse(url)
	if err != nil {
		return nil, err
	}

	switch u.Scheme {
	case "postgres":
		txnType, err := getTxnType()
		if err != nil {
			fmt.Println(err.Error())
			os.Exit(1)
		}

		// For postgres we support multiple transaction strategies
		var d Driver
		switch txnType {
		case TxnNone:
			d = &postgres.NoTxnDriver{}
			log.Println("Migration scripts will be executed with no explicit transactions")
		case TxnPerFile:
			d = &postgres.PerFileTxnDriver{}
			log.Println("Each migration script will be executed in its own transaction")
		case TxnSingle:
			d = &postgres.SingleTxnDriver{}
			log.Println("All migration scripts will be executed in a single transaction")
		}

		verifyFilenameExtension("postgres", d)
		if err := d.Initialize(url); err != nil {
			return nil, err
		}
		return d, nil

	case "mysql":
		d := &mysql.Driver{}
		verifyFilenameExtension("mysql", d)
		if err := d.Initialize(url); err != nil {
			return nil, err
		}
		return d, nil

	case "bash":
		d := &bash.Driver{}
		verifyFilenameExtension("bash", d)
		if err := d.Initialize(url); err != nil {
			return nil, err
		}
		return d, nil

	case "cassandra":
		d := &cassandra.Driver{}
		verifyFilenameExtension("cassanda", d)
		if err := d.Initialize(url); err != nil {
			return nil, err
		}
		return d, nil
	default:
		return nil, errors.New(fmt.Sprintf("Driver '%s' not found.", u.Scheme))
	}
}

// verifyFilenameExtension panics if the drivers filename extension
// is not correct or empty.
func verifyFilenameExtension(driverName string, d Driver) {
	f := d.FilenameExtension()
	if f == "" {
		panic(fmt.Sprintf("%s.FilenameExtension() returns empty string.", driverName))
	}
	if f[0:1] == "." {
		panic(fmt.Sprintf("%s.FilenameExtension() returned string must not start with a dot.", driverName))
	}
}

// getTxnType returns the transaction behavior specified, or an error for unknown
// or undefined behaviors
func getTxnType() (TxnType, error) {
	switch strings.ToLower(*transactionType) {
	case "none":
		return TxnNone, nil

	case "single":
		return TxnSingle, nil

	case "perfile":
		return TxnPerFile, nil
	}

	return TxnNone, fmt.Errorf("Unknown transaction type requested: %s", transactionType)
}
<commit_msg>Made transaction type default to PerFile for backwards compatability Fixed an error statement to print the string, not the pointer to the string<commit_after>// Package driver holds the driver interface.
package driver

import (
	"errors"
	"flag"
	"fmt"
	"log"
	neturl "net/url"
	"os"
	"strings"

	"github.com/fedyakin/migrate/driver/bash"
	"github.com/fedyakin/migrate/driver/cassandra"
	"github.com/fedyakin/migrate/driver/mysql" // alias to allow `url string` func signature in New
	"github.com/fedyakin/migrate/driver/postgres"
	"github.com/fedyakin/migrate/file"
)

var transactionType = flag.String("txn", "PerFile", "")

type TxnType int

const (
	TxnNone TxnType = iota
	TxnPerFile
	TxnSingle
)

// Driver is the interface type that needs to implemented by all drivers.
type Driver interface {

	// Initialize is the first function to be called.
	// Check the url string and open and verify any connection
	// that has to be made.
	Initialize(url string) error

	// Close is the last function to be called.
	// Close any open connection here.
	Close() error

	// FilenameExtension returns the extension of the migration files.
	// The returned string must not begin with a dot.
	FilenameExtension() string

	// Migrate is the heart of the driver.
	// It will receive a file which the driver should apply
	// to its backend or whatever. The migration function should use
	// the pipe channel to return any errors or other useful information.
	Migrate(file file.File, pipe chan interface{})

	// Version returns the current migration version.
	Version() (uint64, error)
}

// New returns Driver and calls Initialize on it
func New(url string) (Driver, error) {
	u, err := neturl.Parse(url)
	if err != nil {
		return nil, err
	}

	switch u.Scheme {
	case "postgres":
		txnType, err := getTxnType()
		if err != nil {
			fmt.Println(err.Error())
			os.Exit(1)
		}

		// For postgres we support multiple transaction strategies
		var d Driver
		switch txnType {
		case TxnNone:
			d = &postgres.NoTxnDriver{}
			log.Println("Migration scripts will be executed with no explicit transactions")
		case TxnPerFile:
			d = &postgres.PerFileTxnDriver{}
			log.Println("Each migration script will be executed in its own transaction")
		case TxnSingle:
			d = &postgres.SingleTxnDriver{}
			log.Println("All migration scripts will be executed in a single transaction")
		}

		verifyFilenameExtension("postgres", d)
		if err := d.Initialize(url); err != nil {
			return nil, err
		}
		return d, nil

	case "mysql":
		d := &mysql.Driver{}
		verifyFilenameExtension("mysql", d)
		if err := d.Initialize(url); err != nil {
			return nil, err
		}
		return d, nil

	case "bash":
		d := &bash.Driver{}
		verifyFilenameExtension("bash", d)
		if err := d.Initialize(url); err != nil {
			return nil, err
		}
		return d, nil

	case "cassandra":
		d := &cassandra.Driver{}
		verifyFilenameExtension("cassanda", d)
		if err := d.Initialize(url); err != nil {
			return nil, err
		}
		return d, nil
	default:
		return nil, errors.New(fmt.Sprintf("Driver '%s' not found.", u.Scheme))
	}
}

// verifyFilenameExtension panics if the drivers filename extension
// is not correct or empty.
func verifyFilenameExtension(driverName string, d Driver) {
	f := d.FilenameExtension()
	if f == "" {
		panic(fmt.Sprintf("%s.FilenameExtension() returns empty string.", driverName))
	}
	if f[0:1] == "." {
		panic(fmt.Sprintf("%s.FilenameExtension() returned string must not start with a dot.", driverName))
	}
}

// getTxnType returns the transaction behavior specified, or an error for unknown
// or undefined behaviors
func getTxnType() (TxnType, error) {
	switch strings.ToLower(*transactionType) {
	case "none":
		return TxnNone, nil

	case "single":
		return TxnSingle, nil

	case "perfile":
		return TxnPerFile, nil
	}

	return TxnNone, fmt.Errorf("Unknown transaction type requested: '%s'", *transactionType)
}
<|endoftext|>


<commit_before>package fakedata

import (
	"math/rand"
	"strconv"

	"github.com/icrowley/fake"
	"github.com/twinj/uuid"
)

//FakeAdapter contains all available functions to create random data in the mock response.
type FakeAdapter struct {
}

//Brand returns a random Brand
func (fa FakeAdapter) Brand() string {
	return fake.Brand()
}

//Character returns a random Character
func (fa FakeAdapter) Character() string {
	return fake.Character()
}

//Characters returns from 1 to 5 random Characters
func (fa FakeAdapter) Characters() string {
	return fake.Characters()
}

//CharactersN returns n random Characters
func (fa FakeAdapter) CharactersN(n int) string {
	return fake.CharactersN(n)
}

//City returns a random City
func (fa FakeAdapter) City() string {
	return fake.City()
}

//Color returns a random Color
func (fa FakeAdapter) Color() string {
	return fake.Color()
}

//Company returns a random Company
func (fa FakeAdapter) Company() string {
	return fake.Company()
}

//Continent returns a random Continent
func (fa FakeAdapter) Continent() string {
	return fake.Continent()
}

//Country returns a random Country
func (fa FakeAdapter) Country() string {
	return fake.Country()
}

//CreditCardVisa returns a random CreditCardVisa
func (fa FakeAdapter) CreditCardVisa() string {
	return fake.CreditCardNum("Visa")
}

//CreditCardMasterCard returns a random CreditCardMasterCard
func (fa FakeAdapter) CreditCardMasterCard() string {
	return fake.CreditCardNum("MasterCard")
}

//CreditCardAmericanExpress returns a random CreditCardAmericanExpress
func (fa FakeAdapter) CreditCardAmericanExpress() string {
	return fake.CreditCardNum("American Express")
}

//Currency returns a random Currency
func (fa FakeAdapter) Currency() string {
	return fake.Currency()
}

//CurrencyCode returns a random CurrencyCode
func (fa FakeAdapter) CurrencyCode() string {
	return fake.CurrencyCode()
}

//Digits returns from 1 to 5 random Digits
func (fa FakeAdapter) Digits() string {
	return fake.Digits()
}

//DigitsN returns n random Digits
func (fa FakeAdapter) DigitsN(n int) string {
	return fake.DigitsN(n)
}

//EmailAddress returns a random EmailAddress
func (fa FakeAdapter) EmailAddress() string {
	return fake.EmailAddress()
}

//FirstName returns a random FirstName
func (fa FakeAdapter) FirstName() string {
	return fake.FirstName()
}

//FullName returns a random FullName
func (fa FakeAdapter) FullName() string {
	return fake.FullName()
}

//LastName returns a random LastName
func (fa FakeAdapter) LastName() string {
	return fake.LastName()
}

//Gender returns a random Gender
func (fa FakeAdapter) Gender() string {
	return fake.Gender()
}

//IPv4 returns a random IPv4
func (fa FakeAdapter) IPv4() string {
	return fake.IPv4()
}

//Language returns a random Language
func (fa FakeAdapter) Language() string {
	return fake.Language()
}

//Model returns a random Model
func (fa FakeAdapter) Model() string {
	return fake.Model()
}

//Paragraph returns a random Paragraph
func (fa FakeAdapter) Paragraph() string {
	return fake.Paragraph()
}

//Paragraphs returns from 1 to 5 random Paragraphs
func (fa FakeAdapter) Paragraphs() string {
	return fake.Paragraphs()
}

//ParagraphsN returns n random Paragraphs
func (fa FakeAdapter) ParagraphsN(n int) string {
	return fake.ParagraphsN(n)
}

//Phone returns a random Phone
func (fa FakeAdapter) Phone() string {
	return fake.Phone()
}

//Product returns a random Product
func (fa FakeAdapter) Product() string {
	return fake.Product()
}

//Sentence returns a random sentence
func (fa FakeAdapter) Sentence() string {
	return fake.Sentence()
}

//Sentences returns from 1 to 5 random sentences
func (fa FakeAdapter) Sentences() string {
	return fake.Sentences()
}

//SentencesN returns n random sentences
func (fa FakeAdapter) SentencesN(n int) string {
	return fake.SentencesN(n)
}

//SimplePassword returns a random simple password
func (fa FakeAdapter) SimplePassword() string {
	return fake.SimplePassword()
}

//State returns a random state
func (fa FakeAdapter) State() string {
	return fake.State()
}

//StateAbbrev returns a random state abbrev
func (fa FakeAdapter) StateAbbrev() string {
	return fake.StateAbbrev()
}

//Street returns a random street
func (fa FakeAdapter) Street() string {
	return fake.Street()
}

//StreetAddress returns a random street address
func (fa FakeAdapter) StreetAddress() string {
	return fake.StreetAddress()
}

//UserName returns a random username
func (fa FakeAdapter) UserName() string {
	return fake.UserName()
}

//Day returns a random day
func (fa FakeAdapter) Day() string {
	return strconv.Itoa(fake.Day())
}

//Month returns a random month
func (fa FakeAdapter) Month() string {
	return fake.Month()
}

//Year returns a random year between (1980,2020)
func (fa FakeAdapter) Year() string {
	return strconv.Itoa(fake.Year(1980, 2020))
}

//MonthShort returns a random month (Short Version)
func (fa FakeAdapter) MonthShort() string {
	return fake.MonthShort()
}

//WeekDay returns a random day of week
func (fa FakeAdapter) WeekDay() string {
	return fake.WeekDay()
}

//Word returns a random word
func (fa FakeAdapter) Word() string {
	return fake.Word()
}

//Words returns from 1 to 5 random words
func (fa FakeAdapter) Words() string {
	return fake.Words()
}

//WordsN returns n random words
func (fa FakeAdapter) WordsN(n int) string {
	return fake.WordsN(n)
}

//Zip returns a random zip
func (fa FakeAdapter) Zip() string {
	return fake.Zip()
}

//Number returns a random positive number less than or equal to n
func (fa FakeAdapter) Int(n int) string {
	return strconv.Itoa(rand.Intn(n + 1))
}

//Float returns a random positive floating point number less than n
func (fa FakeAdapter) Float(n int) string {
	f := float64(n)
	value := rand.Float64() * f
	return strconv.FormatFloat(value, 'f', 4, 64)
}

//UUID generates a unique id
func (fa FakeAdapter) UUID() string {
	u := uuid.NewV2(uuid.DomainUser)
	return u.String()
}
<commit_msg>fixing build to use V4 guid<commit_after>package fakedata

import (
	"math/rand"
	"strconv"

	"github.com/icrowley/fake"
	"github.com/twinj/uuid"
)

//FakeAdapter contains all available functions to create random data in the mock response.
type FakeAdapter struct {
}

//Brand returns a random Brand
func (fa FakeAdapter) Brand() string {
	return fake.Brand()
}

//Character returns a random Character
func (fa FakeAdapter) Character() string {
	return fake.Character()
}

//Characters returns from 1 to 5 random Characters
func (fa FakeAdapter) Characters() string {
	return fake.Characters()
}

//CharactersN returns n random Characters
func (fa FakeAdapter) CharactersN(n int) string {
	return fake.CharactersN(n)
}

//City returns a random City
func (fa FakeAdapter) City() string {
	return fake.City()
}

//Color returns a random Color
func (fa FakeAdapter) Color() string {
	return fake.Color()
}

//Company returns a random Company
func (fa FakeAdapter) Company() string {
	return fake.Company()
}

//Continent returns a random Continent
func (fa FakeAdapter) Continent() string {
	return fake.Continent()
}

//Country returns a random Country
func (fa FakeAdapter) Country() string {
	return fake.Country()
}

//CreditCardVisa returns a random CreditCardVisa
func (fa FakeAdapter) CreditCardVisa() string {
	return fake.CreditCardNum("Visa")
}

//CreditCardMasterCard returns a random CreditCardMasterCard
func (fa FakeAdapter) CreditCardMasterCard() string {
	return fake.CreditCardNum("MasterCard")
}

//CreditCardAmericanExpress returns a random CreditCardAmericanExpress
func (fa FakeAdapter) CreditCardAmericanExpress() string {
	return fake.CreditCardNum("American Express")
}

//Currency returns a random Currency
func (fa FakeAdapter) Currency() string {
	return fake.Currency()
}

//CurrencyCode returns a random CurrencyCode
func (fa FakeAdapter) CurrencyCode() string {
	return fake.CurrencyCode()
}

//Digits returns from 1 to 5 random Digits
func (fa FakeAdapter) Digits() string {
	return fake.Digits()
}

//DigitsN returns n random Digits
func (fa FakeAdapter) DigitsN(n int) string {
	return fake.DigitsN(n)
}

//EmailAddress returns a random EmailAddress
func (fa FakeAdapter) EmailAddress() string {
	return fake.EmailAddress()
}

//FirstName returns a random FirstName
func (fa FakeAdapter) FirstName() string {
	return fake.FirstName()
}

//FullName returns a random FullName
func (fa FakeAdapter) FullName() string {
	return fake.FullName()
}

//LastName returns a random LastName
func (fa FakeAdapter) LastName() string {
	return fake.LastName()
}

//Gender returns a random Gender
func (fa FakeAdapter) Gender() string {
	return fake.Gender()
}

//IPv4 returns a random IPv4
func (fa FakeAdapter) IPv4() string {
	return fake.IPv4()
}

//Language returns a random Language
func (fa FakeAdapter) Language() string {
	return fake.Language()
}

//Model returns a random Model
func (fa FakeAdapter) Model() string {
	return fake.Model()
}

//Paragraph returns a random Paragraph
func (fa FakeAdapter) Paragraph() string {
	return fake.Paragraph()
}

//Paragraphs returns from 1 to 5 random Paragraphs
func (fa FakeAdapter) Paragraphs() string {
	return fake.Paragraphs()
}

//ParagraphsN returns n random Paragraphs
func (fa FakeAdapter) ParagraphsN(n int) string {
	return fake.ParagraphsN(n)
}

//Phone returns a random Phone
func (fa FakeAdapter) Phone() string {
	return fake.Phone()
}

//Product returns a random Product
func (fa FakeAdapter) Product() string {
	return fake.Product()
}

//Sentence returns a random sentence
func (fa FakeAdapter) Sentence() string {
	return fake.Sentence()
}

//Sentences returns from 1 to 5 random sentences
func (fa FakeAdapter) Sentences() string {
	return fake.Sentences()
}

//SentencesN returns n random sentences
func (fa FakeAdapter) SentencesN(n int) string {
	return fake.SentencesN(n)
}

//SimplePassword returns a random simple password
func (fa FakeAdapter) SimplePassword() string {
	return fake.SimplePassword()
}

//State returns a random state
func (fa FakeAdapter) State() string {
	return fake.State()
}

//StateAbbrev returns a random state abbrev
func (fa FakeAdapter) StateAbbrev() string {
	return fake.StateAbbrev()
}

//Street returns a random street
func (fa FakeAdapter) Street() string {
	return fake.Street()
}

//StreetAddress returns a random street address
func (fa FakeAdapter) StreetAddress() string {
	return fake.StreetAddress()
}

//UserName returns a random username
func (fa FakeAdapter) UserName() string {
	return fake.UserName()
}

//Day returns a random day
func (fa FakeAdapter) Day() string {
	return strconv.Itoa(fake.Day())
}

//Month returns a random month
func (fa FakeAdapter) Month() string {
	return fake.Month()
}

//Year returns a random year between (1980,2020)
func (fa FakeAdapter) Year() string {
	return strconv.Itoa(fake.Year(1980, 2020))
}

//MonthShort returns a random month (Short Version)
func (fa FakeAdapter) MonthShort() string {
	return fake.MonthShort()
}

//WeekDay returns a random day of week
func (fa FakeAdapter) WeekDay() string {
	return fake.WeekDay()
}

//Word returns a random word
func (fa FakeAdapter) Word() string {
	return fake.Word()
}

//Words returns from 1 to 5 random words
func (fa FakeAdapter) Words() string {
	return fake.Words()
}

//WordsN returns n random words
func (fa FakeAdapter) WordsN(n int) string {
	return fake.WordsN(n)
}

//Zip returns a random zip
func (fa FakeAdapter) Zip() string {
	return fake.Zip()
}

//Number returns a random positive number less than or equal to n
func (fa FakeAdapter) Int(n int) string {
	return strconv.Itoa(rand.Intn(n + 1))
}

//Float returns a random positive floating point number less than n
func (fa FakeAdapter) Float(n int) string {
	f := float64(n)
	value := rand.Float64() * f
	return strconv.FormatFloat(value, 'f', 4, 64)
}

//UUID generates a unique id
func (fa FakeAdapter) UUID() string {
	u := uuid.NewV4()
	return u.String()
}
<|endoftext|>