<commit_before>package main

import (
	"bufio"
	"crypto/tls"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"net/url"
	"os"
	"sort"
	"strconv"
	"strings"
	"time"

	"github.com/fatih/color"
)

const (
	HTTPSTemplate = `` +
		`  DNS Lookup   TCP Connection   TLS Handshake   Server Processing   Content Transfer` + "\n" +
		`[%s  |     %s  |    %s  |        %s  |       %s  ]` + "\n" +
		`            |                |               |                   |                  |` + "\n" +
		`   namelookup:%s      |               |                   |                  |` + "\n" +
		`                       connect:%s     |                   |                  |` + "\n" +
		`                                   pretransfer:%s         |                  |` + "\n" +
		`                                                     starttransfer:%s        |` + "\n" +
		`                                                                                total:%s` + "\n"

	HTTPTemplate = `` +
		`   DNS Lookup   TCP Connection   Server Processing   Content Transfer` + "\n" +
		`[ %s  |     %s  |        %s  |       %s  ]` + "\n" +
		`             |                |                   |                  |` + "\n" +
		`    namelookup:%s      |                   |                  |` + "\n" +
		`                        connect:%s         |                  |` + "\n" +
		`                                      starttransfer:%s        |` + "\n" +
		`                                                                 total:%s` + "\n"
)

var (
	requestBody io.Reader

	grayscale = func(code int) func(string) string {
		if color.NoColor {
			return func(s string) string { return s }
		}
		return func(s string) string {
			return fmt.Sprintf("\x1b[;38;5;%dm%s\x1b[0m", code+232, s)
		}
	}

	// Command line flags.
	httpMethod      string
	postBody        string
	followRedirects bool
	onlyHeader      bool
	insecure        bool

	usage = fmt.Sprintf("usage: %s URL", os.Args[0])
)

func init() {
	flag.StringVar(&httpMethod, "X", "GET", "HTTP method to use")
	flag.StringVar(&postBody, "d", "", "the body of a POST or PUT request")
	flag.BoolVar(&followRedirects, "L", false, "follow 30x redirects")
	flag.BoolVar(&onlyHeader, "I", false, "don't read body of request")
	flag.BoolVar(&insecure, "k", false, "allow insecure SSL connections")

	flag.Usage = func() {
		os.Stderr.WriteString(usage + "\n")
		flag.PrintDefaults()
		os.Exit(2)
	}
}

func main() {
	flag.Parse()

	args := flag.Args()
	if len(args) != 1 {
		log.Fatalf(usage)
	}

	uri := schemify(args[0])

	url, err := url.Parse(uri)
	if err != nil {
		log.Fatalf("could not parse url %q: %v", uri, err)
	}

	visit(url)
}

func schemify(uri string) string {
	if strings.Contains(uri, "://") != true {
		if strings.HasSuffix(uri, ":80") != true {
			return "https://" + uri
		}
		return "http://" + uri
	}
	return uri
}

func getHostPort(URLScheme, URLHost string) (string, string, string) {
	scheme := URLScheme

	// No hostname, just a port
	if strings.HasPrefix(URLHost, ":") {
		URLHost = "localhost" + URLHost
	}

	host, port, err := net.SplitHostPort(URLHost)
	if err != nil {
		host = URLHost
	}

	switch scheme {
	case "https":
		if port == "" {
			port = "443"
		}
	case "http":
		if port == "" {
			port = "80"
		}
	default:
		log.Fatalf("unsupported url scheme %q", scheme)
	}

	return scheme, host, port
}

// visit visits a url and times the interaction.
// If the response is a 30x, visit follows the redirect.
func visit(url *url.URL) {

	scheme, host, port := getHostPort(url.Scheme, url.Host)

	t0 := time.Now() // before dns resolution
	raddr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%s", host, port))
	if err != nil {
		log.Fatalf("unable to resolve host: %v", err)
	}

	var conn net.Conn
	t1 := time.Now() // after dns resolution, before connect
	conn, err = net.DialTCP("tcp", nil, raddr)
	if err != nil {
		log.Fatalf("unable to connect to host %v; %v", raddr, err)
	}
	fmt.Printf("\n%s%s\n", color.GreenString("Connected to "), color.CyanString(raddr.String()))

	var t2 time.Time // after connect, before TLS handshake
	if scheme == "https" {
		t2 = time.Now()
		c := tls.Client(conn, &tls.Config{
			ServerName:         host,
			InsecureSkipVerify: insecure,
		})
		if err := c.Handshake(); err != nil {

			log.Fatalf("unable to negotiate TLS handshake: %v", err)
		}
		conn = c
	}

	t3 := time.Now() // after connect, before request
	if onlyHeader {
		httpMethod = "HEAD"
	}
	if (httpMethod == "POST" || httpMethod == "PUT") && postBody == "" {
		log.Fatal("must supply post body using -d when POST or PUT is used")
	}
	req, err := http.NewRequest(httpMethod, url.String(), strings.NewReader(postBody))
	if err != nil {
		log.Fatalf("unable to create request: %v", err)
	}

	if err = req.Write(conn); err != nil {
		log.Fatalf("failed to write request: %v", err)
	}

	t4 := time.Now() // after request, before read response
	resp, err := http.ReadResponse(bufio.NewReader(conn), req)
	if err != nil {
		log.Fatalf("failed to read response: %v", err)
	}

	t5 := time.Now() // after read response
	bodyMsg := readResponseBody(resp)
	resp.Body.Close()
	t6 := time.Now() // after read body

	// print status line and headers
	fmt.Printf("\n%s%s%s\n", color.GreenString("HTTP"), grayscale(14)("/"), color.CyanString("%d.%d %s", resp.ProtoMajor, resp.ProtoMinor, resp.Status))

	names := make([]string, 0, len(resp.Header))
	for k := range resp.Header {
		names = append(names, k)
	}
	sort.Sort(headers(names))
	for _, k := range names {
		fmt.Println(grayscale(14)(k+":"), color.CyanString(strings.Join(resp.Header[k], ",")))
	}

	if bodyMsg != "" {
		fmt.Printf("\n%s\n", bodyMsg)
	}

	fmta := func(d time.Duration) string {
		return color.CyanString("%7dms", int(d/time.Millisecond))
	}

	fmtb := func(d time.Duration) string {
		return color.CyanString("%-9s", strconv.Itoa(int(d/time.Millisecond))+"ms")
	}

	colorize := func(s string) string {
		v := strings.Split(s, "\n")
		v[0] = grayscale(16)(v[0])
		return strings.Join(v, "\n")
	}

	fmt.Println()

	switch scheme {
	case "https":
		fmt.Printf(colorize(HTTPSTemplate),
			fmta(t1.Sub(t0)), // dns lookup
			fmta(t2.Sub(t1)), // tcp connection
			fmta(t3.Sub(t2)), // tls handshake
			fmta(t5.Sub(t4)), // server processing
			fmta(t6.Sub(t5)), // content transfer
			fmtb(t1.Sub(t0)), // namelookup
			fmtb(t2.Sub(t0)), // connect
			fmtb(t3.Sub(t0)), // pretransfer
			fmtb(t5.Sub(t0)), // starttransfer
			fmtb(t6.Sub(t0)), // total
		)
	case "http":
		fmt.Printf(colorize(HTTPTemplate),
			fmta(t1.Sub(t0)), // dns lookup
			fmta(t3.Sub(t1)), // tcp connection
			fmta(t5.Sub(t3)), // server processing
			fmta(t6.Sub(t5)), // content transfer
			fmtb(t1.Sub(t0)), // namelookup
			fmtb(t3.Sub(t0)), // connect
			fmtb(t5.Sub(t0)), // starttransfer
			fmtb(t6.Sub(t0)), // total
		)
	}

	if followRedirects && resp.StatusCode > 299 && resp.StatusCode < 400 {
		loc, err := resp.Location()
		if err != nil {
			if err == http.ErrNoLocation {
				// 30x but no Location to follow, give up.
				return
			}
			log.Fatalf("unable to follow redirect: %v", err)
		}
		visit(loc)
	}
}

// readResponseBody consumes the body of the response.
// readResponseBody returns an informational message about the
// disposition of the response body's contents.
func readResponseBody(resp *http.Response) string {
	// TODO(dfc) do not process body if status code is in the 30x range

	// TODO(dfc) if we issued a HEAD request, there is no body to process.

	if _, err := io.Copy(ioutil.Discard, resp.Body); err != nil {
		log.Fatalf("failed to read response body: %v", err)
	}

	return color.CyanString("Body discarded")
}

type headers []string

func (h headers) Len() int      { return len(h) }
func (h headers) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h headers) Less(i, j int) bool {
	a, b := h[i], h[j]

	// server always sorts at the top
	if a == "Server" {
		return true
	}
	if b == "Server" {
		return false
	}

	endtoend := func(n string) bool {
		// https://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1
		switch n {
		case "Connection",
			"Keep-Alive",
			"Proxy-Authenticate",
			"Proxy-Authorization",
			"TE",
			"Trailers",
			"Transfer-Encoding",
			"Upgrade":
			return false
		default:
			return true
		}
	}

	x, y := endtoend(a), endtoend(b)
	if x == y {
		// both are of the same class
		return a < b
	}
	return x
}
<commit_msg>getHostPort takes *url.URL rather than properties thereof<commit_after>package main

import (
	"bufio"
	"crypto/tls"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"net/url"
	"os"
	"sort"
	"strconv"
	"strings"
	"time"

	"github.com/fatih/color"
)

const (
	HTTPSTemplate = `` +
		`  DNS Lookup   TCP Connection   TLS Handshake   Server Processing   Content Transfer` + "\n" +
		`[%s  |     %s  |    %s  |        %s  |       %s  ]` + "\n" +
		`            |                |               |                   |                  |` + "\n" +
		`   namelookup:%s      |               |                   |                  |` + "\n" +
		`                       connect:%s     |                   |                  |` + "\n" +
		`                                   pretransfer:%s         |                  |` + "\n" +
		`                                                     starttransfer:%s        |` + "\n" +
		`                                                                                total:%s` + "\n"

	HTTPTemplate = `` +
		`   DNS Lookup   TCP Connection   Server Processing   Content Transfer` + "\n" +
		`[ %s  |     %s  |        %s  |       %s  ]` + "\n" +
		`             |                |                   |                  |` + "\n" +
		`    namelookup:%s      |                   |                  |` + "\n" +
		`                        connect:%s         |                  |` + "\n" +
		`                                      starttransfer:%s        |` + "\n" +
		`                                                                 total:%s` + "\n"
)

var (
	requestBody io.Reader

	grayscale = func(code int) func(string) string {
		if color.NoColor {
			return func(s string) string { return s }
		}
		return func(s string) string {
			return fmt.Sprintf("\x1b[;38;5;%dm%s\x1b[0m", code+232, s)
		}
	}

	// Command line flags.
	httpMethod      string
	postBody        string
	followRedirects bool
	onlyHeader      bool
	insecure        bool

	usage = fmt.Sprintf("usage: %s URL", os.Args[0])
)

func init() {
	flag.StringVar(&httpMethod, "X", "GET", "HTTP method to use")
	flag.StringVar(&postBody, "d", "", "the body of a POST or PUT request")
	flag.BoolVar(&followRedirects, "L", false, "follow 30x redirects")
	flag.BoolVar(&onlyHeader, "I", false, "don't read body of request")
	flag.BoolVar(&insecure, "k", false, "allow insecure SSL connections")

	flag.Usage = func() {
		os.Stderr.WriteString(usage + "\n")
		flag.PrintDefaults()
		os.Exit(2)
	}
}

func main() {
	flag.Parse()

	args := flag.Args()
	if len(args) != 1 {
		log.Fatalf(usage)
	}

	uri := schemify(args[0])

	url, err := url.Parse(uri)
	if err != nil {
		log.Fatalf("could not parse url %q: %v", uri, err)
	}

	visit(url)
}

func schemify(uri string) string {
	if strings.Contains(uri, "://") != true {
		if strings.HasSuffix(uri, ":80") != true {
			return "https://" + uri
		}
		return "http://" + uri
	}
	return uri
}

func getHostPort(url *url.URL) (string, string, string) {
	scheme := url.Scheme
	URLHost := url.Host

	// No hostname, just a port
	if strings.HasPrefix(URLHost, ":") {
		URLHost = "localhost" + URLHost
	}

	host, port, err := net.SplitHostPort(URLHost)
	if err != nil {
		host = URLHost
	}

	switch scheme {
	case "https":
		if port == "" {
			port = "443"
		}
	case "http":
		if port == "" {
			port = "80"
		}
	default:
		log.Fatalf("unsupported url scheme %q", scheme)
	}

	return scheme, host, port
}

// visit visits a url and times the interaction.
// If the response is a 30x, visit follows the redirect.
func visit(url *url.URL) {

	scheme, host, port := getHostPort(url)

	t0 := time.Now() // before dns resolution
	raddr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%s", host, port))
	if err != nil {
		log.Fatalf("unable to resolve host: %v", err)
	}

	var conn net.Conn
	t1 := time.Now() // after dns resolution, before connect
	conn, err = net.DialTCP("tcp", nil, raddr)
	if err != nil {
		log.Fatalf("unable to connect to host %v; %v", raddr, err)
	}
	fmt.Printf("\n%s%s\n", color.GreenString("Connected to "), color.CyanString(raddr.String()))

	var t2 time.Time // after connect, before TLS handshake
	if scheme == "https" {
		t2 = time.Now()
		c := tls.Client(conn, &tls.Config{
			ServerName:         host,
			InsecureSkipVerify: insecure,
		})
		if err := c.Handshake(); err != nil {
			log.Fatalf("unable to negotiate TLS handshake: %v", err)
		}
		conn = c
	}

	t3 := time.Now() // after connect, before request
	if onlyHeader {
		httpMethod = "HEAD"
	}
	if (httpMethod == "POST" || httpMethod == "PUT") && postBody == "" {
		log.Fatal("must supply post body using -d when POST or PUT is used")
	}
	req, err := http.NewRequest(httpMethod, url.String(), strings.NewReader(postBody))
	if err != nil {
		log.Fatalf("unable to create request: %v", err)
	}

	if err := req.Write(conn); err != nil {
		log.Fatalf("failed to write request: %v", err)
	}

	t4 := time.Now() // after request, before read response
	resp, err := http.ReadResponse(bufio.NewReader(conn), req)
	if err != nil {
		log.Fatalf("failed to read response: %v", err)
	}

	t5 := time.Now() // after read response
	bodyMsg := readResponseBody(resp)
	resp.Body.Close()
	t6 := time.Now() // after read body

	// print status line and headers
	fmt.Printf("\n%s%s%s\n", color.GreenString("HTTP"), grayscale(14)("/"), color.CyanString("%d.%d %s", resp.ProtoMajor, resp.ProtoMinor, resp.Status))

	names := make([]string, 0, len(resp.Header))
	for k := range resp.Header {
		names = append(names, k)
	}
	sort.Sort(headers(names))
	for _, k := range names {
		fmt.Println(grayscale(14)(k+":"), color.CyanString(strings.Join(resp.Header[k], ",")))
	}

	if bodyMsg != "" {
		fmt.Printf("\n%s\n", bodyMsg)
	}

	fmta := func(d time.Duration) string {
		return color.CyanString("%7dms", int(d/time.Millisecond))
	}

	fmtb := func(d time.Duration) string {
		return color.CyanString("%-9s", strconv.Itoa(int(d/time.Millisecond))+"ms")
	}

	colorize := func(s string) string {
		v := strings.Split(s, "\n")
		v[0] = grayscale(16)(v[0])
		return strings.Join(v, "\n")
	}

	fmt.Println()

	switch scheme {
	case "https":
		fmt.Printf(colorize(HTTPSTemplate),
			fmta(t1.Sub(t0)), // dns lookup
			fmta(t2.Sub(t1)), // tcp connection
			fmta(t3.Sub(t2)), // tls handshake
			fmta(t5.Sub(t4)), // server processing
			fmta(t6.Sub(t5)), // content transfer
			fmtb(t1.Sub(t0)), // namelookup
			fmtb(t2.Sub(t0)), // connect
			fmtb(t3.Sub(t0)), // pretransfer
			fmtb(t5.Sub(t0)), // starttransfer
			fmtb(t6.Sub(t0)), // total
		)
	case "http":
		fmt.Printf(colorize(HTTPTemplate),
			fmta(t1.Sub(t0)), // dns lookup
			fmta(t3.Sub(t1)), // tcp connection
			fmta(t5.Sub(t3)), // server processing
			fmta(t6.Sub(t5)), // content transfer
			fmtb(t1.Sub(t0)), // namelookup
			fmtb(t3.Sub(t0)), // connect
			fmtb(t5.Sub(t0)), // starttransfer
			fmtb(t6.Sub(t0)), // total
		)
	}

	if followRedirects && resp.StatusCode > 299 && resp.StatusCode < 400 {
		loc, err := resp.Location()
		if err != nil {
			if err == http.ErrNoLocation {
				// 30x but no Location to follow, give up.
				return
			}
			log.Fatalf("unable to follow redirect: %v", err)
		}
		visit(loc)
	}
}

// readResponseBody consumes the body of the response.
// readResponseBody returns an informational message about the
// disposition of the response body's contents.
func readResponseBody(resp *http.Response) string {
	// TODO(dfc) do not process body if status code is in the 30x range

	// TODO(dfc) if we issued a HEAD request, there is no body to process.

	if _, err := io.Copy(ioutil.Discard, resp.Body); err != nil {
		log.Fatalf("failed to read response body: %v", err)
	}

	return color.CyanString("Body discarded")
}

type headers []string

func (h headers) Len() int      { return len(h) }
func (h headers) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h headers) Less(i, j int) bool {
	a, b := h[i], h[j]

	// server always sorts at the top
	if a == "Server" {
		return true
	}
	if b == "Server" {
		return false
	}

	endtoend := func(n string) bool {
		// https://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1
		switch n {
		case "Connection",
			"Keep-Alive",
			"Proxy-Authenticate",
			"Proxy-Authorization",
			"TE",
			"Trailers",
			"Transfer-Encoding",
			"Upgrade":
			return false
		default:
			return true
		}
	}

	x, y := endtoend(a), endtoend(b)
	if x == y {
		// both are of the same class
		return a < b
	}
	return x
}
<|endoftext|>


<commit_before>package main

import (
  "fmt"
  "time"
  "os"
  "bufio"
  "log"
  "regexp"
  "errors"
  "math/rand"
)

type Posicao struct {
  linha  int
  coluna int
}

type PacGo struct {
  posicao Posicao
  figura  string // emoji
}

type Fantasma struct {
  posicao Posicao
  figura  string // emoji
}

type Labirinto struct {
  largura int
  altura  int
  mapa    []string
}

type Movimento int

const (
        Cima = iota
        Baixo
        Esquerda
        Direita
        Nenhum
        Sai
)

func (labirinto *Labirinto) imprime() {
  fmt.Println(labirinto.largura)
  fmt.Println(labirinto.altura)

  for _, linha := range labirinto.mapa {
    fmt.Print(linha)
    fmt.Print("\r\n")
  }
}

var labirinto *Labirinto
var pacgo     *PacGo
var lista_de_fantasmas []*Fantasma
var mapaSinais map[int]string

func construirLabirinto(nomeArquivo string) (*Labirinto, *PacGo, []*Fantasma, error) {

  var ErrMapNotFound = errors.New("Não conseguiu ler o arquivo do mapa")

  var arquivo string
  if nomeArquivo == "" {
    arquivo = "./data/mapa.txt"
  } else {
    arquivo = nomeArquivo
  }

  if file, err := os.Open(arquivo); err == nil {

    // fecha depois de ler o arquivo
    defer file.Close()

    // inicializa o mapa vazio
    var pacgo *PacGo//{ posicao: Posicao{2, 2}, figura: 'G'}
    fantasmas := []*Fantasma{}
    mapa := []string{}

    r, _ := regexp.Compile("[^ #]")

    // cria um leitor para ler linha a linha o arquivo
    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
      linha := scanner.Text()

      for indice , caracter := range linha {
        switch caracter {
          case 'F': {
            fantasma := &Fantasma{ posicao: Posicao{len(mapa), indice}, figura: "F"}
            fantasmas = append(fantasmas, fantasma)
          }
          //fmt.Println(caracter)
          case 'G': pacgo = &PacGo{ posicao: Posicao{len(mapa), indice}, figura: "G"}
        }
      }

      linha = r.ReplaceAllString(linha, " ")
      mapa = append(mapa, linha)
    }

    // verifica se teve erro o leitor
    if err = scanner.Err(); err != nil {
      log.Fatal(err)
      return nil, nil, nil, ErrMapNotFound
    }

    l := &Labirinto{largura: len(mapa[0]), altura: len(mapa), mapa : mapa}
    return l, pacgo, fantasmas, nil

  } else {
    log.Fatal(err)
    return nil, nil, nil, ErrMapNotFound
  }
}

func atualizarLabirinto() {
  limpaTela()

  for _, linha := range labirinto.mapa {
      fmt.Println(linha)
  }

  // Atualiza PacGo
  moveCursor(pacgo.posicao)
  fmt.Printf("%s", pacgo.figura)

  // Atualiza fantasmas
  for _, fantasma := range lista_de_fantasmas {
    moveCursor(fantasma.posicao)
    fmt.Printf("%s", fantasma.figura)
  }

  // Move o cursor para fora do labirinto
  moveCursor(Posicao{labirinto.altura + 2, 1})
}

func detectarColisao() bool {
  for _, fantasma := range lista_de_fantasmas {
    if fantasma.posicao == pacgo.posicao {
      return true
    }
  }
  return false
}

func moverPacGo(m Movimento) {

  var valorDaPosicaoAtualDaPacgo = labirinto.mapa[pacgo.posicao.linha][pacgo.posicao.coluna]
  var linhaAtualDaPacgo = pacgo.posicao.linha
  var colunaAtualDaPacgo = pacgo.posicao.coluna

  switch m {
  case Cima:
             if linhaAtualDaPacgo == 0{
                 if valorDaPosicaoAtualDaPacgo == ' '{
                   pacgo.posicao.linha = labirinto.altura - 1
                 }
             }else{
               var posicaoAcimaDaPacgo = labirinto.mapa[pacgo.posicao.linha - 1][pacgo.posicao.coluna]
               if posicaoAcimaDaPacgo != '#'{
                 pacgo.posicao.linha = pacgo.posicao.linha - 1
               }
             }
  case Baixo:
             if linhaAtualDaPacgo == labirinto.altura - 1{
                 if valorDaPosicaoAtualDaPacgo == ' '{
                   pacgo.posicao.linha = 0
                 }
             }else{
               var posicaoAbaixoDaPacgo = labirinto.mapa[pacgo.posicao.linha + 1][pacgo.posicao.coluna]
               if posicaoAbaixoDaPacgo != '#'{
                 pacgo.posicao.linha = pacgo.posicao.linha + 1
               }
             }
  case Direita:
             if colunaAtualDaPacgo == labirinto.largura-1{
                 if valorDaPosicaoAtualDaPacgo == ' '{
                   pacgo.posicao.coluna = 0
                 }
             }else{
               var posicaoDireitaDaPacgo = labirinto.mapa[pacgo.posicao.linha][pacgo.posicao.coluna + 1]
               if posicaoDireitaDaPacgo != '#'{
                 pacgo.posicao.coluna = pacgo.posicao.coluna + 1
               }
             }
  case Esquerda:
    if colunaAtualDaPacgo == 0{
      if valorDaPosicaoAtualDaPacgo == ' '{
        pacgo.posicao.coluna = labirinto.largura - 1
      }
    }else{
      var posicaoEsquerdaDaPacgo = labirinto.mapa[pacgo.posicao.linha][pacgo.posicao.coluna - 1]
      if posicaoEsquerdaDaPacgo != '#'{
        pacgo.posicao.coluna = pacgo.posicao.coluna - 1
      }
    }
  }
}

func random(min, max int) int {
    return rand.Intn(max - min) + min
}

func move(fantasma *Fantasma, valorDaPosicaoAtualDoFantasma byte, linhaAtualDoFantasma int, colunaAtualDoFantasma int){

  var direcao = random(0, 4)
  var sinal = mapaSinais[direcao]
  //fmt.Println(sinal)
  switch sinal {
  case "Cima":
              if linhaAtualDoFantasma == 0{
                if valorDaPosicaoAtualDoFantasma == ' '{
                   fantasma.posicao.linha = labirinto.altura - 1
                 }
             }else{
               var posicaoAcimaDoFantasma = labirinto.mapa[fantasma.posicao.linha - 1][fantasma.posicao.coluna]
               if posicaoAcimaDoFantasma != '#'{
                 fantasma.posicao.linha = fantasma.posicao.linha - 1
               }
             }
  case "Baixo":
              if linhaAtualDoFantasma == labirinto.altura - 1{
                 if valorDaPosicaoAtualDoFantasma == ' '{
                   fantasma.posicao.linha = 0
                 }
              }else{
                var posicaoAbaixoDoFantasma = labirinto.mapa[fantasma.posicao.linha + 1][fantasma.posicao.coluna]
                if posicaoAbaixoDoFantasma != '#'{
                  fantasma.posicao.linha = fantasma.posicao.linha + 1
                }
              }
  case "Direita":
                if colunaAtualDoFantasma == labirinto.largura-1{
                  if valorDaPosicaoAtualDoFantasma == ' '{
                    fantasma.posicao.coluna = 0
                  }
                }else{
                  var posicaoDireitaDofantasma = labirinto.mapa[fantasma.posicao.linha][fantasma.posicao.coluna + 1]
                  if posicaoDireitaDofantasma != '#'{
                    fantasma.posicao.coluna = fantasma.posicao.coluna + 1
                  }
                }
  case "Esquerda":
                 if colunaAtualDoFantasma == 0{
                   if valorDaPosicaoAtualDoFantasma == ' '{
                     fantasma.posicao.coluna = labirinto.largura - 1
                   }
                 }else{
                   var posicaoEsquerdaDoFantasma = labirinto.mapa[fantasma.posicao.linha][fantasma.posicao.coluna - 1]
                   if posicaoEsquerdaDoFantasma != '#'{
                     fantasma.posicao.coluna = fantasma.posicao.coluna - 1
                   }
                 }
  }
}

func moverFantasmas() {

  for {
    for i := 0; i < len(lista_de_fantasmas); i++{
        var valorDaPosicaoAtualDoFantasma = labirinto.mapa[lista_de_fantasmas[i].posicao.linha][lista_de_fantasmas[i].posicao.coluna]
        var linhaAtualDoFantasma = lista_de_fantasmas[i].posicao.linha
        var colunaAtualDoFantasma = lista_de_fantasmas[i].posicao.coluna
        //fmt.Println(valorDaPosicaoAtualDoFantasma, linhaAtualDoFantasma, colunaAtualDoFantasma)
        move(lista_de_fantasmas[i], valorDaPosicaoAtualDoFantasma, linhaAtualDoFantasma, colunaAtualDoFantasma)
    }
    dorme(200)
  }
}

func dorme(mili time.Duration) {
  time.Sleep(time.Millisecond * mili)
}

func entradaDoUsuario(canal chan Movimento) {
  array := make([]byte, 10)

  for {
    lido, _ := os.Stdin.Read(array)

    if lido == 1 && array[0] == 0x1b {
      canal <- Sai;
    } else if lido == 3 {
      if array[0] == 0x1b && array[1] == '[' {
        switch array[2] {
        case 'A': canal <- Cima
        case 'B': canal <- Baixo
        case 'C': canal <- Direita
        case 'D': canal <- Esquerda
        }
      }
    }
  }
}

func terminarJogo() {
  // pacgo morreu :(
  moveCursor( Posicao{labirinto.altura + 2, 0} )
  fmt.Println("Fim de jogo! Os fantasmas venceram... \xF0\x9F\x98\xAD")
}

func main() {
  inicializa()
  defer finaliza()

  mapaSinais = make(map[int]string)
  mapaSinais[0] = "Cima"
  mapaSinais[1] = "Baixo"
  mapaSinais[2] = "Direita"
  mapaSinais[3] = "Esquerda"

  args    := os.Args[1:]
  var arquivo string
  if len(args) >= 1 {
    arquivo = args[0]
  } else {
    arquivo = ""
  }

  labirinto, pacgo, lista_de_fantasmas, _ = construirLabirinto(arquivo)

  pacgo.figura = "\xF0\x9F\x98\x83"

  for _, fantasma := range lista_de_fantasmas {
    fantasma.figura = "\xF0\x9F\x91\xBB"
  }

  canal := make(chan Movimento, 10)

  go entradaDoUsuario(canal)
  go moverFantasmas()

  var tecla Movimento
  for  {
    atualizarLabirinto()

    select {
    case tecla = <-canal:
        moverPacGo(tecla)
    default:
    }
    if tecla == Sai { break }

    if detectarColisao() {
      terminarJogo()
      break;
    }

    dorme(100)
  }
}
<commit_msg>code cleanup<commit_after>package main

import (
  "fmt"
  "time"
  "os"
  "bufio"
  "log"
  "regexp"
  "errors"
  "math/rand"
)

type Posicao struct {
  linha  int
  coluna int
}

type PacGo struct {
  posicao Posicao
  figura  string // emoji
}

type Fantasma struct {
  posicao Posicao
  figura  string // emoji
}

type Labirinto struct {
  largura int
  altura  int
  mapa    []string
}

type Movimento int

const (
        Cima = iota
        Baixo
        Esquerda
        Direita
        Nenhum
        Sai
)

var labirinto *Labirinto
var pacgo     *PacGo
var lista_de_fantasmas []*Fantasma
var mapaSinais map[int]string

func construirLabirinto(nomeArquivo string) (*Labirinto, *PacGo, []*Fantasma, error) {

  var ErrMapNotFound = errors.New("Não conseguiu ler o arquivo do mapa")

  var arquivo string
  if nomeArquivo == "" {
    arquivo = "./data/mapa.txt"
  } else {
    arquivo = nomeArquivo
  }

  if file, err := os.Open(arquivo); err == nil {

    // fecha depois de ler o arquivo
    defer file.Close()

    // inicializa o mapa vazio
    var pacgo *PacGo
    fantasmas := []*Fantasma{}
    mapa := []string{}

    r, _ := regexp.Compile("[^ #]")

    // cria um leitor para ler linha a linha o arquivo
    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
      linha := scanner.Text()

      for indice , caracter := range linha {
        switch caracter {
          case 'F': {
            fantasma := &Fantasma{ posicao: Posicao{len(mapa), indice}, figura: "\xF0\x9F\x91\xBB"}
            fantasmas = append(fantasmas, fantasma)
          }
          //fmt.Println(caracter)
          case 'G': pacgo = &PacGo{ posicao: Posicao{len(mapa), indice}, figura: "\xF0\x9F\x98\x83"}
        }
      }

      linha = r.ReplaceAllString(linha, " ")
      mapa = append(mapa, linha)
    }

    // verifica se teve erro o leitor
    if err = scanner.Err(); err != nil {
      log.Fatal(err)
      return nil, nil, nil, ErrMapNotFound
    }

    l := &Labirinto{largura: len(mapa[0]), altura: len(mapa), mapa : mapa}
    return l, pacgo, fantasmas, nil

  } else {
    log.Fatal(err)
    return nil, nil, nil, ErrMapNotFound
  }
}

func atualizarLabirinto() {
  limpaTela()

  for _, linha := range labirinto.mapa {
      fmt.Println(linha)
  }

  // Imprime PacGo
  moveCursor(pacgo.posicao)
  fmt.Printf("%s", pacgo.figura)

  // Imprime fantasmas
  for _, fantasma := range lista_de_fantasmas {
    moveCursor(fantasma.posicao)
    fmt.Printf("%s", fantasma.figura)
  }

  // Move o cursor para fora do labirinto
  moveCursor(Posicao{labirinto.altura + 2, 1})
}

func detectarColisao() bool {
  for _, fantasma := range lista_de_fantasmas {
    if fantasma.posicao == pacgo.posicao {
      return true
    }
  }
  return false
}

func moverPacGo(m Movimento) {

  var valorDaPosicaoAtualDaPacgo = labirinto.mapa[pacgo.posicao.linha][pacgo.posicao.coluna]
  var linhaAtualDaPacgo = pacgo.posicao.linha
  var colunaAtualDaPacgo = pacgo.posicao.coluna

  switch m {
  case Cima:
             if linhaAtualDaPacgo == 0{
                 if valorDaPosicaoAtualDaPacgo == ' '{
                   pacgo.posicao.linha = labirinto.altura - 1
                 }
             }else{
               var posicaoAcimaDaPacgo = labirinto.mapa[pacgo.posicao.linha - 1][pacgo.posicao.coluna]
               if posicaoAcimaDaPacgo != '#'{
                 pacgo.posicao.linha = pacgo.posicao.linha - 1
               }
             }
  case Baixo:
             if linhaAtualDaPacgo == labirinto.altura - 1{
                 if valorDaPosicaoAtualDaPacgo == ' '{
                   pacgo.posicao.linha = 0
                 }
             }else{
               var posicaoAbaixoDaPacgo = labirinto.mapa[pacgo.posicao.linha + 1][pacgo.posicao.coluna]
               if posicaoAbaixoDaPacgo != '#'{
                 pacgo.posicao.linha = pacgo.posicao.linha + 1
               }
             }
  case Direita:
             if colunaAtualDaPacgo == labirinto.largura-1{
                 if valorDaPosicaoAtualDaPacgo == ' '{
                   pacgo.posicao.coluna = 0
                 }
             }else{
               var posicaoDireitaDaPacgo = labirinto.mapa[pacgo.posicao.linha][pacgo.posicao.coluna + 1]
               if posicaoDireitaDaPacgo != '#'{
                 pacgo.posicao.coluna = pacgo.posicao.coluna + 1
               }
             }
  case Esquerda:
    if colunaAtualDaPacgo == 0{
      if valorDaPosicaoAtualDaPacgo == ' '{
        pacgo.posicao.coluna = labirinto.largura - 1
      }
    }else{
      var posicaoEsquerdaDaPacgo = labirinto.mapa[pacgo.posicao.linha][pacgo.posicao.coluna - 1]
      if posicaoEsquerdaDaPacgo != '#'{
        pacgo.posicao.coluna = pacgo.posicao.coluna - 1
      }
    }
  }
}

func random(min, max int) int {
    return rand.Intn(max - min) + min
}

func move(fantasma *Fantasma, valorDaPosicaoAtualDoFantasma byte, linhaAtualDoFantasma int, colunaAtualDoFantasma int){

  var direcao = random(0, 4)
  var sinal = mapaSinais[direcao]
  //fmt.Println(sinal)
  switch sinal {
  case "Cima":
              if linhaAtualDoFantasma == 0{
                if valorDaPosicaoAtualDoFantasma == ' '{
                   fantasma.posicao.linha = labirinto.altura - 1
                 }
             }else{
               var posicaoAcimaDoFantasma = labirinto.mapa[fantasma.posicao.linha - 1][fantasma.posicao.coluna]
               if posicaoAcimaDoFantasma != '#'{
                 fantasma.posicao.linha = fantasma.posicao.linha - 1
               }
             }
  case "Baixo":
              if linhaAtualDoFantasma == labirinto.altura - 1{
                 if valorDaPosicaoAtualDoFantasma == ' '{
                   fantasma.posicao.linha = 0
                 }
              }else{
                var posicaoAbaixoDoFantasma = labirinto.mapa[fantasma.posicao.linha + 1][fantasma.posicao.coluna]
                if posicaoAbaixoDoFantasma != '#'{
                  fantasma.posicao.linha = fantasma.posicao.linha + 1
                }
              }
  case "Direita":
                if colunaAtualDoFantasma == labirinto.largura-1{
                  if valorDaPosicaoAtualDoFantasma == ' '{
                    fantasma.posicao.coluna = 0
                  }
                }else{
                  var posicaoDireitaDofantasma = labirinto.mapa[fantasma.posicao.linha][fantasma.posicao.coluna + 1]
                  if posicaoDireitaDofantasma != '#'{
                    fantasma.posicao.coluna = fantasma.posicao.coluna + 1
                  }
                }
  case "Esquerda":
                 if colunaAtualDoFantasma == 0{
                   if valorDaPosicaoAtualDoFantasma == ' '{
                     fantasma.posicao.coluna = labirinto.largura - 1
                   }
                 }else{
                   var posicaoEsquerdaDoFantasma = labirinto.mapa[fantasma.posicao.linha][fantasma.posicao.coluna - 1]
                   if posicaoEsquerdaDoFantasma != '#'{
                     fantasma.posicao.coluna = fantasma.posicao.coluna - 1
                   }
                 }
  }
}

func moverFantasmas() {

  for {
    for i := 0; i < len(lista_de_fantasmas); i++{
        var valorDaPosicaoAtualDoFantasma = labirinto.mapa[lista_de_fantasmas[i].posicao.linha][lista_de_fantasmas[i].posicao.coluna]
        var linhaAtualDoFantasma = lista_de_fantasmas[i].posicao.linha
        var colunaAtualDoFantasma = lista_de_fantasmas[i].posicao.coluna
        //fmt.Println(valorDaPosicaoAtualDoFantasma, linhaAtualDoFantasma, colunaAtualDoFantasma)
        move(lista_de_fantasmas[i], valorDaPosicaoAtualDoFantasma, linhaAtualDoFantasma, colunaAtualDoFantasma)
    }
    dorme(200)
  }
}

func dorme(mili time.Duration) {
  time.Sleep(time.Millisecond * mili)
}

func entradaDoUsuario(canal chan<- Movimento) {
  array := make([]byte, 10)

  for {
    lido, _ := os.Stdin.Read(array)

    if lido == 1 && array[0] == 0x1b {
      canal <- Sai;
    } else if lido == 3 {
      if array[0] == 0x1b && array[1] == '[' {
        switch array[2] {
        case 'A': canal <- Cima
        case 'B': canal <- Baixo
        case 'C': canal <- Direita
        case 'D': canal <- Esquerda
        }
      }
    }
  }
}

func terminarJogo() {
  // pacgo morreu :(
  moveCursor( Posicao{labirinto.altura + 2, 0} )
  fmt.Println("Fim de jogo! Os fantasmas venceram... \xF0\x9F\x98\xAD")
}

func main() {
  inicializa()
  defer finaliza()

  mapaSinais = make(map[int]string)
  mapaSinais[0] = "Cima"
  mapaSinais[1] = "Baixo"
  mapaSinais[2] = "Direita"
  mapaSinais[3] = "Esquerda"

  args    := os.Args[1:]
  var arquivo string
  if len(args) >= 1 {
    arquivo = args[0]
  } else {
    arquivo = ""
  }

  labirinto, pacgo, lista_de_fantasmas, _ = construirLabirinto(arquivo)

  canal := make(chan Movimento, 10)

  // Processos assincronos
  go entradaDoUsuario(canal)
  go moverFantasmas()

  var tecla Movimento
  for  {
    atualizarLabirinto()

    // canal não-bloqueador
    select {
    case tecla = <-canal:
        moverPacGo(tecla)
    default:
    }
    if tecla == Sai { break }

    if detectarColisao() {
      terminarJogo()
      break;
    }

    dorme(100)
  }
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"strings"
	"time"
)

var replace = map[string]func(){
	"nnf":       nnf,
	"nnl":       nnl,
	"openFile":  openFile,
	"readFile":  readFile,
	"getURL":    getURL,
	"reqStdin":  reqStdin,
	"goMain":    goMain,
	"tempFile":  tempFile,
	"serveHTTP": serveHTTP,
	"pymain":    pyMain,
	"html5":     html5,
	"now":       now,
	"ubb":       bash,
	"ubp":       python,
	"gomain":    goMain,
	"flagsh":    flagsh,
	"dummyType": dummyType,
}

var update = map[string]func(string){
	"lpf(":  lpf,
	"lpl(":  lpl,
	"fpf(":  fpf,
	"fpl(":  fpl,
	"hfunc": hfunc,
	"ow:":   pyOpenWrite,
	"ul":    ul,
}

func main() {
	stat, err := os.Stdin.Stat()
	if err != nil {
		log.Fatal(err)
	}
	if stat.Mode()&os.ModeCharDevice != 0 {
		log.Fatal("please pipe in some data")
	}

	s := bufio.NewScanner(os.Stdin)
	for s.Scan() {
		line := s.Text()
		trim := strings.TrimSpace(s.Text())

		if f, found := replace[trim]; found {
			f()
			continue
		}

	DONE:
		for pre := range update {
			if strings.HasPrefix(trim, pre) {
				update[pre](trim)
				break DONE
			}

			continue
		}
		fmt.Println(line)
	}

}

func nnf() {
	fmt.Println(`if err != nil{
	log.Fatalf("Failed to do something: %s\n", err)
	}`)
}

func nnl() {
	fmt.Println(`if err != nil{
	log.Printf("Failed to do something: %s\n", err)
	}`)
}

func lpf(line string) {
	fmt.Println(strings.Replace(line, "lpf(", "log.Printf(", 1))
}

func fpf(line string) {
	fmt.Println(strings.Replace(line, "fpf(", "fmt.Printf(", 1))
}

func lpl(line string) {
	fmt.Println(strings.Replace(line, "lpl(", "log.Println(", 1))
}

func fpl(line string) {
	fmt.Println(strings.Replace(line, "fpl(", "fmt.Println(", 1))
}

func goMain() {
	fmt.Println(`package main

import (
    "fmt"
)

func main() {
    fmt.Println("gopher")
}
`)
}

func serveHTTP() {
	fmt.Println(`package main

import (
    "fmt"
	"net/http"
)

func main() {
    http.HandleFunc("/", index)
	http.ListenAndServe(":8080", nil)
}

func index(w http.ResponseWriter, r *http.Request){
	fmt.Fprintf(w, "hello")
}
`)
}

func pyMain() {
	fmt.Println(`#!/usr/bin/env python
"""
You should probably write something here.
"""

from __future__ import unicode_literals

def main():
    """
    Do the thing.
    """
    print "python"

if __name__ == '__main__':
    main()
`)
}

func html5() {
	fmt.Println(`<!DOCTYPE html>

		<meta charset="UTF-8">
		<title>title</title>
		<link rel="stylesheet" href="./css/style.css" type="text/css">
		<meta name="viewport" content="width-device-width, initial-scale=1">

content

`)
}

func hfunc(line string) {
	parts := strings.Split(line, " ")
	name := "index"
	if len(parts) > 1 {
		name = parts[1]
	}
	fmt.Printf(`func %s(w http.ResponseWriter, r *http.Request){
	}`, name)
}

func pyOpenWrite(line string) {
	l := len(line) - len(strings.TrimLeft(line, " "))
	pad := strings.Repeat(" ", l)
	lines := []string{
		`with open("out.txt", "wb") as raw:`,
		`    raw.write("{0}\n".format(msg))`,
	}

	for _, line = range lines {
		fmt.Printf("%s%s\n", pad, line)
	}

}

func ul(line string) {
	trim := strings.TrimSpace(line)
	margin := len(line) - len(strings.TrimLeft(trim, " \t"))
	padding := strings.Repeat(" ", margin)
	fmt.Printf(padding)
	fmt.Println("
")
	for i := 0; i < 3; i++ {
		fmt.Printf(padding)
		fmt.Println("\t
")
		fmt.Printf(padding)
		fmt.Println("\t\tthing")
		fmt.Printf(padding)
		fmt.Println("\t
")
	}
	fmt.Printf(padding)
	fmt.Println("
")

}

func openFile() {
	fmt.Println(`f, err := os.Open(filename)
	if err != nil {
		log.Printf("Unable to open %q: %s\n", filename, err)
	}
	defer f.Close()`)
}

func readFile() {
	fmt.Println(`b, err := ioutil.ReadFile(filename)
	if err != nil {
		log.Printf("Unable to open %q: %s\n", filename, err)
	}`)
}

func getURL() {
	fmt.Println(`resp, err := http.Get(link)
	if err != nil {
		log.Printf("Unable to fetch %q: %s\n", link, err)
		return
	}
	defer resp.Body.Close()
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Printf("Unable to read response from  %q: %s\n", link, err)
		return
	}
	`)
}

func reqStdin() {
	fmt.Println(`stat, err := os.Stdin.Stat()
	if err != nil {
		log.Fatal(err)
	}
	if stat.Mode()&os.ModeCharDevice != 0 {
		log.Fatal("please pipe in some data")
	}`)
}

func tempFile() {
	fmt.Println(`t, err := ioutil.TempFile("", "temp")
if err != nil{
	log.Fatalf("Unable to create temp file: %s\n", err)
}
fmt.Printf("Created temp file %q\n", t.Name())
defer t.Close()
`)
}

func now() {
	fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
}

func bash() {
	fmt.Println("#!/usr/bin/env bash")
}

func python() {
	fmt.Println("#!/usr/bin/env python")
}

func flagsh() {

	fmt.Println(`#!/usr/bin/env bash

flag=$(mktemp)
touch $flag

while true; do
sleep 5
    find . -mmin -1 -name '*.go' 2>>/dev/null | while read file; do
        if [[ "$file" -nt $flag ]]; then
            if [[ "$file" == "$flag" ]]; then
                continue
            fi
            echo "$file was updated"
            touch $flag
        fi
    done
done
`)
}

func dummyType() {
	fmt.Println(`type dummy struct {
    thing string
    size int
    color string
}
`)
}
<commit_msg>Fixed bug: no longer printing original when line is replaced<commit_after>package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"strings"
	"time"
)

var replace = map[string]func(){
	"nnf":       nnf,
	"nnl":       nnl,
	"openFile":  openFile,
	"readFile":  readFile,
	"getURL":    getURL,
	"reqStdin":  reqStdin,
	"goMain":    goMain,
	"tempFile":  tempFile,
	"serveHTTP": serveHTTP,
	"pymain":    pyMain,
	"html5":     html5,
	"now":       now,
	"ubb":       bash,
	"ubp":       python,
	"gomain":    goMain,
	"flagsh":    flagsh,
	"dummyType": dummyType,
}

var update = map[string]func(string){
	"fpl(":  fpl,
	"lpf(":  lpf,
	"lpl(":  lpl,
	"fpf(":  fpf,
	"hfunc": hfunc,
	"ow:":   pyOpenWrite,
	"ul":    ul,
}

func main() {
	stat, err := os.Stdin.Stat()
	if err != nil {
		log.Fatal(err)
	}
	if stat.Mode()&os.ModeCharDevice != 0 {
		log.Fatal("please pipe in some data")
	}

	s := bufio.NewScanner(os.Stdin)

	for s.Scan() {
		line := s.Text()
		trim := strings.TrimSpace(s.Text())

		if f, found := replace[trim]; found {
			f()
			continue
		}

		var replaced bool
	DONE:
		for pre := range update {
			if strings.HasPrefix(trim, pre) {
				update[pre](trim)
				replaced = true
				break DONE
			}

		}
		if !replaced {
			fmt.Println(line)
		}
	}

}

func nnf() {
	fmt.Println(`if err != nil{
	log.Fatalf("Failed to do something: %s\n", err)
	}`)
}

func nnl() {
	fmt.Println(`if err != nil{
	log.Printf("Failed to do something: %s\n", err)
	}`)
}

func lpf(line string) {
	fmt.Println(strings.Replace(line, "lpf(", "log.Printf(", 1))
}

func fpf(line string) {
	fmt.Println(strings.Replace(line, "fpf(", "fmt.Printf(", 1))
}

func lpl(line string) {
	fmt.Println(strings.Replace(line, "lpl(", "log.Println(", 1))
}

func fpl(line string) {
	fmt.Println(strings.Replace(line, "fpl(", "fmt.Println(", 1))
}

func goMain() {
	fmt.Println(`package main

import (
    "fmt"
)

func main() {
    fmt.Println("gopher")
}
`)
}

func serveHTTP() {
	fmt.Println(`package main

import (
    "fmt"
	"net/http"
)

func main() {
    http.HandleFunc("/", index)
	http.ListenAndServe(":8080", nil)
}

func index(w http.ResponseWriter, r *http.Request){
	fmt.Fprintf(w, "hello")
}
`)
}

func pyMain() {
	fmt.Println(`#!/usr/bin/env python
"""
You should probably write something here.
"""

from __future__ import unicode_literals

def main():
    """
    Do the thing.
    """
    print "python"

if __name__ == '__main__':
    main()
`)
}

func html5() {
	fmt.Println(`<!DOCTYPE html>

		<meta charset="UTF-8">
		<title>title</title>
		<link rel="stylesheet" href="./css/style.css" type="text/css">
		<meta name="viewport" content="width-device-width, initial-scale=1">

content

`)
}

func hfunc(line string) {
	parts := strings.Split(line, " ")
	name := "index"
	if len(parts) > 1 {
		name = parts[1]
	}
	fmt.Printf(`func %s(w http.ResponseWriter, r *http.Request){
	}`, name)
}

func pyOpenWrite(line string) {
	l := len(line) - len(strings.TrimLeft(line, " "))
	pad := strings.Repeat(" ", l)
	lines := []string{
		`with open("out.txt", "wb") as raw:`,
		`    raw.write("{0}\n".format(msg))`,
	}

	for _, line = range lines {
		fmt.Printf("%s%s\n", pad, line)
	}

}

func ul(line string) {
	trim := strings.TrimSpace(line)
	margin := len(line) - len(strings.TrimLeft(trim, " \t"))
	padding := strings.Repeat(" ", margin)
	fmt.Printf(padding)
	fmt.Println("
")
	for i := 0; i < 3; i++ {
		fmt.Printf(padding)
		fmt.Println("\t
")
		fmt.Printf(padding)
		fmt.Println("\t\tthing")
		fmt.Printf(padding)
		fmt.Println("\t
")
	}
	fmt.Printf(padding)
	fmt.Println("
")

}

func openFile() {
	fmt.Println(`f, err := os.Open(filename)
	if err != nil {
		log.Printf("Unable to open %q: %s\n", filename, err)
	}
	defer f.Close()`)
}

func readFile() {
	fmt.Println(`b, err := ioutil.ReadFile(filename)
	if err != nil {
		log.Printf("Unable to open %q: %s\n", filename, err)
	}`)
}

func getURL() {
	fmt.Println(`resp, err := http.Get(link)
	if err != nil {
		log.Printf("Unable to fetch %q: %s\n", link, err)
		return
	}
	defer resp.Body.Close()
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Printf("Unable to read response from  %q: %s\n", link, err)
		return
	}
	`)
}

func reqStdin() {
	fmt.Println(`stat, err := os.Stdin.Stat()
	if err != nil {
		log.Fatal(err)
	}
	if stat.Mode()&os.ModeCharDevice != 0 {
		log.Fatal("please pipe in some data")
	}`)
}

func tempFile() {
	fmt.Println(`t, err := ioutil.TempFile("", "temp")
if err != nil{
	log.Fatalf("Unable to create temp file: %s\n", err)
}
fmt.Printf("Created temp file %q\n", t.Name())
defer t.Close()
`)
}

func now() {
	fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
}

func bash() {
	fmt.Println("#!/usr/bin/env bash")
}

func python() {
	fmt.Println("#!/usr/bin/env python")
}

func flagsh() {

	fmt.Println(`#!/usr/bin/env bash

flag=$(mktemp)
touch $flag

while true; do
sleep 5
    find . -mmin -1 -name '*.go' 2>>/dev/null | while read file; do
        if [[ "$file" -nt $flag ]]; then
            if [[ "$file" == "$flag" ]]; then
                continue
            fi
            echo "$file was updated"
            touch $flag
        fi
    done
done
`)
}

func dummyType() {
	fmt.Println(`type dummy struct {
    thing string
    size int
    color string
}
`)
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/gob"
	"flag"
	"fmt"
	"net"
)

type Request struct {
	Key string
}

func readFromDb(key string) string {
	return "Db entry for key " + key
}

func createCacheNode(keyCh <-chan string) <-chan string {
	fmt.Println("Cache node started")
	c := make(chan string)
	go func() {
		for {
			cache := make(map[string]string)
			key := <-keyCh
			res, ok := cache[key]
			if !ok {
				res = readFromDb(key)
				cache[key] = key
			}
			c <- res
		}
	}()
	return c
}

func createListener(port string) {
	go func() {
		addr, _ := net.ResolveUDPAddr("udp", port)
		sock, _ := net.ListenUDP("udp", addr)
		fmt.Printf("network server started at udp%s\n", port)
		for {
			dec := gob.NewDecoder(sock)
			var key string
			dec.Decode(&key)
			fmt.Printf("request for %s\n", key)
		}
	}()
}

var ports = []string{":8000", ":8001", ":8002", ":8003"}

func getValue(key string) string {
	// ask all instances
	for _, port := range ports {
		go func(port string) {
			fmt.Printf("Trying to reach %s\n",port)
			conn, err := net.Dial("udp", port)
			if err != nil {
				fmt.Printf("Couldn't connect to %s\n")
				fmt.Println(err)
				return
			}

			defer conn.Close()

			enc := gob.NewEncoder(conn)

			enc.Encode(key)
		}(port)
	}
	return key
}

func main() {
	// parse CL
	instanceId := flag.Int("id", 0, "instance id")

	flag.Parse()

	// init all
	r := make(chan string)
	createCacheNode(r)
	createListener(ports[*instanceId])

	// main loop
	var input string
	for {
		fmt.Scanln(&input)
		getValue(input)
	}
}
<commit_msg>First half of communication is working. Added UDP broadcast search for data Added TCP data downloading<commit_after>package main

import (
	"encoding/json"
	"encoding/gob"
	"container/list"
	"flag"
	"fmt"
	"net"
	"time"
)

// DTO, command type
const (
	VAL_REQ = 1 + iota  // Request about value presence in cache
	VAL_RESP // Response with info about value
)

// DTO, mixed for req/resp in UDP
type ComPacket struct {
	Type int // Command type
	Id int // Command Id
	Key string // Requested key
	Port string // Response point
}

// DTO, TCP request for data
type DataReqPacket struct {
	Key string
}

// DTO, TCP response with requested data
type DataRespPacket struct {
	Value string // Data
}

// Information about request for data
type Request struct {
	Id int
	Key string
	Callback chan DataOwnerInfo
	Cancel chan int
}

//Information about node, which owns requested data
type DataOwnerInfo struct {
	Id int
	Addr string
}

// read data from database
func readFromDb(key string) string {
	return "Db entry for key " + key
}

// Here is cache (hashmap)
func createCacheNode() (chan string, <-chan string) {
	fmt.Println("Cache node started")
	cacheReq := make(chan string)
	cacheResp := make(chan string)
	go func() {
		for {
			cache := make(map[string]string)
			key := <-cacheReq
			res, ok := cache[key]
			if !ok {
				res = readFromDb(key)
				cache[key] = key
			}
			cacheResp <- res
		}
	}()
	return cacheReq, cacheResp
}

// If client is connected for data, try to get it from cache and return to the client
func handleDataConnection(conn net.Conn, cacheReq chan string, cacheResp <- chan string){
	defer conn.Close()
	dec := gob.NewDecoder(conn)
	req := DataReqPacket{}
	dec.Decode(&req)
	cacheReq <- req.Key
	resp := DataRespPacket {Value: <- cacheResp}
	enc := gob.NewEncoder(conn)
	enc.Encode(resp)
}

// Data server is simply handling incoming data connections
func runDataServer(port string, cacheReq chan string, cacheResp <- chan string){
	sock, _ := net.Listen("tcp",port)
	for {
		conn, err := sock.Accept()
		if err != nil {
			continue
		}
		fmt.Println("New connection")
		go handleDataConnection(conn, cacheReq, cacheResp)
	}
}

// Here command packets are parsed and executed
// If ValueRequest packet is received - local cache is checked for this value
// and if it's present ValueResponse packet is returned
// For ValueResponse packet - signal is sent to TaskQueue using quequeRun chan
func runCommHandler(in <-chan ComPacket, port string, cacheReq chan string,
	cacheResp <- chan string, queueRun chan DataOwnerInfo){
	for {
		packet := <-in
		switch(packet.Type){
		case VAL_REQ:
			cacheReq <- packet.Key
			<- cacheResp
			var resp ComPacket
			resp.Type = VAL_RESP
			resp.Port = port
			resp.Id = packet.Id
			conn, err := net.Dial("udp", packet.Port)
			if err != nil {
				fmt.Printf("Couldn't connect to %s\n",packet.Port)
				fmt.Println(err)
				return
			}
			defer conn.Close()
			enc := json.NewEncoder(conn)
			enc.Encode(resp)
		case VAL_RESP:
			fmt.Printf("response is %v\n", packet)
			owner := DataOwnerInfo{ Id: packet.Id, Addr: packet.Port}
			queueRun <- owner
		}
	}
}

// Host Command server (UDP)
func runCommandServer(port string, cacheReq chan string, cacheResp <- chan string,
queueRun chan DataOwnerInfo) {
	handlerCh := make(chan ComPacket)
	go runCommHandler(handlerCh, port, cacheReq, cacheResp, queueRun)
	addr, _ := net.ResolveUDPAddr("udp", port)
	sock, _ := net.ListenUDP("udp", addr)
	fmt.Printf("network server started at udp%s\n", port)
	dec := json.NewDecoder(sock)
	for {
		req := ComPacket{}
		dec.Decode(&req)
		handlerCh <- req
	}
}

// Wait until data is found on network or cancel task
func waitForValue(req Request){
	select{
	case owner := <- req.Callback: // data owner found
		// connect via tcp
		conn, err := net.Dial("tcp", owner.Addr)
		if err != nil {
			fmt.Println("cannot conect to data owner")
		}
		defer conn.Close()
		// send data request
		encoder := gob.NewEncoder(conn)
		req := DataReqPacket{Key: req.Key}
		encoder.Encode(req)

		// receive data
		decoder := gob.NewDecoder(conn)
		resp := DataRespPacket{}
		decoder.Decode(&resp)
		fmt.Printf("data received %s\n", resp.Value)
	case <- time.After(time.Millisecond * 30):// timeout
		req.Cancel <- req.Id
	}
}

// Any request for cache is stored in queque, until it's is fullfield
// return params
// queueAdd chan Request - add new Request to Queue
// queueRun chan DataOwnerInfo - Signals that data owner is found
// queueRemove - removes item from queue (error or timeout)
func createRequestQueue()(chan Request, chan DataOwnerInfo, chan int){
	queueAdd := make(chan Request)
	queueRun := make(chan DataOwnerInfo)
	queueRemove := make(chan int)

	go func(){
		tasks := list.New()
		for {
			select{
			case req := <-queueAdd: // Add
//				fmt.Printf("Addind %v to queue\n",req)
				tasks.PushBack(req)

			case owner := <-queueRun: //Start download process, remove request from queue
//				fmt.Printf("Running %v owner\n", owner)
				for e := tasks.Front(); e !=nil; e = e.Next(){
					if e.Value.(Request).Id == owner.Id {
						e.Value.(Request).Callback <- owner
						tasks.Remove(e)
					}
				}
			case id := <- queueRemove: //Remove item from queue
				for e := tasks.Front(); e != nil; e = e.Next(){
					if e.Value.(Request).Id == id {
						tasks.Remove(e)
					}
				}
			}
		}
	}()
	return queueAdd, queueRun, queueRemove
}

var currId int
func getValue(key, hostPort string, quequeAdd chan Request, cancel chan int) {
	currId++
	var callback = make(chan DataOwnerInfo)
	req := Request { Id: currId, Key: key, Callback: callback, Cancel: cancel}
	go waitForValue(req)
	quequeAdd <- req
	// broadcast all instances
	for _, port := range ports {
		go func(port string) {
			conn, err := net.Dial("udp", port)
			if err != nil {
				fmt.Printf("getValue couldn't connect to %s\n", port)
				fmt.Println(err)
				return
			}
			defer conn.Close()

			// send request packet
			enc := json.NewEncoder(conn)
			packet := ComPacket{Type: VAL_REQ, Key: key, Port: hostPort, Id : currId}
			enc.Encode(packet)
		}(port)
	}
}

var ports = []string{
	"127.0.0.1:8000",
	"127.0.0.1:8001",
	"127.0.0.1:8002",
	"127.0.0.1:8003",
}

func main() {
	// parse CL
	instanceId := flag.Int("id", 0, "instance id")

	flag.Parse()
	port := ports[*instanceId]

	// init all
	cacheReq, cacheResp := createCacheNode()
	queueAdd, queueRun, queueRemove := createRequestQueue()
	go runCommandServer(port, cacheReq, cacheResp, queueRun)
	go runDataServer(port, cacheReq, cacheResp)

	getValue("a", port, queueAdd, queueRemove)
	// main loop
	var input string
	for {
		fmt.Scanln(&input)
		getValue(input, ports[*instanceId], queueAdd, queueRemove)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"io"
	"log"
	"os"
	"strconv"
	"strings"

	"database/sql"
	"encoding/csv"

	_ "github.com/go-sql-driver/mysql"
	_ "github.com/lib/pq"
	_ "github.com/mattn/go-sqlite3"
	"github.com/xwb1989/sqlparser"
)

var (
	dbdriver string
	dbdsn    string
)

func rowimport(stmt *sql.Stmt, list []interface{}) {
	_, err := stmt.Exec(list...)
	if err != nil {
		log.Println(err)
	}
}

func csvImport(db *sql.DB, reader *csv.Reader, table string, header []string) {
	columns := make([]string, len(header))
	place := make([]string, len(header))
	list := make([]interface{}, len(header))
	for i := range header {
		columns[i] = "c" + strconv.Itoa(i+1)
		if dbdriver == "postgres" {
			place[i] = "$" + strconv.Itoa(i+1)
		} else {
			place[i] = "?"
		}
		list[i] = header[i]
	}
	sqlstr := "INSERT INTO " + table + " (" + strings.Join(columns, ",") + ") VALUES (" + strings.Join(place, ",") + ");"
	stmt, err := db.Prepare(sqlstr)
	if err != nil {
		log.Fatal("ISNERT:", err)
	}
	rowimport(stmt, list)

	for {
		record, err := reader.Read()
		if err == io.EOF {
			break
		} else {
			if err != nil {
				log.Fatal("ERROR: ", err)
			}
		}
		for i := range header {
			list[i] = record[i]
		}
		rowimport(stmt, list)
	}
}

func csvOpen(filename string) (*csv.Reader, error) {
	var file *os.File
	var err error
	if filename == "-" {
		file = os.Stdin
	} else {
		if filename[0] == '`' {
			filename = strings.Replace(filename, "`", "", 2)
		}
		file, err = os.Open(filename)
		if err != nil {
			// log.Fatal("ERROR: ", err)
			return nil, err
		}
	}
	reader := csv.NewReader(file)
	return reader, err
}

func csvRead(reader *csv.Reader) (header []string) {
	var err error
	header, err = reader.Read()
	if err != nil {
		log.Fatal("ERROR: ", err)
	}
	return header
}

func escapetable(oldname string) (newname string) {
	if dbdriver == "postgres" {
		if oldname[0] != '"' {
			newname = "\"" + oldname + "\""
		} else {
			newname = oldname
		}
	} else {
		if oldname[0] != '`' {
			newname = "`" + oldname + "`"
		} else {
			newname = oldname
		}
	}
	return newname
}

func rewrite(sqlstr string, oldname string, newname string) (rewrite string) {
	rewrite = strings.Replace(sqlstr, oldname, newname, -1)
	return rewrite
}

func rewriteTable(tree sqlparser.SQLNode, tablename string) string {
	rewriter := func(origin []byte) []byte {
		s := string(origin)
		if s == tablename {
			s = "_"
		}
		return []byte(s)
	}
	sqlparser.Rewrite(tree, rewriter)
	return sqlparser.String(tree)
}

func dbConnect(driver, dsn string) *sql.DB {
	db, err := sql.Open(driver, dsn)
	if err != nil {
		log.Fatal(err)
	}
	return db
}

func dbDisconnect(db *sql.DB) {
	err := db.Close()
	if err != nil {
		log.Fatal(err)
	}
}

func dbCreate(db *sql.DB, table string, header []string) {
	var sqlstr string
	columns := make([]string, len(header))
	for i := 0; i < len(header); i++ {
		columns[i] = "c" + strconv.Itoa(i+1) + " text"
	}
	if dbdriver == "postgres" {
		sqlstr = "CREATE TEMP TABLE "
	} else if dbdriver == "mysql" {
		sqlstr = "CREATE TEMPORARY TABLE "
	} else {
		sqlstr = "CREATE TABLE "
	}
	sqlstr = sqlstr + table + " ( " + strings.Join(columns, ",") + " );"
	log.Println(sqlstr)
	_, err := db.Exec(sqlstr)
	if err != nil {
		log.Fatal("CREATE:", err)
	}
}

func dbSelect(db *sql.DB, writer *csv.Writer, sqlstr string) {
	sqlstr = strings.TrimSpace(sqlstr)
	if sqlstr == "" {
		log.Fatal("ERROR: no SQL statement")
	}
	log.Println(sqlstr)
	rows, err := db.Query(sqlstr)
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()
	columns, err := rows.Columns()
	if err != nil {
		log.Fatal(err)
	}
	values := make([]sql.RawBytes, len(columns))
	results := make([]string, len(columns))
	scanArgs := make([]interface{}, len(values))
	for i := range values {
		scanArgs[i] = &values[i]
	}
	for rows.Next() {
		err = rows.Scan(scanArgs...)
		if err != nil {
			log.Fatal(err)
		}
		for i, col := range values {
			results[i] = string(col)
		}
		writer.Write(results)
		writer.Flush()
	}
}

func sqlparse(sqlstr string) []string {
	word := strings.Fields(sqlstr)
	tablenames := make([]string, 0, 1)
	for i := 0; i < len(word); i++ {
		if element := strings.ToUpper(word[i]); element == "FROM" || element == "JOIN" {
			tablenames = append(tablenames, word[i+1])
		}
	}
	return tablenames
}

func getSeparator(sepString string) (sepRune rune) {
	sepString = `'` + sepString + `'`
	sepRunes, err := strconv.Unquote(sepString)
	if err != nil {
		log.Fatal(sepString, ": ", err)
	}
	sepRune = ([]rune(sepRunes))[0]

	return sepRune
}

func main() {
	var (
		inSep  string
		outSep string
	)
	flag.StringVar(&dbdriver, "dbdriver", "sqlite3", "database driver.")
	flag.StringVar(&dbdsn, "dbdsn", "", "database connection option.")
	flag.StringVar(&inSep, "input-delimiter", ",", "Field delimiter for input.")
	flag.StringVar(&inSep, "d", ",", "Field delimiter for input.")
	flag.StringVar(&outSep, "output-delimiter", ",", "Field delimiter for output.")
	flag.StringVar(&outSep, "D", ",", "Field delimiter for output.")
	flag.Parse()
	if len(flag.Args()) == 0 {
		flag.Usage()
		os.Exit(2)
	}
	sqlstr := flag.Args()[0]
	writer := csv.NewWriter(os.Stdout)
	writer.Comma = getSeparator(outSep)
	readerComma := getSeparator(inSep)

	if dbdsn == "" {
		if dbdriver == "sqlite3" {
			dbdsn = ":memory:"
		}
	}
	db := dbConnect(dbdriver, dbdsn)
	defer dbDisconnect(db)

	tablenames := sqlparse(sqlstr)
	for _, tablename := range tablenames {
		reader, err := csvOpen(tablename)
		if err != nil {
			continue
		}
		rtable := escapetable(tablename)
		sqlstr = rewrite(sqlstr, tablename, rtable)
		reader.Comma = readerComma
		reader.FieldsPerRecord = -1
		header := csvRead(reader)
		dbCreate(db, rtable, header)
		csvImport(db, reader, rtable, header)
	}
	dbSelect(db, writer, sqlstr)
}
<commit_msg>Unified "TEMP" to "TEMPORARY".<commit_after>package main

import (
	"flag"
	"io"
	"log"
	"os"
	"strconv"
	"strings"

	"database/sql"
	"encoding/csv"

	_ "github.com/go-sql-driver/mysql"
	_ "github.com/lib/pq"
	_ "github.com/mattn/go-sqlite3"
	"github.com/xwb1989/sqlparser"
)

var (
	dbdriver string
	dbdsn    string
)

func rowimport(stmt *sql.Stmt, list []interface{}) {
	_, err := stmt.Exec(list...)
	if err != nil {
		log.Println(err)
	}
}

func csvImport(db *sql.DB, reader *csv.Reader, table string, header []string) {
	columns := make([]string, len(header))
	place := make([]string, len(header))
	list := make([]interface{}, len(header))
	for i := range header {
		columns[i] = "c" + strconv.Itoa(i+1)
		if dbdriver == "postgres" {
			place[i] = "$" + strconv.Itoa(i+1)
		} else {
			place[i] = "?"
		}
		list[i] = header[i]
	}
	sqlstr := "INSERT INTO " + table + " (" + strings.Join(columns, ",") + ") VALUES (" + strings.Join(place, ",") + ");"
	stmt, err := db.Prepare(sqlstr)
	if err != nil {
		log.Fatal("ISNERT:", err)
	}
	rowimport(stmt, list)

	for {
		record, err := reader.Read()
		if err == io.EOF {
			break
		} else {
			if err != nil {
				log.Fatal("ERROR: ", err)
			}
		}
		for i := range header {
			list[i] = record[i]
		}
		rowimport(stmt, list)
	}
}

func csvOpen(filename string) (*csv.Reader, error) {
	var file *os.File
	var err error
	if filename == "-" {
		file = os.Stdin
	} else {
		if filename[0] == '`' {
			filename = strings.Replace(filename, "`", "", 2)
		}
		file, err = os.Open(filename)
		if err != nil {
			// log.Fatal("ERROR: ", err)
			return nil, err
		}
	}
	reader := csv.NewReader(file)
	return reader, err
}

func csvRead(reader *csv.Reader) (header []string) {
	var err error
	header, err = reader.Read()
	if err != nil {
		log.Fatal("ERROR: ", err)
	}
	return header
}

func escapetable(oldname string) (newname string) {
	if dbdriver == "postgres" {
		if oldname[0] != '"' {
			newname = "\"" + oldname + "\""
		} else {
			newname = oldname
		}
	} else {
		if oldname[0] != '`' {
			newname = "`" + oldname + "`"
		} else {
			newname = oldname
		}
	}
	return newname
}

func rewrite(sqlstr string, oldname string, newname string) (rewrite string) {
	rewrite = strings.Replace(sqlstr, oldname, newname, -1)
	return rewrite
}

func rewriteTable(tree sqlparser.SQLNode, tablename string) string {
	rewriter := func(origin []byte) []byte {
		s := string(origin)
		if s == tablename {
			s = "_"
		}
		return []byte(s)
	}
	sqlparser.Rewrite(tree, rewriter)
	return sqlparser.String(tree)
}

func dbConnect(driver, dsn string) *sql.DB {
	db, err := sql.Open(driver, dsn)
	if err != nil {
		log.Fatal(err)
	}
	return db
}

func dbDisconnect(db *sql.DB) {
	err := db.Close()
	if err != nil {
		log.Fatal(err)
	}
}

func dbCreate(db *sql.DB, table string, header []string) {
	var sqlstr string
	columns := make([]string, len(header))
	for i := 0; i < len(header); i++ {
		columns[i] = "c" + strconv.Itoa(i+1) + " text"
	}
	if dbdriver == "sqlite3" {
		sqlstr = "CREATE TABLE "
	} else {
		sqlstr = "CREATE TEMPORARY TABLE "
	}
	sqlstr = sqlstr + table + " ( " + strings.Join(columns, ",") + " );"
	log.Println(sqlstr)
	_, err := db.Exec(sqlstr)
	if err != nil {
		log.Fatal("CREATE:", err)
	}
}

func dbSelect(db *sql.DB, writer *csv.Writer, sqlstr string) {
	sqlstr = strings.TrimSpace(sqlstr)
	if sqlstr == "" {
		log.Fatal("ERROR: no SQL statement")
	}
	log.Println(sqlstr)
	rows, err := db.Query(sqlstr)
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()
	columns, err := rows.Columns()
	if err != nil {
		log.Fatal(err)
	}
	values := make([]sql.RawBytes, len(columns))
	results := make([]string, len(columns))
	scanArgs := make([]interface{}, len(values))
	for i := range values {
		scanArgs[i] = &values[i]
	}
	for rows.Next() {
		err = rows.Scan(scanArgs...)
		if err != nil {
			log.Fatal(err)
		}
		for i, col := range values {
			results[i] = string(col)
		}
		writer.Write(results)
		writer.Flush()
	}
}

func sqlparse(sqlstr string) []string {
	word := strings.Fields(sqlstr)
	tablenames := make([]string, 0, 1)
	for i := 0; i < len(word); i++ {
		if element := strings.ToUpper(word[i]); element == "FROM" || element == "JOIN" {
			tablenames = append(tablenames, word[i+1])
		}
	}
	return tablenames
}

func getSeparator(sepString string) (sepRune rune) {
	sepString = `'` + sepString + `'`
	sepRunes, err := strconv.Unquote(sepString)
	if err != nil {
		log.Fatal(sepString, ": ", err)
	}
	sepRune = ([]rune(sepRunes))[0]

	return sepRune
}

func main() {
	var (
		inSep  string
		outSep string
	)
	flag.StringVar(&dbdriver, "dbdriver", "sqlite3", "database driver.")
	flag.StringVar(&dbdsn, "dbdsn", "", "database connection option.")
	flag.StringVar(&inSep, "input-delimiter", ",", "Field delimiter for input.")
	flag.StringVar(&inSep, "d", ",", "Field delimiter for input.")
	flag.StringVar(&outSep, "output-delimiter", ",", "Field delimiter for output.")
	flag.StringVar(&outSep, "D", ",", "Field delimiter for output.")
	flag.Parse()
	if len(flag.Args()) == 0 {
		flag.Usage()
		os.Exit(2)
	}
	sqlstr := flag.Args()[0]
	writer := csv.NewWriter(os.Stdout)
	writer.Comma = getSeparator(outSep)
	readerComma := getSeparator(inSep)

	if dbdsn == "" {
		if dbdriver == "sqlite3" {
			dbdsn = ":memory:"
		}
	}
	db := dbConnect(dbdriver, dbdsn)
	defer dbDisconnect(db)

	tablenames := sqlparse(sqlstr)
	for _, tablename := range tablenames {
		reader, err := csvOpen(tablename)
		if err != nil {
			continue
		}
		rtable := escapetable(tablename)
		sqlstr = rewrite(sqlstr, tablename, rtable)
		reader.Comma = readerComma
		reader.FieldsPerRecord = -1
		header := csvRead(reader)
		dbCreate(db, rtable, header)
		csvImport(db, reader, rtable, header)
	}
	dbSelect(db, writer, sqlstr)
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"github.com/davecgh/go-spew/spew"
	"github.com/k0kubun/twitter"
	"github.com/mingderwang/userstream"
	"github.com/parnurzeal/gorequest"
	"net/http"
	"os"
	"strconv"
	"strings"
)

type Onion struct {
	Ginger_Created int32 `json:"ginger_created"`
	Ginger_Id      int32 `json:"ginger_id" gorm:"primary_key"`

	DomainName string `json:"domainName"`
	TypeName   string `json:"typeName"`
	JsonSchema string `json:"jsonSchema"`
}

func main() {
	var CONSUMER_KEY = os.Getenv("CONSUMER_KEY")
	var CONSUMER_SECRET = os.Getenv("CONSUMER_SECRET")
	var ACCESS_TOKEN = os.Getenv("ACCESS_TOKEN")
	var ACCESS_TOKEN_SECRET = os.Getenv("ACCESS_TOKEN_SECRET")
	client := &userstream.Client{
		ConsumerKey:       CONSUMER_KEY,
		ConsumerSecret:    CONSUMER_SECRET,
		AccessToken:       ACCESS_TOKEN,
		AccessTokenSecret: ACCESS_TOKEN_SECRET,
	}

	client.UserStream(func(event interface{}) {
		switch event.(type) {
		case *twitter.Tweet:
			tweet := event.(*twitter.Tweet)
			fmt.Printf("%s: %s\n", tweet.User.ScreenName, tweet.Text)
		case *userstream.Delete:
			tweetDelete := event.(*userstream.Delete)
			fmt.Printf("[delete] %d\n", tweetDelete.Id)
		case *userstream.Favorite:
			favorite := event.(*userstream.Favorite)
			fmt.Printf("[favorite] %s => %s : %s\n",
				favorite.Source.ScreenName, favorite.Target.ScreenName, favorite.TargetObject.Text)
		case *userstream.Unfavorite:
			unfavorite := event.(*userstream.Unfavorite)
			fmt.Printf("[unfavorite] %s => %s : %s\n",
				unfavorite.Source.ScreenName, unfavorite.Target.ScreenName, unfavorite.TargetObject.Text)
		case *userstream.Follow:
			follow := event.(*userstream.Follow)
			fmt.Printf("[follow] %s => %s\n", follow.Source.ScreenName, follow.Target.ScreenName)
		case *userstream.Unfollow:
			unfollow := event.(*userstream.Unfollow)
			fmt.Printf("[unfollow] %s => %s\n", unfollow.Source.ScreenName, unfollow.Target.ScreenName)
		case *userstream.ListMemberAdded:
			listMemberAdded := event.(*userstream.ListMemberAdded)
			fmt.Printf("[list_member_added] %s (%s)\n",
				listMemberAdded.TargetObject.FullName, listMemberAdded.TargetObject.Description)
		case *userstream.ListMemberRemoved:
			listMemberRemoved := event.(*userstream.ListMemberRemoved)
			fmt.Printf("[list_member_removed] %s (%s)\n",
				listMemberRemoved.TargetObject.FullName, listMemberRemoved.TargetObject.Description)
		case *userstream.Record:
			directMessage := event.(*userstream.Record)
			sendRequest(directMessage.DirectMessage.Sender.ScreenName, directMessage.DirectMessage.Text)
		}
	})
}

func stringify(data string) (tag string, schema string) {
	jsonString := strings.SplitN(data, ":", 2)
	//	spew.Dump(jsonString)
	if len(jsonString) == 2 {
		str := strconv.Quote(jsonString[1])
		return jsonString[0], str
	} else {
		return "", ""
	}
}

func sendRequest(userName string, jsonSchemaWithTag string) {
	request := gorequest.New()
	if tag, schema := stringify(jsonSchemaWithTag); tag == "" && schema == "" {
		fmt.Println("error")
	} else {
		str := `{"domainName":"` + userName + `","typeName":` + tag + `,"jsonSchema":` + schema + `}`
		fmt.Printf("%s", str)
		resp, body, err := request.Post("http://log4security.com:8080/onion").
			Set("Content-Type", "application/json").
			Send(str).End()
		if err != nil {
			panic(err)
		}
		spew.Dump(body)
		spew.Dump(resp)
		target := Onion{}
		processResponser(resp, &target)
		spew.Dump(target.Ginger_Id)
		sendRequestByIdForBuild(string(target.Ginger_Id))
	}
}

func sendRequestByIdForBuild(idString string) {

}

func processResponser(response *http.Response, target *Onion) {
	json.NewDecoder(response.Body).Decode(&target)
}

func getJson(url string, target interface{}) error {
	r, err := http.Get(url)
	if err != nil {
		return err
	}
	defer r.Body.Close()

	return json.NewDecoder(r.Body).Decode(target)
}
<commit_msg>ok for send build and return url<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"github.com/davecgh/go-spew/spew"
	"github.com/k0kubun/twitter"
	"github.com/mingderwang/userstream"
	"github.com/parnurzeal/gorequest"
	"net/http"
	"os"
	"strconv"
	"strings"
)

type Result struct {
	EndpointURL string `json:"endpointURL"`
}

type Onion struct {
	Ginger_Created int32 `json:"ginger_created"`
	Ginger_Id      int32 `json:"ginger_id" gorm:"primary_key"`

	DomainName string `json:"domainName"`
	TypeName   string `json:"typeName"`
	JsonSchema string `json:"jsonSchema"`
}

const baseURL string = "http://log4security.com:8080/onion"

func main() {
	var CONSUMER_KEY = os.Getenv("CONSUMER_KEY")
	var CONSUMER_SECRET = os.Getenv("CONSUMER_SECRET")
	var ACCESS_TOKEN = os.Getenv("ACCESS_TOKEN")
	var ACCESS_TOKEN_SECRET = os.Getenv("ACCESS_TOKEN_SECRET")
	client := &userstream.Client{
		ConsumerKey:       CONSUMER_KEY,
		ConsumerSecret:    CONSUMER_SECRET,
		AccessToken:       ACCESS_TOKEN,
		AccessTokenSecret: ACCESS_TOKEN_SECRET,
	}

	client.UserStream(func(event interface{}) {
		switch event.(type) {
		case *twitter.Tweet:
			tweet := event.(*twitter.Tweet)
			fmt.Printf("%s: %s\n", tweet.User.ScreenName, tweet.Text)
		case *userstream.Delete:
			tweetDelete := event.(*userstream.Delete)
			fmt.Printf("[delete] %d\n", tweetDelete.Id)
		case *userstream.Favorite:
			favorite := event.(*userstream.Favorite)
			fmt.Printf("[favorite] %s => %s : %s\n",
				favorite.Source.ScreenName, favorite.Target.ScreenName, favorite.TargetObject.Text)
		case *userstream.Unfavorite:
			unfavorite := event.(*userstream.Unfavorite)
			fmt.Printf("[unfavorite] %s => %s : %s\n",
				unfavorite.Source.ScreenName, unfavorite.Target.ScreenName, unfavorite.TargetObject.Text)
		case *userstream.Follow:
			follow := event.(*userstream.Follow)
			fmt.Printf("[follow] %s => %s\n", follow.Source.ScreenName, follow.Target.ScreenName)
		case *userstream.Unfollow:
			unfollow := event.(*userstream.Unfollow)
			fmt.Printf("[unfollow] %s => %s\n", unfollow.Source.ScreenName, unfollow.Target.ScreenName)
		case *userstream.ListMemberAdded:
			listMemberAdded := event.(*userstream.ListMemberAdded)
			fmt.Printf("[list_member_added] %s (%s)\n",
				listMemberAdded.TargetObject.FullName, listMemberAdded.TargetObject.Description)
		case *userstream.ListMemberRemoved:
			listMemberRemoved := event.(*userstream.ListMemberRemoved)
			fmt.Printf("[list_member_removed] %s (%s)\n",
				listMemberRemoved.TargetObject.FullName, listMemberRemoved.TargetObject.Description)
		case *userstream.Record:
			directMessage := event.(*userstream.Record)
			sendRequest(directMessage.DirectMessage.Sender.ScreenName, directMessage.DirectMessage.Text)
		}
	})
}

func stringify(data string) (tag string, schema string) {
	jsonString := strings.SplitN(data, ":", 2)
	//	spew.Dump(jsonString)
	if len(jsonString) == 2 {
		str := strconv.Quote(jsonString[1])
		return jsonString[0], str
	} else {
		return "", ""
	}
}

func sendRequest(userName string, jsonSchemaWithTag string) {
	request := gorequest.New()
	if tag, schema := stringify(jsonSchemaWithTag); tag == "" && schema == "" {
		fmt.Println("error")
	} else {
		str := `{"domainName":"` + userName + `","typeName":` + tag + `,"jsonSchema":` + schema + `}`
		fmt.Printf("%s", str)
		resp, _, err := request.Post(baseURL).
			Set("Content-Type", "application/json").
			Send(str).End()
		if err != nil {
			panic(err)
		}
		//	spew.Dump(body)
		//	spew.Dump(resp)
		target := Onion{}
		processResponser(resp, &target)
		spew.Dump(target.Ginger_Id)
		var s string = strconv.Itoa(int(target.Ginger_Id))
		sendRequestByIdForBuild(s)
	}
}

func sendRequestByIdForBuild(idString string) {
	target := Result{}
	url := fmt.Sprintf("%s/%s/build", baseURL, idString)
	fmt.Println(url)
	request := gorequest.New()
	resp, _, _ := request.Get(url).End(printStatus)
	spew.Dump(resp.Body)
	json.NewDecoder(resp.Body).Decode(&target)
	spew.Dump(target)
}

func printStatus(resp gorequest.Response, body string, errs []error) {
	fmt.Println(resp.Status)
}

func processResponser(response *http.Response, target *Onion) {
	json.NewDecoder(response.Body).Decode(&target)
}

func getJson(url string, target interface{}) error {
	r, err := http.Get(url)
	if err != nil {
		return err
	}
	defer r.Body.Close()

	return json.NewDecoder(r.Body).Decode(target)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os/exec"
	"path"
	"time"
)

type Deploy struct {
	Id   string
	Note string
	Port int // -1 for not running
}

type Label string

type Server interface {
	ListLabels() ([]Label, error)

	ListDeploys() ([]Deploy, error)

	Run(deployId string) error

	Stop(deployId string) error

	Label(deployId string, label Label) error

	// TODO Maintenance mode
}

const deployPath = "deploys"

type ServerImpl struct {
	root string
}

func (s *ServerImpl) ListDeploys() ([]Deploy, error) {
	infos, err := ioutil.ReadDir(path.Join(s.root, deployPath))
	if err != nil {
		return nil, err
	}
	var result []Deploy
	for _, info := range infos {
		result = append(result, Deploy{
			Id:   info.Name(),
			Port: -1,
		})
	}
	return result, nil
}

const CAMUS_PORT = 9966

/*

1. build
2. tag & push tag to git
3.

1. push binary (rsync)
   - build
   - tag & push tag to git
   - rsync binary
2. bring up binary (Run())
3. set to live (Label())

Application defines:
- build command (and tell us where the dir is)
- run command (with substitution for port)
- status check endpoint

*/

type Application struct {
	BuildCmd string

	BuildOutputDir string

	// needs a %PORT% part for port subsitution
	RunCmd string

	StatusEndpoint string

	// e.g. user@host  (no path)
	SshTarget map[string]string
}

func gitTag( /*args*/ ) {
}
func rsync( /*args*/ ) {
}

// TODO the rest

var serverRoot = flag.String("serverRoot", "", "Path to the root directory in the prod machine")

func main() {
	welcome()

	setupChannel("localhost")

	flag.Parse()
	server := ServerImpl{
		root: *serverRoot,
	}
	deploys, err := server.ListDeploys()
	if err != nil {
		log.Fatalf("Failed to list deploys: %s", err)
	}

	for _, deploy := range deploys {
		fmt.Printf("%v\n", deploy)
	}

}

func welcome() {
	println("--------")
	println(QUOTES[int(time.Now().UnixNano())%len(QUOTES)])
	println("--------")
}

func setupChannel(login string) func() {
	port := CAMUS_PORT
	cmd := exec.Command("ssh", login, fmt.Sprintf("-L%d:localhost:%d", port, port))
	pipe, err := cmd.StdinPipe()
	err = cmd.Start()

	if err != nil {
		log.Fatalf("%s", err)
	}

	return func() {
		pipe.Close()
	}
}

func sleepSeconds(seconds int) {
	time.Sleep(time.Duration(seconds) * time.Second)
}
<commit_msg>Add RPC for server, introduce server and client mode.<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"net/rpc"
	"os/exec"
	"path"
	"time"
)

type Deploy struct {
	Id   string
	Note string
	Port int // -1 for not running
}

type Label string

type Server interface {
	ListLabels() ([]Label, error)
	ListDeploys() ([]Deploy, error)
	Run(deployId string) error
	Stop(deployId string) error
	Label(deployId string, label Label) error

	// TODO Maintenance mode
}

const deployPath = "deploys"

type ServerImpl struct {
	root string
}

func (s *ServerImpl) ListDeploys() ([]Deploy, error) {
	infos, err := ioutil.ReadDir(path.Join(s.root, deployPath))
	if err != nil {
		return nil, err
	}
	var result []Deploy
	for _, info := range infos {
		result = append(result, Deploy{
			Id:   info.Name(),
			Port: -1,
		})
	}
	return result, nil
}

const CAMUS_PORT = 9966

type RpcServer struct {
	server *ServerImpl
}

type ListDeploysRequest struct{}
type ListDeploysReply struct {
	Deploys []Deploy
}

func (s *RpcServer) ListDeploys(arg ListDeploysRequest, reply *ListDeploysReply) error {
	deploys, err := s.server.ListDeploys()
	if err != nil {
		return err
	}
	reply.Deploys = deploys
	return nil
}

/*

1. build
2. tag & push tag to git
3.

1. push binary (rsync)
   - build
   - tag & push tag to git
   - rsync binary
2. bring up binary (Run())
3. set to live (Label())

Application defines:
- build command (and tell us where the dir is)
- run command (with substitution for port)
- status check endpoint

*/

type Application struct {
	BuildCmd string

	BuildOutputDir string

	// needs a %PORT% part for port subsitution
	RunCmd string

	StatusEndpoint string

	// e.g. user@host  (no path)
	SshTarget map[string]string
}

func gitTag( /*args*/ ) {
}
func rsync( /*args*/ ) {
}

// TODO the rest

var serverRoot = flag.String("serverRoot", "", "Path to the root directory in the prod machine")
var mode = flag.String("mode", "server", "'server' or 'client'")
var port = flag.String("port", ":1234", "port to serve on / connect to")

func main() {
	welcome()

	setupChannel("localhost")

	flag.Parse()
	fmt.Printf("running in '%s' mode\n", *mode)
	if *mode == "server" {
		serverMain()
	} else {
		clientMain()
	}
}

func serverMain() {
	s := &RpcServer{
		server: &ServerImpl{
			root: *serverRoot,
		},
	}
	rpc.Register(s)
	rpc.HandleHTTP()
	l, err := net.Listen("tcp", *port)
	if err != nil {
		log.Fatal("failed to listen:", err)
	}
	http.Serve(l, nil)
}

func clientMain() {
	serverAddr := "localhost" + *port
	fmt.Printf("dialing %s\n", serverAddr)
	client, err := rpc.DialHTTP("tcp", serverAddr)
	if err != nil {
		log.Fatal("dialing:", err)
	}
	args := &ListDeploysRequest{}
	var reply ListDeploysReply
	err = client.Call("RpcServer.ListDeploys", args, &reply)

	if err != nil {
		log.Fatal("RPC:", err)
	}

	for _, deploy := range reply.Deploys {
		fmt.Printf("%v\n", deploy)
	}

}

func welcome() {
	println("--------")
	println(QUOTES[int(time.Now().UnixNano())%len(QUOTES)])
	println("--------")
}

func setupChannel(login string) func() {
	port := CAMUS_PORT
	cmd := exec.Command("ssh", login, fmt.Sprintf("-L%d:localhost:%d", port, port))
	pipe, err := cmd.StdinPipe()
	err = cmd.Start()

	if err != nil {
		log.Fatalf("%s", err)
	}

	return func() {
		pipe.Close()
	}
}

func sleepSeconds(seconds int) {
	time.Sleep(time.Duration(seconds) * time.Second)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"

	"github.com/cloudfoundry/statsd-injector/app"
)

const defaultAPIVersion = "v1"

func main() {
	statsdHost := flag.String("statsdHost", "localhost", "The hostname the injector will listen on for statsd messages")
	statsdPort := flag.Uint("statsd-port", 8125, "The UDP port the injector will listen on for statsd messages")
	apiVersion := flag.String("metron-api", defaultAPIVersion, "API version of Metron to which to send envelopes")
	metronPort := flag.Uint("metron-port", 3458, "The GRPC port the injector will forward message to")

	ca := flag.String("ca", "", "File path to the CA certificate")
	cert := flag.String("cert", "", "File path to the client TLS cert")
	privateKey := flag.String("key", "", "File path to the client TLS private key")

	deploymentName := flag.String("deployment-name", "", "Deployment name (envelope tag)")
	jobName := flag.String("job-name", "", "Job name (envelope tag)")
	ipAddr := flag.String("ip", "", "IP address of host machine (envelope tag)")
	instanceIndex := flag.String("instance-index", "", "index of job instance")
	flag.Parse()

	injector := app.NewInjector(app.Config{
		StatsdHost:     *statsdHost,
		StatsdPort:     *statsdPort,
		APIVersion:     *apiVersion,
		MetronPort:     *metronPort,
		CA:             *ca,
		Cert:           *cert,
		Key:            *privateKey,
		DeploymentName: *deploymentName,
		JobName:        *jobName,
		IPAddr:         *ipAddr,
		InstanceIndex:  *instanceIndex,
	})
	injector.Start()
}
<commit_msg>Use dash-case for flags<commit_after>package main

import (
	"flag"

	"github.com/cloudfoundry/statsd-injector/app"
)

const defaultAPIVersion = "v1"

func main() {
	statsdHost := flag.String("statsd-host", "localhost", "The hostname the injector will listen on for statsd messages")
	statsdPort := flag.Uint("statsd-port", 8125, "The UDP port the injector will listen on for statsd messages")
	apiVersion := flag.String("metron-api", defaultAPIVersion, "API version of Metron to which to send envelopes")
	metronPort := flag.Uint("metron-port", 3458, "The GRPC port the injector will forward message to")

	ca := flag.String("ca", "", "File path to the CA certificate")
	cert := flag.String("cert", "", "File path to the client TLS cert")
	privateKey := flag.String("key", "", "File path to the client TLS private key")

	deploymentName := flag.String("deployment-name", "", "Deployment name (envelope tag)")
	jobName := flag.String("job-name", "", "Job name (envelope tag)")
	ipAddr := flag.String("ip", "", "IP address of host machine (envelope tag)")
	instanceIndex := flag.String("instance-index", "", "index of job instance")
	flag.Parse()

	injector := app.NewInjector(app.Config{
		StatsdHost:     *statsdHost,
		StatsdPort:     *statsdPort,
		APIVersion:     *apiVersion,
		MetronPort:     *metronPort,
		CA:             *ca,
		Cert:           *cert,
		Key:            *privateKey,
		DeploymentName: *deploymentName,
		JobName:        *jobName,
		IPAddr:         *ipAddr,
		InstanceIndex:  *instanceIndex,
	})
	injector.Start()
}
<|endoftext|>


<commit_before>// pollen, the stupid file watcher
package main

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"
)

type paths struct {
	files []string
	dirs  []string
}

type set struct {
	entries map[string]struct{}
}

func newSet(keys []string) *set {
	s := &set{entries: make(map[string]struct{})}
	s.addAll(keys)
	return s
}

func (s *set) addAll(keys []string) {
	for _, k := range keys {
		s.add(k)
	}
}

func (s *set) add(key string) {
	s.entries[key] = struct{}{}
}

func (s *set) del(key string) {
	delete(s.entries, key)
}

func (s set) exists(key string) bool {
	_, ok := s.entries[key]
	return ok
}

func main() {
	cmd := os.Args[1]
	ignore := os.Args[2:]

	action := func() {
		o, err := exec.Command("/bin/sh", "-c", cmd).CombinedOutput()
		if err != nil {
			fmt.Println(err)
			return
		}
		fmt.Println(string(o))
	}

	state := make(chan *paths)
	go func() {
		tick := time.NewTicker(3 * time.Second)
		defer tick.Stop()
		for {
			select {
			case <-tick.C:
				var files []string
				var dirs []string

				filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
					if err != nil {
						fmt.Println(path, err)
						// don't stop walking
						return nil
					}
					if info.IsDir() {
						dirs = append(dirs, path)
					} else {
						files = append(files, path)
					}
					return nil
				})
				state <- &paths{files: files, dirs: dirs}
			}
		}
	}()

	go func() {
		previous := &paths{}
		for {
			select {
			case p := <-state:
				filtered := &paths{}
				for _, v := range p.dirs {
					if ignored(v, ignore) {
						continue
					}
					filtered.dirs = append(filtered.dirs, v)
				}
				for _, v := range p.files {
					if ignored(v, ignore) {
						continue
					}
					filtered.files = append(filtered.files, v)
				}

				//fmt.Printf("%#v\n", filtered)
				if needsAction(previous, filtered) {
					fmt.Println("reloading...")
					go action()
				}

				previous = filtered
			}
		}
	}()

	<-(chan bool)(nil)
}

func needsAction(previous *paths, current *paths) bool {
	if len(previous.dirs) != len(current.dirs) {
		return true
	}

	if len(previous.files) != len(current.files) {
		return true
	}

	uniondirs := newSet(previous.dirs)
	uniondirs.addAll(current.dirs)

	if len(uniondirs.entries) != len(previous.dirs) {
		return true
	}

	unionfiles := newSet(previous.files)
	unionfiles.addAll(current.files)

	if len(unionfiles.entries) != len(previous.files) {
		return true
	}

	for _, entry := range current.files {
		if info, err := os.Stat(entry); err == nil {
			// check if file has been modified in the last couple of seconds
			since := time.Now().Add(-3 * time.Second)
			if since.Before(info.ModTime()) {
				fmt.Println("changed:", entry)
				return true
			}
		}
	}

	return false
}

func ignored(v string, ignore []string) bool {
	for _, ignore := range ignore {
		if strings.HasPrefix(v, ignore) {
			return true
		}
	}
	return false
}
<commit_msg>only restart when build succeeds<commit_after>// pollen, the stupid file watcher
package main

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"
)

type paths struct {
	files []string
	dirs  []string
}

type set struct {
	entries map[string]struct{}
}

func newSet(keys []string) *set {
	s := &set{entries: make(map[string]struct{})}
	s.addAll(keys)
	return s
}

func (s *set) addAll(keys []string) {
	for _, k := range keys {
		s.add(k)
	}
}

func (s *set) add(key string) {
	s.entries[key] = struct{}{}
}

func (s *set) del(key string) {
	delete(s.entries, key)
}

func (s set) exists(key string) bool {
	_, ok := s.entries[key]
	return ok
}

func main() {
	buildCmd := os.Args[1]
	restartCmd := os.Args[2]
	ignore := os.Args[3:]

	action := func() {
		{
			fmt.Println("building...")
			o, err := exec.Command("/bin/sh", "-c", buildCmd).CombinedOutput()
			if err != nil {
				fmt.Println(err)
				return
			}
			fmt.Println(string(o))
		}
		{
			fmt.Println("restarting...")
			o, err := exec.Command("/bin/sh", "-c", restartCmd).CombinedOutput()
			if err != nil {
				fmt.Println(err)
				return
			}
			fmt.Println(string(o))
		}
	}

	state := make(chan *paths)
	go func() {
		tick := time.NewTicker(3 * time.Second)
		defer tick.Stop()
		for {
			select {
			case <-tick.C:
				var files []string
				var dirs []string

				filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
					if err != nil {
						fmt.Println(path, err)
						// don't stop walking
						return nil
					}
					if info.IsDir() {
						dirs = append(dirs, path)
					} else {
						files = append(files, path)
					}
					return nil
				})
				state <- &paths{files: files, dirs: dirs}
			}
		}
	}()

	go func() {
		previous := &paths{}
		for {
			select {
			case p := <-state:
				filtered := &paths{}
				for _, v := range p.dirs {
					if ignored(v, ignore) {
						continue
					}
					filtered.dirs = append(filtered.dirs, v)
				}
				for _, v := range p.files {
					if ignored(v, ignore) {
						continue
					}
					filtered.files = append(filtered.files, v)
				}

				//fmt.Printf("%#v\n", filtered)
				if needsAction(previous, filtered) {
					go action()
				}

				previous = filtered
			}
		}
	}()

	<-(chan bool)(nil)
}

func needsAction(previous *paths, current *paths) bool {
	if len(previous.dirs) != len(current.dirs) {
		return true
	}

	if len(previous.files) != len(current.files) {
		return true
	}

	uniondirs := newSet(previous.dirs)
	uniondirs.addAll(current.dirs)

	if len(uniondirs.entries) != len(previous.dirs) {
		return true
	}

	unionfiles := newSet(previous.files)
	unionfiles.addAll(current.files)

	if len(unionfiles.entries) != len(previous.files) {
		return true
	}

	for _, entry := range current.files {
		if info, err := os.Stat(entry); err == nil {
			// check if file has been modified in the last couple of seconds
			since := time.Now().Add(-3 * time.Second)
			if since.Before(info.ModTime()) {
				fmt.Println("changed:", entry)
				return true
			}
		}
	}

	return false
}

func ignored(v string, ignore []string) bool {
	for _, ignore := range ignore {
		if strings.HasPrefix(v, ignore) {
			return true
		}
	}
	return false
}
<|endoftext|>


<commit_before>// Copyright (C) 2015 Scaleway. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE.md file.

// Manage BareMetal Servers from Command Line (as easily as with Docker)
package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"

	log "github.com/scaleway/scaleway-cli/vendor/github.com/Sirupsen/logrus"
	flag "github.com/scaleway/scaleway-cli/vendor/github.com/docker/docker/pkg/mflag"

	"github.com/scaleway/scaleway-cli/api"
	cmds "github.com/scaleway/scaleway-cli/commands"
	"github.com/scaleway/scaleway-cli/scwversion"
	"github.com/scaleway/scaleway-cli/utils"
)

// CommandListOpts holds a list of parameters
type CommandListOpts struct {
	Values *[]string
}

// NewListOpts create an empty CommandListOpts
func NewListOpts() CommandListOpts {
	var values []string
	return CommandListOpts{
		Values: &values,
	}
}

// String returns a string representation of a CommandListOpts object
func (opts *CommandListOpts) String() string {
	return fmt.Sprintf("%v", []string((*opts.Values)))
}

// Set appends a new value to a CommandListOpts
func (opts *CommandListOpts) Set(value string) error {
	(*opts.Values) = append((*opts.Values), value)
	return nil
}

func commandUsage(name string) {
}

var (
	flAPIEndPoint *string
	flDebug       = flag.Bool([]string{"D", "-debug"}, false, "Enable debug mode")
	flVerbose     = flag.Bool([]string{"V", "-verbose"}, false, "Enable verbose mode")
	flVersion     = flag.Bool([]string{"v", "-version"}, false, "Print version information and quit")
	flSensitive   = flag.Bool([]string{"-sensitive"}, false, "Show sensitive data in outputs, i.e. API Token/Organization")
)

func main() {
	config, cfgErr := getConfig()
	if cfgErr != nil && !os.IsNotExist(cfgErr) {
		log.Fatalf("Unable to open .scwrc config file: %v", cfgErr)
	}

	if config != nil {
		flAPIEndPoint = flag.String([]string{"-api-endpoint"}, config.APIEndPoint, "Set the API endpoint")
	}
	flag.Parse()

	if *flVersion {
		showVersion()
		return
	}

	if flAPIEndPoint != nil {
		os.Setenv("scaleway_api_endpoint", *flAPIEndPoint)
	}

	if *flSensitive {
		os.Setenv("SCW_SENSITIVE", "1")
	}

	if *flDebug {
		os.Setenv("DEBUG", "1")
	}

	if *flVerbose {
		os.Setenv("VERBOSE", "1")
	}

	initLogging(os.Getenv("DEBUG") != "", os.Getenv("VERBOSE") != "")

	args := flag.Args()
	if len(args) < 1 {
		usage()
	}
	name := args[0]

	args = args[1:]

	for _, cmd := range cmds.Commands {
		if cmd.Name() == name {
			cmd.Flag.SetOutput(ioutil.Discard)
			err := cmd.Flag.Parse(args)
			if err != nil {
				log.Fatalf("usage: scw %s", cmd.UsageLine)
			}
			if cmd.Name() != "login" && cmd.Name() != "help" && cmd.Name() != "version" {
				if cfgErr != nil {
					if name != "login" && config == nil {
						fmt.Fprintf(os.Stderr, "You need to login first: 'scw login'\n")
						os.Exit(1)
					}
				}
				api, err := getScalewayAPI()
				if err != nil {
					log.Fatalf("unable to initialize scw api: %s", err)
				}
				cmd.API = api
			}
			cmd.Exec(cmd, cmd.Flag.Args())
			if cmd.API != nil {
				cmd.API.Sync()
			}
			os.Exit(0)
		}
	}

	log.Fatalf("scw: unknown subcommand %s\nRun 'scw help' for usage.", name)
}

func usage() {
	cmds.CmdHelp.Exec(cmds.CmdHelp, []string{})
	os.Exit(1)
}

// getConfig returns the Scaleway CLI config file for the current user
func getConfig() (*api.Config, error) {
	scwrcPath, err := utils.GetConfigFilePath()
	if err != nil {
		return nil, err
	}

	stat, err := os.Stat(scwrcPath)
	// we don't care if it fails, the user just won't see the warning
	if err == nil {
		mode := stat.Mode()
		if mode&0066 != 0 {
			log.Fatalf("Permissions %#o for .scwrc are too open.", mode)
		}
	}

	file, err := ioutil.ReadFile(scwrcPath)
	if err != nil {
		return nil, err
	}
	var config api.Config
	err = json.Unmarshal(file, &config)
	if err != nil {
		return nil, err
	}
	if os.Getenv("scaleway_api_endpoint") == "" {
		os.Setenv("scaleway_api_endpoint", config.APIEndPoint)
	}
	return &config, nil
}

// getScalewayAPI returns a ScalewayAPI using the user config file
func getScalewayAPI() (*api.ScalewayAPI, error) {
	// We already get config globally, but whis way we can get explicit error when trying to create a ScalewayAPI object
	config, err := getConfig()
	if err != nil {
		return nil, err
	}
	return api.NewScalewayAPI(os.Getenv("scaleway_api_endpoint"), config.Organization, config.Token)
}

func showVersion() {
	fmt.Printf("scw version %s, build %s\n", scwversion.VERSION, scwversion.GITCOMMIT)
}

func initLogging(debug bool, verbose bool) {
	log.SetOutput(os.Stderr)
	if debug {
		log.SetLevel(log.DebugLevel)
	} else if verbose {
		log.SetLevel(log.InfoLevel)
	} else {
		log.SetLevel(log.WarnLevel)
	}
}
<commit_msg>Don't set up the VERBOSE header<commit_after>// Copyright (C) 2015 Scaleway. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE.md file.

// Manage BareMetal Servers from Command Line (as easily as with Docker)
package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"

	log "github.com/scaleway/scaleway-cli/vendor/github.com/Sirupsen/logrus"
	flag "github.com/scaleway/scaleway-cli/vendor/github.com/docker/docker/pkg/mflag"

	"github.com/scaleway/scaleway-cli/api"
	cmds "github.com/scaleway/scaleway-cli/commands"
	"github.com/scaleway/scaleway-cli/scwversion"
	"github.com/scaleway/scaleway-cli/utils"
)

// CommandListOpts holds a list of parameters
type CommandListOpts struct {
	Values *[]string
}

// NewListOpts create an empty CommandListOpts
func NewListOpts() CommandListOpts {
	var values []string
	return CommandListOpts{
		Values: &values,
	}
}

// String returns a string representation of a CommandListOpts object
func (opts *CommandListOpts) String() string {
	return fmt.Sprintf("%v", []string((*opts.Values)))
}

// Set appends a new value to a CommandListOpts
func (opts *CommandListOpts) Set(value string) error {
	(*opts.Values) = append((*opts.Values), value)
	return nil
}

func commandUsage(name string) {
}

var (
	flAPIEndPoint *string
	flDebug       = flag.Bool([]string{"D", "-debug"}, false, "Enable debug mode")
	flVerbose     = flag.Bool([]string{"V", "-verbose"}, false, "Enable verbose mode")
	flVersion     = flag.Bool([]string{"v", "-version"}, false, "Print version information and quit")
	flSensitive   = flag.Bool([]string{"-sensitive"}, false, "Show sensitive data in outputs, i.e. API Token/Organization")
)

func main() {
	config, cfgErr := getConfig()
	if cfgErr != nil && !os.IsNotExist(cfgErr) {
		log.Fatalf("Unable to open .scwrc config file: %v", cfgErr)
	}

	if config != nil {
		flAPIEndPoint = flag.String([]string{"-api-endpoint"}, config.APIEndPoint, "Set the API endpoint")
	}
	flag.Parse()

	if *flVersion {
		showVersion()
		return
	}

	if flAPIEndPoint != nil {
		os.Setenv("scaleway_api_endpoint", *flAPIEndPoint)
	}

	if *flSensitive {
		os.Setenv("SCW_SENSITIVE", "1")
	}

	if *flDebug {
		os.Setenv("DEBUG", "1")
	}

	initLogging(os.Getenv("DEBUG") != "", *flVerbose)

	args := flag.Args()
	if len(args) < 1 {
		usage()
	}
	name := args[0]

	args = args[1:]

	for _, cmd := range cmds.Commands {
		if cmd.Name() == name {
			cmd.Flag.SetOutput(ioutil.Discard)
			err := cmd.Flag.Parse(args)
			if err != nil {
				log.Fatalf("usage: scw %s", cmd.UsageLine)
			}
			if cmd.Name() != "login" && cmd.Name() != "help" && cmd.Name() != "version" {
				if cfgErr != nil {
					if name != "login" && config == nil {
						fmt.Fprintf(os.Stderr, "You need to login first: 'scw login'\n")
						os.Exit(1)
					}
				}
				api, err := getScalewayAPI()
				if err != nil {
					log.Fatalf("unable to initialize scw api: %s", err)
				}
				cmd.API = api
			}
			cmd.Exec(cmd, cmd.Flag.Args())
			if cmd.API != nil {
				cmd.API.Sync()
			}
			os.Exit(0)
		}
	}

	log.Fatalf("scw: unknown subcommand %s\nRun 'scw help' for usage.", name)
}

func usage() {
	cmds.CmdHelp.Exec(cmds.CmdHelp, []string{})
	os.Exit(1)
}

// getConfig returns the Scaleway CLI config file for the current user
func getConfig() (*api.Config, error) {
	scwrcPath, err := utils.GetConfigFilePath()
	if err != nil {
		return nil, err
	}

	stat, err := os.Stat(scwrcPath)
	// we don't care if it fails, the user just won't see the warning
	if err == nil {
		mode := stat.Mode()
		if mode&0066 != 0 {
			log.Fatalf("Permissions %#o for .scwrc are too open.", mode)
		}
	}

	file, err := ioutil.ReadFile(scwrcPath)
	if err != nil {
		return nil, err
	}
	var config api.Config
	err = json.Unmarshal(file, &config)
	if err != nil {
		return nil, err
	}
	if os.Getenv("scaleway_api_endpoint") == "" {
		os.Setenv("scaleway_api_endpoint", config.APIEndPoint)
	}
	return &config, nil
}

// getScalewayAPI returns a ScalewayAPI using the user config file
func getScalewayAPI() (*api.ScalewayAPI, error) {
	// We already get config globally, but whis way we can get explicit error when trying to create a ScalewayAPI object
	config, err := getConfig()
	if err != nil {
		return nil, err
	}
	return api.NewScalewayAPI(os.Getenv("scaleway_api_endpoint"), config.Organization, config.Token)
}

func showVersion() {
	fmt.Printf("scw version %s, build %s\n", scwversion.VERSION, scwversion.GITCOMMIT)
}

func initLogging(debug bool, verbose bool) {
	log.SetOutput(os.Stderr)
	if debug {
		log.SetLevel(log.DebugLevel)
	} else if verbose {
		log.SetLevel(log.InfoLevel)
	} else {
		log.SetLevel(log.WarnLevel)
	}
}
<|endoftext|>