<commit_before>package main

import (
	"errors"
	"fmt"
	"go/build"
	"log"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"strings"

	cli "github.com/codegangsta/cli"
	rw "github.com/whyrusleeping/gx-go-tool/rewrite"
	gx "github.com/whyrusleeping/gx/gxutil"
)

func main() {
	app := cli.NewApp()
	app.Name = "gx-go-tool"
	app.Author = "whyrusleeping"
	app.Version = "0.2.0"

	var UpdateCommand = cli.Command{
		Name:      "update",
		Usage:     "update a packages imports to a new path",
		ArgsUsage: "[old import] [new import]",
		Action: func(c *cli.Context) {
			if len(c.Args()) < 2 {
				fmt.Println("must specify current and new import names")
				return
			}

			oldimp := c.Args()[0]
			newimp := c.Args()[1]

			curpath, err := os.Getwd()
			if err != nil {
				fmt.Println("error getting working dir: ", err)
				return
			}

			rwf := func(in string) string {
				if in == oldimp {
					return newimp
				}
				return in
			}

			filter := func(in string) bool {
				return strings.HasSuffix(in, ".go")
			}

			err = rw.RewriteImports(curpath, rwf, filter)
			if err != nil {
				fmt.Println(err)
				return
			}
		},
	}

	var ImportCommand = cli.Command{
		Name:  "import",
		Usage: "import a go package and all its depencies into gx",
		Flags: []cli.Flag{
			cli.BoolFlag{
				Name:  "rewrite",
				Usage: "rewrite import paths to use vendored packages",
			},
		},
		Action: func(c *cli.Context) {
			importer, err := NewImporter(c.Bool("rewrite"))
			if err != nil {
				fmt.Println(err)
				return
			}

			if !c.Args().Present() {
				fmt.Println("must specify a package name")
				return
			}

			pkg := c.Args().First()
			fmt.Printf("vendoring package %s\n", pkg)

			_, err = importer.GxPublishGoPackage(pkg)
			if err != nil {
				log.Println(err)
				return
			}
		},
	}

	var PathCommand = cli.Command{
		Name:  "path",
		Usage: "prints the import path of the current package within GOPATH",
		Action: func(c *cli.Context) {
			gopath := os.Getenv("GOPATH")
			if gopath == "" {
				fmt.Println("GOPATH not set, cannot derive import path")
				return
			}

			cwd, err := os.Getwd()
			if err != nil {
				fmt.Println(err)
				os.Exit(1)
			}

			srcdir := path.Join(gopath, "src")
			srcdir += "/"

			if !strings.HasPrefix(cwd, srcdir) {
				fmt.Println("package not within GOPATH/src")
				os.Exit(1)
			}

			rel := cwd[len(srcdir):]
			fmt.Println(rel)
		},
	}

	app.Commands = []cli.Command{
		UpdateCommand,
		ImportCommand,
		PathCommand,
	}

	app.Run(os.Args)
}

func pathIsNotStdlib(path string) bool {
	first := strings.Split(path, "/")[0]

	if len(strings.Split(first, ".")) > 1 {
		return true
	}
	return false
}

type Importer struct {
	pkgs    map[string]*gx.Dependency
	gopath  string
	pm      *gx.PM
	rewrite bool
}

func NewImporter(rw bool) (*Importer, error) {
	gp, err := getGoPath()
	if err != nil {
		return nil, err
	}

	return &Importer{
		pkgs:    make(map[string]*gx.Dependency),
		gopath:  gp,
		pm:      gx.NewPM(),
		rewrite: rw,
	}, nil
}

func getGoPath() (string, error) {
	gopath := os.Getenv("GOPATH")
	if gopath == "" {
		return "", errors.New("gopath not set")
	}
	return gopath, nil
}

func (i *Importer) GxPublishGoPackage(imppath string) (*gx.Dependency, error) {
	if d, ok := i.pkgs[imppath]; ok {
		return d, nil
	}

	// make sure its local
	err := GoGet(imppath)
	if err != nil {
		return nil, err
	}

	pkgpath := path.Join(i.gopath, "src", imppath)
	pkgFilePath := path.Join(pkgpath, gx.PkgFileName)
	pkg, err := gx.LoadPackageFile(pkgFilePath)
	if err != nil {
		if !os.IsNotExist(err) {
			return nil, err
		}

		// init as gx package
		parts := strings.Split(imppath, "/")
		pkgname := parts[len(parts)-1]
		err = gx.InitPkg(pkgpath, pkgname, "go")
		if err != nil {
			return nil, err
		}

		pkg, err = gx.LoadPackageFile(pkgFilePath)
		if err != nil {
			return nil, err
		}
	}

	// recurse!
	gopkg, err := build.Import(imppath, "", 0)
	if err != nil {
		return nil, err
	}

	var depsToVendor []string

	for _, child := range gopkg.Imports {
		if pathIsNotStdlib(child) {
			depsToVendor = append(depsToVendor, child)
		}
	}

	for n, child := range depsToVendor {
		fmt.Printf("- processing dep %s for %s [%d / %d]\n", child, imppath, n+1, len(depsToVendor))
		childdep, err := i.GxPublishGoPackage(child)
		if err != nil {
			return nil, err
		}

		pkg.Dependencies = append(pkg.Dependencies, childdep)
	}

	err = gx.SavePackageFile(pkg, pkgFilePath)
	if err != nil {
		return nil, err
	}

	if i.rewrite {
		fullpkgpath, err := filepath.Abs(pkgpath)
		if err != nil {
			return nil, err
		}

		err = i.rewriteImports(fullpkgpath)
		if err != nil {
			return nil, err
		}
	}

	hash, err := i.pm.PublishPackage(pkgpath, pkg)
	if err != nil {
		return nil, err
	}

	fmt.Printf("published %s as %s\n", imppath, hash)

	dep := &gx.Dependency{
		Hash: hash,
		Name: pkg.Name,
	}
	i.pkgs[imppath] = dep
	return dep, nil
}

func (i *Importer) rewriteImports(pkgpath string) error {

	filter := func(p string) bool {
		return !strings.HasPrefix(p, "vendor") &&
			!strings.HasPrefix(p, ".git") &&
			strings.HasSuffix(p, ".go")
	}

	rwf := func(in string) string {
		dep, ok := i.pkgs[in]
		if !ok {
			return in
		}

		return dep.Hash + "/" + dep.Name
	}

	return rw.RewriteImports(pkgpath, rwf, filter)
}

// TODO: take an option to grab packages from local GOPATH
func GoGet(path string) error {
	out, err := exec.Command("go", "get", path).CombinedOutput()
	if err != nil {
		return fmt.Errorf("go get failed: %s - %s", string(out), err)
	}
	return nil
}
<commit_msg>interactive imports<commit_after>package main

import (
	"bufio"
	"errors"
	"fmt"
	"go/build"
	"log"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"strings"

	cli "github.com/codegangsta/cli"
	rw "github.com/whyrusleeping/gx-go-tool/rewrite"
	gx "github.com/whyrusleeping/gx/gxutil"
)

func main() {
	app := cli.NewApp()
	app.Name = "gx-go-tool"
	app.Author = "whyrusleeping"
	app.Version = "0.2.0"

	var UpdateCommand = cli.Command{
		Name:      "update",
		Usage:     "update a packages imports to a new path",
		ArgsUsage: "[old import] [new import]",
		Action: func(c *cli.Context) {
			if len(c.Args()) < 2 {
				fmt.Println("must specify current and new import names")
				return
			}

			oldimp := c.Args()[0]
			newimp := c.Args()[1]

			curpath, err := os.Getwd()
			if err != nil {
				fmt.Println("error getting working dir: ", err)
				return
			}

			rwf := func(in string) string {
				if in == oldimp {
					return newimp
				}
				return in
			}

			filter := func(in string) bool {
				return strings.HasSuffix(in, ".go")
			}

			err = rw.RewriteImports(curpath, rwf, filter)
			if err != nil {
				fmt.Println(err)
				return
			}
		},
	}

	var ImportCommand = cli.Command{
		Name:  "import",
		Usage: "import a go package and all its depencies into gx",
		Flags: []cli.Flag{
			cli.BoolFlag{
				Name:  "rewrite",
				Usage: "rewrite import paths to use vendored packages",
			},
			cli.BoolFlag{
				Name:  "yesall",
				Usage: "assume defaults for all options",
			},
		},
		Action: func(c *cli.Context) {
			importer, err := NewImporter(c.Bool("rewrite"))
			if err != nil {
				fmt.Println(err)
				return
			}

			importer.yesall = c.Bool("yesall")

			if !c.Args().Present() {
				fmt.Println("must specify a package name")
				return
			}

			pkg := c.Args().First()
			fmt.Printf("vendoring package %s\n", pkg)

			_, err = importer.GxPublishGoPackage(pkg)
			if err != nil {
				log.Println(err)
				return
			}
		},
	}

	var PathCommand = cli.Command{
		Name:  "path",
		Usage: "prints the import path of the current package within GOPATH",
		Action: func(c *cli.Context) {
			gopath := os.Getenv("GOPATH")
			if gopath == "" {
				fmt.Println("GOPATH not set, cannot derive import path")
				return
			}

			cwd, err := os.Getwd()
			if err != nil {
				fmt.Println(err)
				os.Exit(1)
			}

			srcdir := path.Join(gopath, "src")
			srcdir += "/"

			if !strings.HasPrefix(cwd, srcdir) {
				fmt.Println("package not within GOPATH/src")
				os.Exit(1)
			}

			rel := cwd[len(srcdir):]
			fmt.Println(rel)
		},
	}

	app.Commands = []cli.Command{
		UpdateCommand,
		ImportCommand,
		PathCommand,
	}

	app.Run(os.Args)
}

func pathIsNotStdlib(path string) bool {
	first := strings.Split(path, "/")[0]

	if len(strings.Split(first, ".")) > 1 {
		return true
	}
	return false
}

type Importer struct {
	pkgs    map[string]*gx.Dependency
	gopath  string
	pm      *gx.PM
	rewrite bool
	yesall  bool
}

func NewImporter(rw bool) (*Importer, error) {
	gp, err := getGoPath()
	if err != nil {
		return nil, err
	}

	cfg, err := gx.LoadConfig()
	if err != nil {
		return nil, err
	}

	return &Importer{
		pkgs:    make(map[string]*gx.Dependency),
		gopath:  gp,
		pm:      gx.NewPM(cfg),
		rewrite: rw,
	}, nil
}

func getGoPath() (string, error) {
	gopath := os.Getenv("GOPATH")
	if gopath == "" {
		return "", errors.New("gopath not set")
	}
	return gopath, nil
}

func (i *Importer) GxPublishGoPackage(imppath string) (*gx.Dependency, error) {
	if d, ok := i.pkgs[imppath]; ok {
		return d, nil
	}

	// make sure its local
	err := GoGet(imppath)
	if err != nil {
		return nil, err
	}

	pkgpath := path.Join(i.gopath, "src", imppath)
	pkgFilePath := path.Join(pkgpath, gx.PkgFileName)
	pkg, err := gx.LoadPackageFile(pkgFilePath)
	if err != nil {
		if !os.IsNotExist(err) {
			return nil, err
		}

		// init as gx package
		parts := strings.Split(imppath, "/")
		pkgname := parts[len(parts)-1]
		if !i.yesall {
			p := fmt.Sprintf("enter name for import '%s'", imppath)
			nname, err := prompt(p, pkgname)
			if err != nil {
				return nil, err
			}

			pkgname = nname
		}

		err = i.pm.InitPkg(pkgpath, pkgname, "go")
		if err != nil {
			return nil, err
		}

		pkg, err = gx.LoadPackageFile(pkgFilePath)
		if err != nil {
			return nil, err
		}
	}

	// recurse!
	gopkg, err := build.Import(imppath, "", 0)
	if err != nil {
		return nil, err
	}

	var depsToVendor []string

	for _, child := range gopkg.Imports {
		if pathIsNotStdlib(child) {
			depsToVendor = append(depsToVendor, child)
		}
	}

	for n, child := range depsToVendor {
		fmt.Printf("- processing dep %s for %s [%d / %d]\n", child, imppath, n+1, len(depsToVendor))
		childdep, err := i.GxPublishGoPackage(child)
		if err != nil {
			return nil, err
		}

		pkg.Dependencies = append(pkg.Dependencies, childdep)
	}

	err = gx.SavePackageFile(pkg, pkgFilePath)
	if err != nil {
		return nil, err
	}

	if i.rewrite {
		fullpkgpath, err := filepath.Abs(pkgpath)
		if err != nil {
			return nil, err
		}

		err = i.rewriteImports(fullpkgpath)
		if err != nil {
			return nil, err
		}
	}

	hash, err := i.pm.PublishPackage(pkgpath, pkg)
	if err != nil {
		return nil, err
	}

	fmt.Printf("published %s as %s\n", imppath, hash)

	dep := &gx.Dependency{
		Hash: hash,
		Name: pkg.Name,
	}
	i.pkgs[imppath] = dep
	return dep, nil
}

func (i *Importer) rewriteImports(pkgpath string) error {

	filter := func(p string) bool {
		return !strings.HasPrefix(p, "vendor") &&
			!strings.HasPrefix(p, ".git") &&
			strings.HasSuffix(p, ".go")
	}

	rwf := func(in string) string {
		dep, ok := i.pkgs[in]
		if !ok {
			return in
		}

		return dep.Hash + "/" + dep.Name
	}

	return rw.RewriteImports(pkgpath, rwf, filter)
}

// TODO: take an option to grab packages from local GOPATH
func GoGet(path string) error {
	out, err := exec.Command("go", "get", path).CombinedOutput()
	if err != nil {
		return fmt.Errorf("go get failed: %s - %s", string(out), err)
	}
	return nil
}

func prompt(text, def string) (string, error) {
	scan := bufio.NewScanner(os.Stdin)
	fmt.Printf("%s (default: '%s') ", text, def)
	for scan.Scan() {
		if scan.Text() != "" {
			return scan.Text(), nil
		}
		return def, nil
	}

	return "", scan.Err()
}
<|endoftext|>


<commit_before>package main

import (
	"os"

	log "github.com/Sirupsen/logrus"
	"github.com/clinta/docker-vxlan-plugin/vxlan"
	"github.com/docker/go-plugins-helpers/network"
	"github.com/codegangsta/cli"
)

const (
	version = "0.2.5"
)

func main() {

	var flagDebug = cli.BoolFlag{
		Name:  "debug, d",
		Usage: "enable debugging",
	}
	var flagScope = cli.StringFlag{
		Name:  "scope",
		Value: "local",
		Usage: "Scope of the network. local or global.",
	}
	var flagVtepDev = cli.StringFlag{
		Name:  "vtepdev",
		Value: "",
		Usage: "VTEP device.",
	}
	app := cli.NewApp()
	app.Name = "don"
	app.Usage = "Docker vxLan Networking"
	app.Version = version
	app.Flags = []cli.Flag{
		flagDebug,
		flagScope,
		flagVtepDev,
	}
	app.Action = Run
	app.Run(os.Args)
}

// Run initializes the driver
func Run(ctx *cli.Context) {
	if ctx.Bool("debug") {
		log.SetLevel(log.DebugLevel)
	}
	d, err := vxlan.NewDriver(ctx.String("scope"), ctx.String("vtepdev"))
	if err != nil {
		panic(err)
	}
	h := network.NewHandler(d)
	h.ServeUnix("root", "vxlan")
}
<commit_msg>log format text with timestamp<commit_after>package main

import (
	"os"

	log "github.com/Sirupsen/logrus"
	"github.com/clinta/docker-vxlan-plugin/vxlan"
	"github.com/docker/go-plugins-helpers/network"
	"github.com/codegangsta/cli"
)

const (
	version = "0.2.5"
)

func main() {

	var flagDebug = cli.BoolFlag{
		Name:  "debug, d",
		Usage: "enable debugging",
	}
	var flagScope = cli.StringFlag{
		Name:  "scope",
		Value: "local",
		Usage: "Scope of the network. local or global.",
	}
	var flagVtepDev = cli.StringFlag{
		Name:  "vtepdev",
		Value: "",
		Usage: "VTEP device.",
	}
	app := cli.NewApp()
	app.Name = "don"
	app.Usage = "Docker vxLan Networking"
	app.Version = version
	app.Flags = []cli.Flag{
		flagDebug,
		flagScope,
		flagVtepDev,
	}
	app.Action = Run
	app.Run(os.Args)
}

// Run initializes the driver
func Run(ctx *cli.Context) {
	if ctx.Bool("debug") {
		log.SetLevel(log.DebugLevel)
	}
	log.SetFormatter(&log.TextFormatter{
		ForceColors: false,
		DisableColors: true,
		DisableTimestamp: false,
		FullTimestamp: true,
	})
	d, err := vxlan.NewDriver(ctx.String("scope"), ctx.String("vtepdev"))
	if err != nil {
		panic(err)
	}
	h := network.NewHandler(d)
	h.ServeUnix("root", "vxlan")
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strings"
)

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

func main() {

	github_user := os.Getenv("GITHUB_USER")
	github_password := os.Getenv("GITHUB_PASSWORD")

	json := `{
	"name": "web",
	"config": {"url": "http://services.scraperwiki.com/hook",
		"content_type": "json"},
	"events": ["push", "issues", "issue_comment",
		"commit_comment", "create", "delete",
		"pull_request", "pull_request_review_comment",
		"gollum", "watch", "release", "fork", "member",
		"public", "team_add", "status"],
	"active": true
	}`

	endpoint := "https://" + github_user + ":" + github_password + "@" + "api.github.com"

	repos := []string{
		"scraperwiki/custard",
		"scraperwiki/tang",
	}

	for _, repo := range repos {

		buffer := strings.NewReader(json)
		resp, err := http.Post(endpoint+"/repos/"+repo+"/hooks", "application/json", buffer)
		check(err)

		log.Println("Rate Limit:", resp.Header["X-Ratelimit-Remaining"][0])

		switch resp.StatusCode {
		default:
			response, err := ioutil.ReadAll(resp.Body)
			check(err)

			log.Print(string(response))

		case 422:
			log.Println("Already hooked for", repo)
		}
	}

	http.HandleFunc("/hook", handleRoot)
	log.Fatal(http.ListenAndServe(":80", nil))

}

func handleRoot(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello, world!\n")

	request, err := ioutil.ReadAll(r.Body)
	check(err)

	var dst bytes.Buffer
	r.Header.Write(&dst)
	log.Println("Incoming request headers: ", string(dst.Bytes()))

	dst.Reset()
	err = json.Indent(&dst, request, "", "  ")
	check(err)

	var doc_ interface{}
	err = json.Unmarshal(dst.Bytes(), &doc_)
	check(err)
	doc := doc_.(map[string]interface{})

	log.Println("Incoming request:", string(dst.Bytes()))

	switch eventType := r.Header["X-Github-Event"][0]; eventType {
	case "push":

		log.Println("Pushed")
		ref := doc["ref"].(string)
		url := doc["repository"].(map[string]interface{})["url"].(string)
		after := doc["after"].(string)

		log.Println("Push to", url, ref, "after", after)

	default:
		log.Println("Unhandled event:", eventType)
	}

}
<commit_msg>Make Listen address configurable<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strings"
)

var address = flag.String("address", ":8080", "address to listen on")

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

func main() {
	flag.Parse()

	github_user := os.Getenv("GITHUB_USER")
	github_password := os.Getenv("GITHUB_PASSWORD")

	json := `{
	"name": "web",
	"config": {"url": "http://services.scraperwiki.com/hook",
		"content_type": "json"},
	"events": ["push", "issues", "issue_comment",
		"commit_comment", "create", "delete",
		"pull_request", "pull_request_review_comment",
		"gollum", "watch", "release", "fork", "member",
		"public", "team_add", "status"],
	"active": true
	}`

	endpoint := "https://" + github_user + ":" + github_password + "@" + "api.github.com"

	repos := []string{
		"scraperwiki/custard",
		"scraperwiki/tang",
	}

	for _, repo := range repos {

		buffer := strings.NewReader(json)
		resp, err := http.Post(endpoint+"/repos/"+repo+"/hooks", "application/json", buffer)
		check(err)

		log.Println("Rate Limit:", resp.Header["X-Ratelimit-Remaining"][0])

		switch resp.StatusCode {
		default:
			response, err := ioutil.ReadAll(resp.Body)
			check(err)

			log.Print(string(response))

		case 422:
			log.Println("Already hooked for", repo)
		}
	}

	http.HandleFunc("/hook", handleRoot)
	log.Fatal(http.ListenAndServe(*address, nil))

}

func handleRoot(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello, world!\n")

	request, err := ioutil.ReadAll(r.Body)
	check(err)

	var dst bytes.Buffer
	r.Header.Write(&dst)
	log.Println("Incoming request headers: ", string(dst.Bytes()))

	dst.Reset()
	err = json.Indent(&dst, request, "", "  ")
	check(err)

	var doc_ interface{}
	err = json.Unmarshal(dst.Bytes(), &doc_)
	check(err)
	doc := doc_.(map[string]interface{})

	log.Println("Incoming request:", string(dst.Bytes()))

	switch eventType := r.Header["X-Github-Event"][0]; eventType {
	case "push":

		log.Println("Pushed")
		ref := doc["ref"].(string)
		url := doc["repository"].(map[string]interface{})["url"].(string)
		after := doc["after"].(string)

		log.Println("Push to", url, ref, "after", after)

	default:
		log.Println("Unhandled event:", eventType)
	}

}
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, version 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/http/httputil"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
)

var (
	githubToken       string
	githubUser        string
	githubRepo        string
	githubAPIEndpoint string
	// Version gets initialized in compilation time.
	Version string
	debug   bool
)

// Release represents a Github Release.
type Release struct {
	UploadURL  string `json:"upload_url,omitempty"`
	TagName    string `json:"tag_name"`
	Branch     string `json:"target_commitish"`
	Name       string `json:"name"`
	Body       string `json:"body"`
	Draft      bool   `json:"draft"`
	Prerelease bool   `json:"prerelease"`
}

var verFlag bool

func init() {
	log.SetFlags(0)

	debug, _ = strconv.ParseBool(os.Getenv("DEBUG"))

	githubToken = os.Getenv("GITHUB_TOKEN")
	githubUser = os.Getenv("GITHUB_USER")
	githubRepo = os.Getenv("GITHUB_REPO")
	githubAPIEndpoint = os.Getenv("GITHUB_API")

	if githubAPIEndpoint == "" {
		githubAPIEndpoint = "https://api.github.com"
	}

	flag.BoolVar(&verFlag, "version", false, "-version")
	flag.Parse()
}

var usage = `Github command line release tool.

Usage:
	github-release <user/repo> <tag> <branch> <description> "<files>"

Parameters:
	<user/repo>: Github user and repository
	<tag>: Used to created the release. It is also used as the release's name
	<branch>: Reference from where to create the provided <tag>, if it does not exist
	<description>: The release description
	<files>: Glob pattern describing the list of files to include in the release.
	Make sure you enclose it in quotes to avoid the shell expanding the glob pattern.

Options:
	-version: Displays version

Environment variables:
  DEBUG: Allows you to run github-release in debugging mode. DO NOT do this if you are attempting to upload big files.
  GITHUB_TOKEN: Must be set in order to interact with Github's API
  GITHUB_USER: Just in case you want an alternative way of providing your github user
  GITHUB_REPO: Just in case you want an alternative way of providing your github repo
  GITHUB_API: Github API endpoint. Set to https://api.github.com/repos/:github-user/:github-repo by default

Before using this tool make sure you set the environment variable GITHUB_TOKEN
with a valid Github token and correct authorization scopes to allow you to create releases
in your project. For more information about creating Github tokens please read the
official Github documentation at https://help.github.com/articles/creating-an-access-token-for-command-line-use/

Author: https://github.com/c4milo
License: http://mozilla.org/MPL/2.0/
`

func main() {
	if verFlag {
		log.Println(Version)
		return
	}

	if len(os.Args) < 6 {
		log.Fatal(usage)
	}

	userRepo := strings.Split(os.Args[1], "/")
	if len(userRepo) != 2 {
		log.Printf("Error: Invalid format used for username and repository: %s\n\n", os.Args[1])
		log.Fatal(usage)
	}

	if githubToken == "" {
		log.Fatal(`Error: GITHUB_TOKEN environment variable is not set.
Please refer to https://help.github.com/articles/creating-an-access-token-for-command-line-use/ for more help`)
	}

	githubUser = userRepo[0]
	githubRepo = userRepo[1]
	githubAPIEndpoint = fmt.Sprintf("%s/repos/%s/%s", githubAPIEndpoint, githubUser, githubRepo)

	if debug {
		log.Println("Glob pattern received: ")
		log.Println(os.Args[5])
	}

	filepaths, err := filepath.Glob(os.Args[5])
	if err != nil {
		log.Fatalf("Error: Invalid glob pattern: %s\n", os.Args[5])
	}

	if debug {
		log.Println("Expanded glob pattern: ")
		log.Printf("%v\n", filepaths)
	}

	tag := os.Args[2]
	branch := os.Args[3]
	desc := os.Args[4]

	CreateRelease(tag, branch, desc, filepaths)
	log.Println("Done")
}

func uploadFile(uploadURL, path string) {
	file, err := os.Open(path)
	if err != nil {
		log.Printf("Error: %s\n", err.Error())
		return
	}
	defer file.Close()

	size, err := fileSize(file)
	if err != nil {
		log.Printf("Error: %s\n", err.Error())
		return
	}

	filename := filepath.Base(file.Name())
	log.Printf("Uploading %s...\n", filename)
	body, err := doRequest("POST", uploadURL+"?name="+filename, "application/octet-stream", file, size)
	if err != nil {
		log.Printf("Error: %s\n", err.Error())
	}

	if debug {
		log.Println("========= UPLOAD RESPONSE ===========")
		log.Println(string(body[:]))
	}
}

// CreateRelease creates a Github Release, attaching the given files as release assets
// If a release already exist, up in Github, this function will attempt to attach the given files to it.
func CreateRelease(tag, branch, desc string, filepaths []string) {
	endpoint := fmt.Sprintf("%s/releases", githubAPIEndpoint)

	release := Release{
		TagName:    tag,
		Name:       tag,
		Prerelease: false,
		Draft:      false,
		Branch:     branch,
		Body:       desc,
	}

	releaseData, err := json.Marshal(release)
	if err != nil {
		log.Fatalln(err)
	}

	releaseBuffer := bytes.NewBuffer(releaseData)

	data, err := doRequest("POST", endpoint, "application/json", releaseBuffer, int64(releaseBuffer.Len()))
	if err != nil {
		log.Fatalln(err)
	}

	// Gets the release Upload URL from the returned JSON data
	err = json.Unmarshal(data, &release)
	if err != nil {
		log.Fatalln(err)
	}

	// Upload URL comes like this https://uploads.github.com/repos/octocat/Hello-World/releases/1/assets{?name}
	// So we need to remove the {?name} part
	uploadURL := strings.Split(release.UploadURL, "{")[0]

	var wg sync.WaitGroup
	for i := range filepaths {
		wg.Add(1)
		func(index int) {
			uploadFile(uploadURL, filepaths[index])
			wg.Done()
		}(i)
	}
	wg.Wait()
}

func fileSize(file *os.File) (int64, error) {
	stat, err := file.Stat()
	if err != nil {
		return 0, err
	}
	return stat.Size(), nil
}

// Sends HTTP request to Github API
func doRequest(method, url, contentType string, reqBody io.Reader, bodySize int64) ([]byte, error) {
	req, err := http.NewRequest(method, url, reqBody)
	if err != nil {
		return nil, err
	}

	req.Header.Set("Authorization", fmt.Sprintf("token %s", githubToken))
	req.Header.Set("Content-type", contentType)
	req.Header.Set("Accept", "application/vnd.github.v3+json")
	req.ContentLength = bodySize

	if debug {
		log.Println("================ REQUEST DUMP ==================")
		dump, err := httputil.DumpRequestOut(req, true)
		if err != nil {
			log.Println(err.Error())
		}
		log.Println(string(dump[:]))
	}

	resp, err := http.DefaultClient.Do(req)

	if debug {
		log.Println("================ RESPONSE DUMP ==================")
		dump, err := httputil.DumpResponse(resp, true)
		if err != nil {
			log.Println(err.Error())
		}
		log.Println(string(dump[:]))
	}

	if err != nil {
		return nil, err
	}

	defer resp.Body.Close()

	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
		return nil, fmt.Errorf("Github returned an error:\n Code: %s. \n Body: %s", resp.Status, respBody)
	}

	return respBody, nil
}
<commit_msg>If creating a release fails then try attaching the files to an existing release.<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, version 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/http/httputil"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
)

var (
	githubToken       string
	githubUser        string
	githubRepo        string
	githubAPIEndpoint string
	// Version gets initialized in compilation time.
	Version string
	debug   bool
)

// Release represents a Github Release.
type Release struct {
	UploadURL  string `json:"upload_url,omitempty"`
	TagName    string `json:"tag_name"`
	Branch     string `json:"target_commitish"`
	Name       string `json:"name"`
	Body       string `json:"body"`
	Draft      bool   `json:"draft"`
	Prerelease bool   `json:"prerelease"`
}

var verFlag bool

func init() {
	log.SetFlags(0)

	debug, _ = strconv.ParseBool(os.Getenv("DEBUG"))

	githubToken = os.Getenv("GITHUB_TOKEN")
	githubUser = os.Getenv("GITHUB_USER")
	githubRepo = os.Getenv("GITHUB_REPO")
	githubAPIEndpoint = os.Getenv("GITHUB_API")

	if githubAPIEndpoint == "" {
		githubAPIEndpoint = "https://api.github.com"
	}

	flag.BoolVar(&verFlag, "version", false, "-version")
	flag.Parse()
}

var usage = `Github command line release tool.

Usage:
	github-release <user/repo> <tag> <branch> <description> "<files>"

Parameters:
	<user/repo>: Github user and repository
	<tag>: Used to created the release. It is also used as the release's name
	<branch>: Reference from where to create the provided <tag>, if it does not exist
	<description>: The release description
	<files>: Glob pattern describing the list of files to include in the release.
	Make sure you enclose it in quotes to avoid the shell expanding the glob pattern.

Options:
	-version: Displays version

Environment variables:
  DEBUG: Allows you to run github-release in debugging mode. DO NOT do this if you are attempting to upload big files.
  GITHUB_TOKEN: Must be set in order to interact with Github's API
  GITHUB_USER: Just in case you want an alternative way of providing your github user
  GITHUB_REPO: Just in case you want an alternative way of providing your github repo
  GITHUB_API: Github API endpoint. Set to https://api.github.com/repos/:github-user/:github-repo by default

Before using this tool make sure you set the environment variable GITHUB_TOKEN
with a valid Github token and correct authorization scopes to allow you to create releases
in your project. For more information about creating Github tokens please read the
official Github documentation at https://help.github.com/articles/creating-an-access-token-for-command-line-use/

Author: https://github.com/c4milo
License: http://mozilla.org/MPL/2.0/
`

func main() {
	if verFlag {
		log.Println(Version)
		return
	}

	if len(os.Args) < 6 {
		log.Fatal(usage)
	}

	userRepo := strings.Split(os.Args[1], "/")
	if len(userRepo) != 2 {
		log.Printf("Error: Invalid format used for username and repository: %s\n\n", os.Args[1])
		log.Fatal(usage)
	}

	if githubToken == "" {
		log.Fatal(`Error: GITHUB_TOKEN environment variable is not set.
Please refer to https://help.github.com/articles/creating-an-access-token-for-command-line-use/ for more help`)
	}

	githubUser = userRepo[0]
	githubRepo = userRepo[1]
	githubAPIEndpoint = fmt.Sprintf("%s/repos/%s/%s", githubAPIEndpoint, githubUser, githubRepo)

	if debug {
		log.Println("Glob pattern received: ")
		log.Println(os.Args[5])
	}

	filepaths, err := filepath.Glob(os.Args[5])
	if err != nil {
		log.Fatalf("Error: Invalid glob pattern: %s\n", os.Args[5])
	}

	if debug {
		log.Println("Expanded glob pattern: ")
		log.Printf("%v\n", filepaths)
	}

	tag := os.Args[2]
	branch := os.Args[3]
	desc := os.Args[4]

	CreateRelease(tag, branch, desc, filepaths)
	log.Println("Done")
}

func uploadFile(uploadURL, path string) {
	file, err := os.Open(path)
	if err != nil {
		log.Printf("Error: %s\n", err.Error())
		return
	}
	defer file.Close()

	size, err := fileSize(file)
	if err != nil {
		log.Printf("Error: %s\n", err.Error())
		return
	}

	filename := filepath.Base(file.Name())
	log.Printf("Uploading %s...\n", filename)
	body, err := doRequest("POST", uploadURL+"?name="+filename, "application/octet-stream", file, size)
	if err != nil {
		log.Printf("Error: %s\n", err.Error())
	}

	if debug {
		log.Println("========= UPLOAD RESPONSE ===========")
		log.Println(string(body[:]))
	}
}

// CreateRelease creates a Github Release, attaching the given files as release assets
// If a release already exist, up in Github, this function will attempt to attach the given files to it.
func CreateRelease(tag, branch, desc string, filepaths []string) {
	endpoint := fmt.Sprintf("%s/releases", githubAPIEndpoint)

	release := Release{
		TagName:    tag,
		Name:       tag,
		Prerelease: false,
		Draft:      false,
		Branch:     branch,
		Body:       desc,
	}

	releaseData, err := json.Marshal(release)
	if err != nil {
		log.Fatalln(err)
	}

	releaseBuffer := bytes.NewBuffer(releaseData)

	data, err := doRequest("POST", endpoint, "application/json", releaseBuffer, int64(releaseBuffer.Len()))

	if err != nil && data != nil {
		log.Println(err)
		log.Println("Trying again assuming release already exists.")
		endpoint = fmt.Sprintf("%s/releases/tags/%s", githubAPIEndpoint, tag)
		data, err = doRequest("GET", endpoint, "application/json", nil, int64(0))
	}

	if err != nil {
		log.Fatalln(err)
	}

	// Gets the release Upload URL from the returned JSON data
	err = json.Unmarshal(data, &release)
	if err != nil {
		log.Fatalln(err)
	}

	// Upload URL comes like this https://uploads.github.com/repos/octocat/Hello-World/releases/1/assets{?name}
	// So we need to remove the {?name} part
	uploadURL := strings.Split(release.UploadURL, "{")[0]

	var wg sync.WaitGroup
	for i := range filepaths {
		wg.Add(1)
		func(index int) {
			uploadFile(uploadURL, filepaths[index])
			wg.Done()
		}(i)
	}
	wg.Wait()
}

func fileSize(file *os.File) (int64, error) {
	stat, err := file.Stat()
	if err != nil {
		return 0, err
	}
	return stat.Size(), nil
}

// Sends HTTP request to Github API
func doRequest(method, url, contentType string, reqBody io.Reader, bodySize int64) ([]byte, error) {
	req, err := http.NewRequest(method, url, reqBody)
	if err != nil {
		return nil, err
	}

	req.Header.Set("Authorization", fmt.Sprintf("token %s", githubToken))
	req.Header.Set("Content-type", contentType)
	req.Header.Set("Accept", "application/vnd.github.v3+json")
	req.ContentLength = bodySize

	if debug {
		log.Println("================ REQUEST DUMP ==================")
		dump, err := httputil.DumpRequestOut(req, true)
		if err != nil {
			log.Println(err.Error())
		}
		log.Println(string(dump[:]))
	}

	resp, err := http.DefaultClient.Do(req)

	if debug {
		log.Println("================ RESPONSE DUMP ==================")
		dump, err := httputil.DumpResponse(resp, true)
		if err != nil {
			log.Println(err.Error())
		}
		log.Println(string(dump[:]))
	}

	if err != nil {
		return nil, err
	}

	defer resp.Body.Close()

	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
		return respBody, fmt.Errorf("Github returned an error:\n Code: %s. \n Body: %s", resp.Status, respBody)
	}

	return respBody, nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/slyrz/newscat/html"
	"github.com/slyrz/newscat/model"
	"github.com/slyrz/newscat/util"
	"io"
	"net/http"
	"os"
	"strings"
)

// Input stores the user-provided HTML data and its location.
type Input struct {
	Location string    // either file path or URL or empty if data was read from stdin
	Data     io.Reader // the HTML data (hopefully)
}

var (
	// highlight indicates whether newscat should use ANSI escape codes
	// to print headings and emphasized text in bold type. The default value of this flag
	// depends on the type of stdout - it's set to false if newscat isn't printing
	// onto a terminal.
	highlight = flag.Bool("highlight", util.IsTerminal(os.Stdout), "highlight headings and emphasized text")

	// extract defines the extraction method used.
	extract = flag.String("extract", "content", "extract either article content or links")
)

func printChunks(chunks []*html.Chunk) {
	var last *html.Chunk = nil
	for _, chunk := range chunks {
		delim, pre, pos := "", "", ""
		// If the last chunk and the current chunk are part of the same HTML block,
		// separate them by a space character. Otherwise use two newline characters
		// to create a new paragraph.
		if last != nil {
			switch {
			case last.Block != chunk.Block:
				delim = "\n\n"
			case last.Block == chunk.Block:
				delim = " "
			}
		}
		if *highlight {
			// Print headings and emphasized text bold.
			switch chunk.Base.Data {
			case "h1", "h2", "h3", "h4", "h5", "h6", "em", "strong", "b":
				pre, pos = "\x1b[1m", "\x1b[0m"
			default:
				pre, pos = "", ""
			}
		}
		fmt.Printf("%s%s%s%s", delim, pre, chunk.Text, pos)
		last = chunk
	}
	fmt.Println()
}

func printLinks(links []*html.Link) {
	for _, link := range links {
		fmt.Println(link.URL)
	}
}

func main() {
	flag.Parse()

	inputChannel := make(chan Input, 4)
	// Open all input (file paths or URLs) or read from stdin and write the
	// corresponding Input structs to the inputChannel channel.
	go func() {
		if flag.NArg() > 0 {
			for _, arg := range flag.Args() {
				if strings.HasPrefix(arg, "http://") || strings.HasPrefix(arg, "https://") {
					if resp, err := http.Get(arg); err == nil {
						inputChannel <- Input{arg, resp.Body}
					}
				} else {
					if file, err := os.Open(arg); err == nil {
						inputChannel <- Input{arg, file}
					}
				}
			}
		} else {
			inputChannel <- Input{"", os.Stdin}
		}
		close(inputChannel)
	}()

	switch *extract {
	case "links":
		ext := model.NewLinkExtractor()
		for input := range inputChannel {
			if website, err := html.NewWebsite(input.Data); err == nil {
				// Add protocol and domain to relative links before we perform
				// link extraction. Works only if input.Location is a URL.
				website.ResolveBase(input.Location)
				if links := ext.Extract(website); len(links) > 0 {
					printLinks(links)
				}
			}
		}
	case "content":
		ext := model.NewChunkExtractor()
		for input := range inputChannel {
			if article, err := html.NewArticle(input.Data); err == nil {
				if chunks := ext.Extract(article); len(chunks) > 0 {
					printChunks(chunks)
				}
			}
		}
	}
}
<commit_msg>replaced string flag with two boolean flags<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/slyrz/newscat/html"
	"github.com/slyrz/newscat/model"
	"github.com/slyrz/newscat/util"
	"io"
	"net/http"
	"os"
	"strings"
)

// Input stores the user-provided HTML data and its location.
type Input struct {
	Location string    // either file path or URL or empty if data was read from stdin
	Data     io.Reader // the HTML data (hopefully)
}

var (
	// highlight indicates whether newscat should use ANSI escape codes
	// to print headings and emphasized text in bold type. The default value of this flag
	// depends on the type of stdout - it's set to false if newscat isn't printing
	// onto a terminal.
	highlight = flag.Bool("highlight", util.IsTerminal(os.Stdout), "highlight headings and emphasized text")

	// newscat extracts either article content or links.
	extractContent = flag.Bool("content", true, "extract article content")
	extractLinks   = flag.Bool("links", false, "extract links")
)

func printChunks(chunks []*html.Chunk) {
	var last *html.Chunk = nil
	for _, chunk := range chunks {
		delim, pre, pos := "", "", ""
		// If the last chunk and the current chunk are part of the same HTML block,
		// separate them by a space character. Otherwise use two newline characters
		// to create a new paragraph.
		if last != nil {
			switch {
			case last.Block != chunk.Block:
				delim = "\n\n"
			case last.Block == chunk.Block:
				delim = " "
			}
		}
		if *highlight {
			// Print headings and emphasized text bold.
			switch chunk.Base.Data {
			case "h1", "h2", "h3", "h4", "h5", "h6", "em", "strong", "b":
				pre, pos = "\x1b[1m", "\x1b[0m"
			default:
				pre, pos = "", ""
			}
		}
		fmt.Printf("%s%s%s%s", delim, pre, chunk.Text, pos)
		last = chunk
	}
	fmt.Println()
}

func printLinks(links []*html.Link) {
	for _, link := range links {
		fmt.Println(link.URL)
	}
}

func main() {
	flag.Parse()

	inputChannel := make(chan Input, 4)
	// Open all input (file paths or URLs) or read from stdin and write the
	// corresponding Input structs to the inputChannel channel.
	go func() {
		if flag.NArg() > 0 {
			for _, arg := range flag.Args() {
				if strings.HasPrefix(arg, "http://") || strings.HasPrefix(arg, "https://") {
					if resp, err := http.Get(arg); err == nil {
						inputChannel <- Input{arg, resp.Body}
					}
				} else {
					if file, err := os.Open(arg); err == nil {
						inputChannel <- Input{arg, file}
					}
				}
			}
		} else {
			inputChannel <- Input{"", os.Stdin}
		}
		close(inputChannel)
	}()

	switch {
	case *extractLinks:
		ext := model.NewLinkExtractor()
		for input := range inputChannel {
			if website, err := html.NewWebsite(input.Data); err == nil {
				// Add protocol and domain to relative links before we perform
				// link extraction. Works only if input.Location is a URL.
				website.ResolveBase(input.Location)
				if links := ext.Extract(website); len(links) > 0 {
					printLinks(links)
				}
			}
		}
	case *extractContent:
		ext := model.NewChunkExtractor()
		for input := range inputChannel {
			if article, err := html.NewArticle(input.Data); err == nil {
				if chunks := ext.Extract(article); len(chunks) > 0 {
					printChunks(chunks)
				}
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"os"

	"github.com/emicklei/artreyu/command"
	"github.com/emicklei/artreyu/local"
	"github.com/emicklei/artreyu/model"
	"github.com/spf13/cobra"
)

var (
	VERSION   string = "dev"
	BUILDDATE string = "now"

	applicationSettings *model.Settings
	rootCmd             *cobra.Command
)

func main() {
	model.Printf("artreyu - artifact assembly tool (build:%s, commit:%s)\n", BUILDDATE, VERSION)
	initRootCommand()
	rootCmd.Execute()
}

func initRootCommand() {
	rootCmd = &cobra.Command{
		Use:   "artreyu",
		Short: "archives, fetches and assembles build artifacts",
		Long: `A tool for handling versioned, platform dependent artifacts.
Its primary purpose is to create assembly artifacts from build artifacts archived in a (remote) repository.

See https://github.com/emicklei/artreyu for more details.

(c)2015 http://ernestmicklei.com, MIT license`,
		Run: func(cmd *cobra.Command, args []string) {
			cmd.Help()
		},
	}
	applicationSettings = command.NewSettingsBoundToFlags(rootCmd)
	rootCmd.PersistentPreRun = func(cmd *cobra.Command, args []string) {
		if applicationSettings.Verbose {
			dir, _ := os.Getwd()
			model.Printf("working directory = [%s]", dir)
		}
	}

	archive := command.NewCommandForArchive()
	archive.Run = func(cmd *cobra.Command, args []string) {
		if len(args) == 0 {
			model.Fatalf("archive failed, missing source argument")
		}
		artifact, err := model.LoadArtifact(applicationSettings.ArtifactConfigLocation)
		if err != nil {
			model.Fatalf("archive failed, could not load artifact: %v", err)
		}
		target := applicationSettings.TargetRepository
		if "local" == target {
			archive := command.Archive{
				Artifact:   artifact,
				Repository: local.NewRepository(model.RepositoryConfigNamed(applicationSettings, "local"), applicationSettings.OS),
				Source:     args[0],
			}
			archive.Perform()
			return
		}
		// not local
		if err := command.RunPluginWithArtifact("artreyu-"+target, "archive", artifact, *applicationSettings, args); err != nil {
			model.Fatalf("archive failed, could not run plugin: %v", err)
		}
	}
	rootCmd.AddCommand(archive)

	fetch := command.NewCommandForFetch()
	fetch.Run = func(cmd *cobra.Command, args []string) {
		artifact, err := model.LoadArtifact(applicationSettings.ArtifactConfigLocation)
		if err != nil {
			model.Fatalf("fetch failed, unable to load artifact: %v", err)
		}
		target := applicationSettings.TargetRepository
		if "local" == target {
			var destination = "."
			if len(args) > 0 {
				destination = args[0]
			}
			fetch := command.Fetch{
				Artifact:    artifact,
				Repository:  local.NewRepository(model.RepositoryConfigNamed(applicationSettings, "local"), applicationSettings.OS),
				Destination: destination,
				AutoExtract: command.AutoExtract,
			}
			fetch.Perform()
			return
		}
		// not local
		if err := command.RunPluginWithArtifact("artreyu-"+target, "fetch", artifact, *applicationSettings, args); err != nil {
			model.Fatalf("fetch failed, could not run plugin:  %v", err)
		}
	}
	rootCmd.AddCommand(fetch)
	rootCmd.AddCommand(newAssembleCmd())
}
<commit_msg>pass x flag to plugin<commit_after>package main

import (
	"os"
	"strconv"

	"github.com/emicklei/artreyu/command"
	"github.com/emicklei/artreyu/local"
	"github.com/emicklei/artreyu/model"
	"github.com/spf13/cobra"
)

var (
	VERSION   string = "dev"
	BUILDDATE string = "now"

	applicationSettings *model.Settings
	rootCmd             *cobra.Command
)

func main() {
	model.Printf("artreyu - artifact assembly tool (build:%s, commit:%s)\n", BUILDDATE, VERSION)
	initRootCommand()
	rootCmd.Execute()
}

func initRootCommand() {
	rootCmd = &cobra.Command{
		Use:   "artreyu",
		Short: "archives, fetches and assembles build artifacts",
		Long: `A tool for handling versioned, platform dependent artifacts.
Its primary purpose is to create assembly artifacts from build artifacts archived in a (remote) repository.

See https://github.com/emicklei/artreyu for more details.

(c)2015 http://ernestmicklei.com, MIT license`,
		Run: func(cmd *cobra.Command, args []string) {
			cmd.Help()
		},
	}
	applicationSettings = command.NewSettingsBoundToFlags(rootCmd)
	rootCmd.PersistentPreRun = func(cmd *cobra.Command, args []string) {
		if applicationSettings.Verbose {
			dir, _ := os.Getwd()
			model.Printf("working directory = [%s]", dir)
		}
	}

	archive := command.NewCommandForArchive()
	archive.Run = func(cmd *cobra.Command, args []string) {
		if len(args) == 0 {
			model.Fatalf("archive failed, missing source argument")
		}
		artifact, err := model.LoadArtifact(applicationSettings.ArtifactConfigLocation)
		if err != nil {
			model.Fatalf("archive failed, could not load artifact: %v", err)
		}
		target := applicationSettings.TargetRepository
		if "local" == target {
			archive := command.Archive{
				Artifact:   artifact,
				Repository: local.NewRepository(model.RepositoryConfigNamed(applicationSettings, "local"), applicationSettings.OS),
				Source:     args[0],
			}
			archive.Perform()
			return
		}
		// not local, no archive specific flags to add
		if err := command.RunPluginWithArtifact("artreyu-"+target, "archive", artifact, *applicationSettings, args); err != nil {
			model.Fatalf("archive failed, could not run plugin: %v", err)
		}
	}
	rootCmd.AddCommand(archive)

	fetch := command.NewCommandForFetch()
	fetch.Run = func(cmd *cobra.Command, args []string) {
		artifact, err := model.LoadArtifact(applicationSettings.ArtifactConfigLocation)
		if err != nil {
			model.Fatalf("fetch failed, unable to load artifact: %v", err)
		}
		target := applicationSettings.TargetRepository
		if "local" == target {
			var destination = "."
			if len(args) > 0 {
				destination = args[0]
			}
			fetch := command.Fetch{
				Artifact:    artifact,
				Repository:  local.NewRepository(model.RepositoryConfigNamed(applicationSettings, "local"), applicationSettings.OS),
				Destination: destination,
				AutoExtract: command.AutoExtract,
			}
			fetch.Perform()
			return
		}
		// extend args with fetch specific flags
		extendedArgs := append(args, "--extract="+strconv.FormatBool(command.AutoExtract))

		// not local
		if err := command.RunPluginWithArtifact("artreyu-"+target, "fetch", artifact, *applicationSettings, extendedArgs); err != nil {
			model.Fatalf("fetch failed, could not run plugin:  %v", err)
		}
	}
	rootCmd.AddCommand(fetch)
	rootCmd.AddCommand(newAssembleCmd())
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"log"
	"net/http"

	rdb "github.com/dancannon/gorethink"
	"github.com/julienschmidt/httprouter"
	"github.com/rs/cors"
)

// Person is the model for our user
type Person struct {
	ID             string `json:"id"`
	FirstName      string `json:"firstName"`
	LastName       string `json:"lastName"`
	CoolnessFactor int    `json:"coolnessFactor"`
}

// DB holds our connection to the database
type DB struct {
	Session *rdb.Session
}

func newDBConn() *DB {
	session, err := rdb.Connect(rdb.ConnectOpts{
		Address: "localhost:28015",
	})
	if err != nil {
		log.Fatal("Error: %s\n", err)
	}
	return &DB{
		Session: session,
	}
}

func main() {
	db := newDBConn()
	db.Init("arg", "People")
	router := httprouter.New()

	router.GET("/api/people", db.List)
	router.GET("/api/people/:id", db.Get)
	router.PUT("/api/people/:id", db.Update)
	router.DELETE("/api/people/:id", db.Delete)
	router.POST("/api/people", db.Add)

	http.ListenAndServe(":8000", cors.Default().Handler(router))
}

// Init creates a new DB and a new table
func (db *DB) Init(dbName string, tableName string) error {
	resp, err := rdb.DBCreate(dbName).RunWrite(db.Session)
	if err != nil {
		return err
	}
	log.Println("DB created: ", resp.DBsCreated)

	resp, err = rdb.TableCreate(tableName).RunWrite(db.Session)
	if err != nil {
		return err
	}
	log.Println("Table created: ", resp.TablesCreated)

	return nil
}

// List all users
func (db *DB) List(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	var people []Person
	rows, err := rdb.Table("People").Run(db.Session)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	err = rows.All(&people)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	json.NewEncoder(w).Encode(people)
}

// Get all users
func (db *DB) Get(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	var p Person
	row, err := rdb.Table("People").Get(ps.ByName("id")).Run(db.Session)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	row.One(&p)
	json.NewEncoder(w).Encode(p)
}

// Update a specific user
func (db *DB) Update(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	resp, err := rdb.Table("People").Update(ps.ByName("id")).RunWrite(db.Session)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	json.NewEncoder(w).Encode(resp)
}

// Delete a specific user
func (db *DB) Delete(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	resp, err := rdb.Table("People").Get(ps.ByName("id")).Delete().RunWrite(db.Session)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	json.NewEncoder(w).Encode(resp)
}

// Add a new user
func (db *DB) Add(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	var p Person
	json.NewDecoder(r.Body).Decode(&p)

	row, err := rdb.Table("People").Insert(p).Run(db.Session)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	err = row.One(p)
	json.NewEncoder(w).Encode(p)
}
<commit_msg>Set correct CORS options<commit_after>package main

import (
	"encoding/json"
	"log"
	"net/http"

	rdb "github.com/dancannon/gorethink"
	"github.com/julienschmidt/httprouter"
	"github.com/rs/cors"
)

// Person is the model for our user
type Person struct {
	ID             string `json:"id"`
	FirstName      string `json:"firstName"`
	LastName       string `json:"lastName"`
	CoolnessFactor int    `json:"coolnessFactor"`
}

// DB holds our connection to the database
type DB struct {
	Session *rdb.Session
}

func newDBConn() *DB {
	session, err := rdb.Connect(rdb.ConnectOpts{
		Address: "localhost:28015",
	})
	if err != nil {
		log.Fatal("Error: %s\n", err)
	}
	return &DB{
		Session: session,
	}
}

func main() {
	db := newDBConn()
	db.Init("arg", "People")
	c := cors.New(cors.Options{
		AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "HEAD"},
	})
	router := httprouter.New()

	router.GET("/api/people", db.List)
	router.GET("/api/people/:id", db.Get)
	router.PUT("/api/people/:id", db.Update)
	router.DELETE("/api/people/:id", db.Delete)
	router.POST("/api/people", db.Add)

	http.ListenAndServe(":8000", c.Handler(router))
}

// Init creates a new DB and a new table
func (db *DB) Init(dbName string, tableName string) error {
	resp, err := rdb.DBCreate(dbName).RunWrite(db.Session)
	if err != nil {
		return err
	}
	log.Println("DB created: ", resp.DBsCreated)

	resp, err = rdb.TableCreate(tableName).RunWrite(db.Session)
	if err != nil {
		return err
	}
	log.Println("Table created: ", resp.TablesCreated)

	return nil
}

// List all users
func (db *DB) List(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	var people []Person
	rows, err := rdb.Table("People").Run(db.Session)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	err = rows.All(&people)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	json.NewEncoder(w).Encode(people)
}

// Get all users
func (db *DB) Get(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	var p Person
	row, err := rdb.Table("People").Get(ps.ByName("id")).Run(db.Session)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	row.One(&p)
	json.NewEncoder(w).Encode(p)
}

// Update a specific user
func (db *DB) Update(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	var p Person
	json.NewDecoder(r.Body).Decode(&p)

	resp, err := rdb.Table("People").Get(ps.ByName("id")).Update(p).RunWrite(db.Session)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	json.NewEncoder(w).Encode(resp.GeneratedKeys)
}

// Delete a specific user
func (db *DB) Delete(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	resp, err := rdb.Table("People").Get(ps.ByName("id")).Delete().RunWrite(db.Session)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	json.NewEncoder(w).Encode(resp)
}

// Add a new user
func (db *DB) Add(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	var p Person
	json.NewDecoder(r.Body).Decode(&p)

	row, err := rdb.Table("People").Insert(p).Run(db.Session)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	err = row.One(p)
	json.NewEncoder(w).Encode(p)
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"os"
	"os/exec"
	"time"
)

func main() {
	if len(os.Args) == 1 {
		log.Fatal("Please put a command after this.")
	}
	cmd := exec.Command(os.Args[1], os.Args[2:]...)
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		log.Fatal(err)
	}
	if err := cmd.Start(); err != nil {
		log.Fatal(err)
	}
	buf := make([]byte, 1024)
	pkc := make(chan bool)
	go monitor(pkc)
	for {
		n, e := stdout.Read(buf)
		if e != nil {
			os.Exit(1)
		}
		os.Stdout.Write(buf[:n])
		pkc <- true
	}
}

func monitor(poke chan bool) {
	for {
		select {
		case <-poke:
			// a read from ch has occurred
		case <-time.After(time.Second * 5):
			// the read from ch has timed out
			log.Fatal("Timed out")
			os.Exit(0)
		}
	}
}
<commit_msg>Kill the process after timeout<commit_after>package main

import (
	"log"
	"os"
	"os/exec"
	"time"
)

func main() {
	if len(os.Args) == 1 {
		log.Fatal("Please put a command after this.")
	}
	cmd := exec.Command(os.Args[1], os.Args[2:]...)
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		log.Fatal(err)
	}
	if err := cmd.Start(); err != nil {
		log.Fatal(err)
	}
	buf := make([]byte, 1024)
	pkc := make(chan bool)
	go monitor(pkc, cmd)
	for {
		n, e := stdout.Read(buf)
		if e != nil {
			os.Exit(1)
		}
		os.Stdout.Write(buf[:n])
		pkc <- true
	}
}

func monitor(poke chan bool, cmd *exec.Cmd) {
	for {
		select {
		case <-poke:
			// a read from ch has occurred
		case <-time.After(time.Second * 5):
			// the read from ch has timed out
			log.Fatal("Timed out")
			cmd.Process.Kill()
			os.Exit(0)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net/http"

	"crypto/tls"
	"encoding/gob"
	"log"
	"net/http/pprof"
	_ "net/http/pprof"
	"strings"
	"time"

	"github.com/gorilla/securecookie"
	"github.com/julienschmidt/httprouter"
	"github.com/raggaer/castro/app"
	"github.com/raggaer/castro/app/controllers"
	"github.com/raggaer/castro/app/models"
	"github.com/raggaer/castro/app/util"
	"github.com/ulule/limiter"
	"github.com/ulule/limiter/drivers/store/memory"
	"github.com/urfave/negroni"
	"github.com/yuin/gopher-lua"
	"golang.org/x/crypto/acme/autocert"
)

func main() {
	// Register gob data
	gob.Register(&models.CsrfToken{})
	gob.Register(&lua.LTable{})
	gob.Register(&util.CastroMap{})
	gob.Register(map[string]interface{}{})
	gob.Register([]interface{}{})

	// Show credits and application name
	fmt.Printf(`
Castro - High performance content management system for Open Tibia servers

Running version: %v
Compiled at: %v

`, util.VERSION, util.BUILD_DATE)

	// Check if application is installed
	if !isInstalled() {

		// Run the installation process
		if err := startInstallerApplication(); err != nil {
			log.Fatal(err)
		}

		return
	}

	// Run main app entry point
	app.Start()

	// Create rate-limiter instance
	rate := limiter.Rate{
		Period: util.Config.Configuration.RateLimit.Time.Duration,
		Limit:  util.Config.Configuration.RateLimit.Number,
	}

	// Create rate-limiter storage
	store := memory.NewStore()

	// Create rate-limiter
	limiter := limiter.New(store, rate)

	// Declare our new http router
	router := httprouter.New()

	// Declare application endpoints
	router.GET("/", controllers.LuaPage)
	router.POST("/", controllers.LuaPage)
	router.POST("/subtopic/*filepath", controllers.LuaPage)
	router.GET("/subtopic/*filepath", controllers.LuaPage)
	router.GET("/extensions/:id/static/*filepath", controllers.ExtensionStatic)
	router.POST("/nocsrf/*filepath", controllers.LuaPage)
	router.NotFound = PageNotFound

	// Register pprof router only on development mode
	if util.Config.Configuration.IsDev() {
		router.GET("/pprof/heap", wrapHandler(pprof.Handler("heap")))
	}

	// Create the session storage
	util.SessionStore = securecookie.New(
		[]byte(util.Config.Configuration.Cookies.HashKey),
		[]byte(util.Config.Configuration.Cookies.BlockKey),
	)

	// Create the middleware negroni instance with some application middleware
	n := negroni.New(
		newRateLimitHandler(limiter),
		newSecurityHandler(),
		newSessionHandler(),
		newMicrotimeHandler(),
		newCsrfHandler(),
		newI18nHandler(),
	)

	// Use static handler if enabled
	if util.Config.Configuration.Static.Enabled {
		n.Use(negroni.NewStatic(http.Dir(util.Config.Configuration.Static.Directory)))
	}

	// Use negroni logger only in development mode
	if util.Config.Configuration.IsDev() || util.Config.Configuration.IsLog() {
		n.Use(negroni.NewLogger())
	}

	// Disable httprouter not found handler
	router.HandleMethodNotAllowed = false

	// Tell negroni to use our http router
	n.UseHandler(router)

	// Create castro server
	server := http.Server{
		Addr:         fmt.Sprintf(":%v", util.Config.Configuration.Port),
		Handler:      n,
		ReadTimeout:  10 * time.Second,
		WriteTimeout: 10 * time.Second,
	}

	// Check if Castro should run on SSL mode
	if util.Config.Configuration.SSL.Enabled {

		// Check if user is using auto-certificate
		if util.Config.Configuration.SSL.Auto {

			// Create auto-certificate manager
			m := autocert.Manager{
				Prompt: autocert.AcceptTOS,
				Cache:  autocert.DirCache("tls"),
			}

			// Set auto-certificate hosts
			if strings.HasPrefix(util.Config.Configuration.URL, "www") {
				m.HostPolicy = autocert.HostWhitelist(util.Config.Configuration.URL, strings.Replace(util.Config.Configuration.URL, "www.", "", 1))
			} else {
				m.HostPolicy = autocert.HostWhitelist(util.Config.Configuration.URL, "www."+util.Config.Configuration.URL)
			}

			// Set server TLS option
			server.TLSConfig = &tls.Config{
				GetCertificate: m.GetCertificate,
			}

			// Listen to non-https ACME challenges connections
			go http.ListenAndServe(":http", m.HTTPHandler(nil))

			// Listen to https connections using autocert
			if err := server.ListenAndServeTLS("", ""); err != nil {
				util.Logger.Logger.Fatalf("Cannot start Castro autocert HTTPS server: %v", err)
			}
		}

		// Redirect all non https connections
		go httpsRedirect()

		// If SSL is enabled listen with cert and key
		if err := server.ListenAndServeTLS(
			util.Config.Configuration.SSL.Cert,
			util.Config.Configuration.SSL.Key,
		); err != nil {
			util.Logger.Logger.Fatalf("Cannot start Castro HTTPS server: %v", err)
		}

	} else {

		// Listen without using ssl
		if err := server.ListenAndServe(); err != nil {
			util.Logger.Logger.Fatalf("Cannot start Castro HTTP server: %v", err)
		}
	}
}

// wrapHandler converts a normal http handler to a httprouter handler
func wrapHandler(h http.Handler) httprouter.Handle {
	return func(rw http.ResponseWriter, req *http.Request, ps httprouter.Params) {
		h.ServeHTTP(rw, req)
	}
}

// httpsRedirect gets all non-https traffic and redirects to https
func httpsRedirect() {
	// Create router
	mux := httprouter.New()
	mux.GET("/*filepath", controllers.SSLRedirect)

	// Create server
	server := http.Server{
		Addr:         fmt.Sprintf(":%v", 80),
		Handler:      mux,
		ReadTimeout:  10 * time.Second,
		WriteTimeout: 10 * time.Second,
	}

	if err := server.ListenAndServe(); err != nil {
		util.Logger.Logger.Fatalf("Cannot start HTTP redirect server: %v", err)
	}
}
<commit_msg>Fix #89<commit_after>package main

import (
	"fmt"
	"net/http"

	"crypto/tls"
	"encoding/gob"
	"log"
	"net/http/pprof"
	_ "net/http/pprof"
	"strings"
	"time"

	"github.com/gorilla/securecookie"
	"github.com/julienschmidt/httprouter"
	"github.com/raggaer/castro/app"
	"github.com/raggaer/castro/app/controllers"
	"github.com/raggaer/castro/app/models"
	"github.com/raggaer/castro/app/util"
	"github.com/ulule/limiter"
	"github.com/ulule/limiter/drivers/store/memory"
	"github.com/urfave/negroni"
	"github.com/yuin/gopher-lua"
	"golang.org/x/crypto/acme/autocert"
)

func main() {
	// Register gob data
	gob.Register(&models.CsrfToken{})
	gob.Register(&lua.LTable{})
	gob.Register(&util.CastroMap{})
	gob.Register(map[string]interface{}{})
	gob.Register([]interface{}{})

	// Show credits and application name
	fmt.Printf(`
Castro - High performance content management system for Open Tibia servers

Running version: %v
Compiled at: %v

`, util.VERSION, util.BUILD_DATE)

	// Check if application is installed
	if !isInstalled() {

		// Run the installation process
		if err := startInstallerApplication(); err != nil {
			log.Fatal(err)
		}

		return
	}

	// Run main app entry point
	app.Start()

	// Create rate-limiter instance
	rate := limiter.Rate{
		Period: util.Config.Configuration.RateLimit.Time.Duration,
		Limit:  util.Config.Configuration.RateLimit.Number,
	}

	// Create rate-limiter storage
	store := memory.NewStore()

	// Create rate-limiter
	limiter := limiter.New(store, rate)

	// Declare our new http router
	router := httprouter.New()

	// Declare application endpoints
	router.GET("/", controllers.LuaPage)
	router.POST("/", controllers.LuaPage)
	router.POST("/subtopic/*filepath", controllers.LuaPage)
	router.GET("/subtopic/*filepath", controllers.LuaPage)
	router.GET("/extensions/:id/static/*filepath", controllers.ExtensionStatic)
	router.POST("/nocsrf/*filepath", controllers.LuaPage)
	router.NotFound = http.HandlerFunc(PageNotFound)

	// Register pprof router only on development mode
	if util.Config.Configuration.IsDev() {
		router.GET("/pprof/heap", wrapHandler(pprof.Handler("heap")))
	}

	// Create the session storage
	util.SessionStore = securecookie.New(
		[]byte(util.Config.Configuration.Cookies.HashKey),
		[]byte(util.Config.Configuration.Cookies.BlockKey),
	)

	// Create the middleware negroni instance with some application middleware
	n := negroni.New(
		newRateLimitHandler(limiter),
		newSecurityHandler(),
		newSessionHandler(),
		newMicrotimeHandler(),
		newCsrfHandler(),
		newI18nHandler(),
	)

	// Use static handler if enabled
	if util.Config.Configuration.Static.Enabled {
		n.Use(negroni.NewStatic(http.Dir(util.Config.Configuration.Static.Directory)))
	}

	// Use negroni logger only in development mode
	if util.Config.Configuration.IsDev() || util.Config.Configuration.IsLog() {
		n.Use(negroni.NewLogger())
	}

	// Disable httprouter not found handler
	router.HandleMethodNotAllowed = false

	// Tell negroni to use our http router
	n.UseHandler(router)

	// Create castro server
	server := http.Server{
		Addr:         fmt.Sprintf(":%v", util.Config.Configuration.Port),
		Handler:      n,
		ReadTimeout:  10 * time.Second,
		WriteTimeout: 10 * time.Second,
	}

	// Check if Castro should run on SSL mode
	if util.Config.Configuration.SSL.Enabled {

		// Check if user is using auto-certificate
		if util.Config.Configuration.SSL.Auto {

			// Create auto-certificate manager
			m := autocert.Manager{
				Prompt: autocert.AcceptTOS,
				Cache:  autocert.DirCache("tls"),
			}

			// Set auto-certificate hosts
			if strings.HasPrefix(util.Config.Configuration.URL, "www") {
				m.HostPolicy = autocert.HostWhitelist(util.Config.Configuration.URL, strings.Replace(util.Config.Configuration.URL, "www.", "", 1))
			} else {
				m.HostPolicy = autocert.HostWhitelist(util.Config.Configuration.URL, "www."+util.Config.Configuration.URL)
			}

			// Set server TLS option
			server.TLSConfig = &tls.Config{
				GetCertificate: m.GetCertificate,
			}

			// Listen to non-https ACME challenges connections
			go http.ListenAndServe(":http", m.HTTPHandler(nil))

			// Listen to https connections using autocert
			if err := server.ListenAndServeTLS("", ""); err != nil {
				util.Logger.Logger.Fatalf("Cannot start Castro autocert HTTPS server: %v", err)
			}
		}

		// Redirect all non https connections
		go httpsRedirect()

		// If SSL is enabled listen with cert and key
		if err := server.ListenAndServeTLS(
			util.Config.Configuration.SSL.Cert,
			util.Config.Configuration.SSL.Key,
		); err != nil {
			util.Logger.Logger.Fatalf("Cannot start Castro HTTPS server: %v", err)
		}

	} else {

		// Listen without using ssl
		if err := server.ListenAndServe(); err != nil {
			util.Logger.Logger.Fatalf("Cannot start Castro HTTP server: %v", err)
		}
	}
}

// wrapHandler converts a normal http handler to a httprouter handler
func wrapHandler(h http.Handler) httprouter.Handle {
	return func(rw http.ResponseWriter, req *http.Request, ps httprouter.Params) {
		h.ServeHTTP(rw, req)
	}
}

// httpsRedirect gets all non-https traffic and redirects to https
func httpsRedirect() {
	// Create router
	mux := httprouter.New()
	mux.GET("/*filepath", controllers.SSLRedirect)

	// Create server
	server := http.Server{
		Addr:         fmt.Sprintf(":%v", 80),
		Handler:      mux,
		ReadTimeout:  10 * time.Second,
		WriteTimeout: 10 * time.Second,
	}

	if err := server.ListenAndServe(); err != nil {
		util.Logger.Logger.Fatalf("Cannot start HTTP redirect server: %v", err)
	}
}
<|endoftext|>


<commit_before>package main

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

	"github.com/sbinet/liner"
	_ "github.com/sbinet/go-croot/pkg/croot"
	"github.com/sbinet/gribble"
)

var term *liner.State = nil

func init() {
	fmt.Println(`
************************
** PAW-Go interpreter **
************************
`)
	fmt.Printf(":: available commands:\n%v\n::\n\n", env)

	term = liner.NewLiner()

	fname := path.Join(os.Getenv("HOME"), ".pawgo.history")
	f, err := os.Open(fname)
	if err != nil {
		f, err = os.Create(fname)
		if err != nil {
			fmt.Printf("**warning: could not access nor create history file [%s]\n", fname)
			return
		}
	}
	defer f.Close()
	_, err = term.ReadHistory(f)
	if err != nil {
		fmt.Printf("**warning: could not read history file [%s]\n", fname)
		return
	}

	term.SetCompleter(paw_completer)
}

func atexit() {
	fname := path.Join(os.Getenv("HOME"), ".pawgo.history")
	f, err := os.OpenFile(fname, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)
	if err != nil {
		fmt.Printf("**warning: could not access history file [%s]\n", fname)
		return
	}
	defer f.Close()
	_, err = term.WriteHistory(f)
	if err != nil {
		fmt.Printf("**warning: could not write history file [%s]\n", fname)
		return
	}

	err = term.Close()
	if err != nil {
		fmt.Printf("**warning: problem closing term: %v\n", err)
		return
	}
}

// A Gribble environment is composed of Go struct types. Since the environment
// does not care about values, zero values of each command struct can be
// used in the gribble.Command slice.
//
// Note that these may also be specified as non-pointers.
var env *gribble.Environment = gribble.New(
	[]gribble.Command{
		new_cmd_ntuple_create(),
	},
)

var paw_completer liner.Completer = func(line string) []string {
	completions := []string{}
	for _,cmd := range env.CommandNames() {
		if strings.HasPrefix(cmd, line) {
			completions = append(completions, cmd)
		}
	}
	return completions
}

func new_cmd_ntuple_create() *ntuple_create {
	return &ntuple_create{
		//mgr: nil,
	}
}

type ntuple_create struct {
	name     string      `ntcr`
	Id int `param:"1" types:"int"`
	Title string `param:"2" types:"string"`
	Vars  string `param:"3" types:"string"`

	mgr *NtupleMgr
}

func (cmd *ntuple_create) Run() gribble.Value {
	id := cmd.Id
	title,err := strconv.Unquote(cmd.Title)
	if err != nil {
		return err
	}
	//nvars := cmd.Nvars.(int)
	vars, err := strconv.Unquote(cmd.Vars)
	ntvars := strings.Split(vars, ",")
	return cmd.mgr.create(id, title, ntvars)
}

type NtupleMgr struct {
}

func (mgr *NtupleMgr) create(id int, title string, vars []string) error {
	fmt.Printf("==> /ntuple/create id=%v title=%q vars=%v\n",
		id, title, vars)
	return nil
}

func main() {

	defer atexit()

	var ierr error = nil // previous interpreter error
	ps1 := "paw> "
	ps2 := "...  "
	prompt := &ps1
	codelet := ""

	for {
		line, err := term.Prompt(*prompt)
		if err != nil {
			if err != io.EOF {
				ierr = err
			} else {
				ierr = nil
			}
			break //os.Exit(0)
		}
		if line == "" {
			// no more input
			prompt = &ps1
		}

		codelet += line
		if codelet != "" {
			for _, ll := range strings.Split(codelet, "\n") {
				term.AppendHistory(ll)
			}
		} else {
			continue
		}

		_, err = env.Run(codelet)
		if err != nil {
			if ierr != nil && prompt == &ps1 {
				fmt.Println(err.Error())
				fmt.Printf("(error %T)\n", err)
				// reset state
				codelet = ""
				ierr = nil
				prompt = &ps1
				continue
			}
			// maybe multi-line command ?
			prompt = &ps2
			ierr = err
			codelet += "\n"
			continue
		}

		//	resetstate:
		// reset state
		codelet = ""
		ierr = nil
	}

	fmt.Printf("\n:: bye.\n")
}

// EOF
<commit_msg>remove multiline edit. simplify parsing. rename ntcr into its proper name /ntuple/create<commit_after>package main

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

	"github.com/sbinet/liner"
	_ "github.com/sbinet/go-croot/pkg/croot"
	"github.com/sbinet/gribble"
)

var term *liner.State = nil

func init() {
	fmt.Println(`
************************
** PAW-Go interpreter **
************************
`)
	fmt.Printf(":: available commands:\n%v\n::\n\n", env)

	term = liner.NewLiner()

	fname := path.Join(os.Getenv("HOME"), ".pawgo.history")
	f, err := os.Open(fname)
	if err != nil {
		f, err = os.Create(fname)
		if err != nil {
			fmt.Printf("**warning: could not access nor create history file [%s]\n", fname)
			return
		}
	}
	defer f.Close()
	_, err = term.ReadHistory(f)
	if err != nil {
		fmt.Printf("**warning: could not read history file [%s]\n", fname)
		return
	}

	term.SetCompleter(paw_completer)
}

func atexit() {
	fname := path.Join(os.Getenv("HOME"), ".pawgo.history")
	f, err := os.OpenFile(fname, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)
	if err != nil {
		fmt.Printf("**warning: could not access history file [%s]\n", fname)
		return
	}
	defer f.Close()
	_, err = term.WriteHistory(f)
	if err != nil {
		fmt.Printf("**warning: could not write history file [%s]\n", fname)
		return
	}

	err = term.Close()
	if err != nil {
		fmt.Printf("**warning: problem closing term: %v\n", err)
		return
	}
}

// A Gribble environment is composed of Go struct types. Since the environment
// does not care about values, zero values of each command struct can be
// used in the gribble.Command slice.
//
// Note that these may also be specified as non-pointers.
var env *gribble.Environment = gribble.New(
	[]gribble.Command{
		new_cmd_ntuple_create(),
	},
)

var paw_completer liner.Completer = func(line string) []string {
	completions := []string{}
	for _,cmd := range env.CommandNames() {
		if strings.HasPrefix(cmd, line) {
			completions = append(completions, cmd)
		}
	}
	return completions
}

func new_cmd_ntuple_create() *ntuple_create {
	return &ntuple_create{
		//mgr: nil,
	}
}

type ntuple_create struct {
	name     string      `/ntuple/create`
	Id int `param:"1" types:"int"`
	Title string `param:"2" types:"string"`
	Vars  string `param:"3" types:"string"`

	mgr *NtupleMgr
}

func (cmd *ntuple_create) Run() gribble.Value {
	id := cmd.Id
	title,err := strconv.Unquote(cmd.Title)
	if err != nil {
		return err
	}
	//nvars := cmd.Nvars.(int)
	vars, err := strconv.Unquote(cmd.Vars)
	ntvars := strings.Split(vars, ",")
	return cmd.mgr.create(id, title, ntvars)
}

type NtupleMgr struct {
}

func (mgr *NtupleMgr) create(id int, title string, vars []string) error {
	fmt.Printf("==> /ntuple/create id=%v title=%q vars=%v\n",
		id, title, vars)
	return nil
}

func main() {

	defer atexit()

	prompt := "paw> "
	cmd := ""

	for {
		line, err := term.Prompt(prompt)
		if err != nil {
			break //os.Exit(0)
		}
		cmd = line
		if cmd != "" {
			for _, ll := range strings.Split(cmd, "\n") {
				term.AppendHistory(ll)
			}
		} else {
			continue
		}

		_, err = env.Run(cmd)
		if err != nil {
			fmt.Println(err.Error())
			fmt.Printf("(error %T)\n", err)
			continue
		}
	}

	fmt.Printf("\n:: bye.\n")
}

// EOF
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"reflect"
)

type Config map[string]interface{}

type Response struct {
	Success  bool
	Errors   []string
	Messages []string
	Result   []ResponseSetting
}

type ResponseSetting struct {
	ID         string
	Value      interface{}
	ModifiedOn string `json:"modified_on"`
	Editable   bool
}

const rootURL = "https://api.cloudflare.com/v4"

var (
	httpClient = &http.Client{}
	authEmail  = flag.String("email", "", "Authentication email address")
	authKey    = flag.String("key", "", "Authentication key")
	zoneID     = flag.String("zone", "", "Zone ID")
)

func main() {
	var (
		configFile = flag.String("file", "cloudflare_zone.json", "Config file")
		download   = flag.Bool("download", false, "Download configuration")
	)

	flag.Parse()

	settings := getSettings()
	config := convertToConfig(settings)

	if *download {
		log.Println("Saving configuration..")
		writeConfig(config, *configFile)
	} else {
		log.Println("Comparing and updating configuration..")
		configDesired := readConfig(*configFile)
		compareConfig(config, configDesired)
	}
}

func getSettings() []ResponseSetting {
	url := fmt.Sprintf("%s/zones/%s/settings", rootURL, *zoneID)

	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		log.Fatalln("Constructing request failed:", err)
	}

	resp := makeRequest(req)
	return resp.Result
}

func makeRequest(req *http.Request) Response {
	req.Header.Set("X-Auth-Email", *authEmail)
	req.Header.Set("X-Auth-Key", *authKey)

	resp, err := httpClient.Do(req)
	if err != nil {
		log.Fatalln("Request failed:", err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatalln("Reading response body failed:", err)
	}

	if resp.StatusCode != http.StatusOK {
		log.Fatalln("Incorrect HTTP response code", resp.StatusCode, ":", string(body))
	}

	var parsedResp Response
	err = json.Unmarshal(body, &parsedResp)
	if err != nil {
		log.Fatalln("Parsing response body as JSON failed", err)
	}

	if !parsedResp.Success || len(parsedResp.Errors) > 0 {
		log.Fatalln("Response body indicated that request failed:", parsedResp)
	}

	return parsedResp
}

func convertToConfig(settings []ResponseSetting) Config {
	config := make(Config)
	for _, setting := range settings {
		config[setting.ID] = setting.Value
	}

	return config
}

func writeConfig(config Config, file string) {
	bs, err := json.MarshalIndent(config, "", "    ")
	if err != nil {
		log.Fatalln("Parsing config to JSON failed:", err)
	}

	err = ioutil.WriteFile(file, bs, 0644)
	if err != nil {
		log.Fatalln("Writing config file failed:", err)
	}
}

func readConfig(file string) Config {
	bs, err := ioutil.ReadFile(file)
	if err != nil {
		log.Fatalln("Reading config file failed:", err)
	}

	var config Config
	err = json.Unmarshal(bs, &config)
	if err != nil {
		log.Fatalln("Parsing config file as JSON failed:", err)
	}

	return config
}

func compareConfig(configActual, configDesired Config) {
	if reflect.DeepEqual(configActual, configDesired) {
		log.Println("No config changes to make")
		return
	}

	for key, valActual := range configActual {
		if valDesired, ok := configDesired[key]; ok {
			if reflect.DeepEqual(valActual, valDesired) {
				continue
			}

			log.Println("Change:", key, valActual, "->", valDesired)
		} else {
			log.Println("Not in config:", key)
		}
	}
}
<commit_msg>Find missing keys in remote config<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"reflect"
)

type Config map[string]interface{}

type Response struct {
	Success  bool
	Errors   []string
	Messages []string
	Result   []ResponseSetting
}

type ResponseSetting struct {
	ID         string
	Value      interface{}
	ModifiedOn string `json:"modified_on"`
	Editable   bool
}

const rootURL = "https://api.cloudflare.com/v4"

var (
	httpClient = &http.Client{}
	authEmail  = flag.String("email", "", "Authentication email address")
	authKey    = flag.String("key", "", "Authentication key")
	zoneID     = flag.String("zone", "", "Zone ID")
)

func main() {
	var (
		configFile = flag.String("file", "cloudflare_zone.json", "Config file")
		download   = flag.Bool("download", false, "Download configuration")
	)

	flag.Parse()

	settings := getSettings()
	config := convertToConfig(settings)

	if *download {
		log.Println("Saving configuration..")
		writeConfig(config, *configFile)
	} else {
		log.Println("Comparing and updating configuration..")
		configDesired := readConfig(*configFile)
		compareConfig(config, configDesired)
	}
}

func getSettings() []ResponseSetting {
	url := fmt.Sprintf("%s/zones/%s/settings", rootURL, *zoneID)

	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		log.Fatalln("Constructing request failed:", err)
	}

	resp := makeRequest(req)
	return resp.Result
}

func makeRequest(req *http.Request) Response {
	req.Header.Set("X-Auth-Email", *authEmail)
	req.Header.Set("X-Auth-Key", *authKey)

	resp, err := httpClient.Do(req)
	if err != nil {
		log.Fatalln("Request failed:", err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatalln("Reading response body failed:", err)
	}

	if resp.StatusCode != http.StatusOK {
		log.Fatalln("Incorrect HTTP response code", resp.StatusCode, ":", string(body))
	}

	var parsedResp Response
	err = json.Unmarshal(body, &parsedResp)
	if err != nil {
		log.Fatalln("Parsing response body as JSON failed", err)
	}

	if !parsedResp.Success || len(parsedResp.Errors) > 0 {
		log.Fatalln("Response body indicated that request failed:", parsedResp)
	}

	return parsedResp
}

func convertToConfig(settings []ResponseSetting) Config {
	config := make(Config)
	for _, setting := range settings {
		config[setting.ID] = setting.Value
	}

	return config
}

func writeConfig(config Config, file string) {
	bs, err := json.MarshalIndent(config, "", "    ")
	if err != nil {
		log.Fatalln("Parsing config to JSON failed:", err)
	}

	err = ioutil.WriteFile(file, bs, 0644)
	if err != nil {
		log.Fatalln("Writing config file failed:", err)
	}
}

func readConfig(file string) Config {
	bs, err := ioutil.ReadFile(file)
	if err != nil {
		log.Fatalln("Reading config file failed:", err)
	}

	var config Config
	err = json.Unmarshal(bs, &config)
	if err != nil {
		log.Fatalln("Parsing config file as JSON failed:", err)
	}

	return config
}

func compareConfig(configActual, configDesired Config) {
	if reflect.DeepEqual(configActual, configDesired) {
		log.Println("No config changes to make")
		return
	}

	for key, val := range configDesired {
		if _, ok := configActual[key]; !ok {
			log.Println("Missing from remote config:", key, val)
		}
	}

	for key, valActual := range configActual {
		if valDesired, ok := configDesired[key]; !ok {
			log.Println("Missing from local config:", key, valActual)
		} else if !reflect.DeepEqual(valActual, valDesired) {
			log.Println("Changing setting:", key, valActual, "->", valDesired)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"net/http"
	"encoding/json"
	"strings"
	"errors"
)

func main() {
	http.HandleFunc("/weather/", func(w http.ResponseWriter, r *http.Request) {
		city := strings.SplitN(r.URL.Path, "/", 3)[2]

		data, err := query(city)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		w.Header().Set("Content-Type", "application/json; charset=utf-8")
		json.NewEncoder(w).Encode(data)
	})
	http.ListenAndServe(":8080", nil)
}

type weatherData struct {
	Name string `json:"name"`
	Main struct {
		Kelvin float64 `json:"temp"`
	} `json:"main"`
}

func query(city string) (weatherData, error) {
	apiKey := ""
	if apiKey == "" {
		return weatherData{}, errors.New("No API key. Open main.go and set an API key.")
	}
	resp, err := http.Get("http://api.openweathermap.org/data/2.5/weather?APPID=" + apiKey + "&q=" + city)
	if err != nil {
		return weatherData{}, err
	}

	defer resp.Body.Close()

	var d weatherData

	if err := json.NewDecoder(resp.Body).Decode(&d); err != nil {
		return weatherData{}, err
	}

	return d, nil
}
<commit_msg>Create and implement a weatherProvider interface, use it to hook up to another weather source<commit_after>package main

import (
	"net/http"
	"encoding/json"
	"strings"
	"errors"
	"time"
	"log"
)

func main() {
	mw := multiWeatherProvider{
		openWeatherMap{apiKey: "your-key-here"},
		weatherUnderground{apiKey: "your-key-here"},
	}
	http.HandleFunc("/weather/", func(w http.ResponseWriter, r *http.Request) {
		begin := time.Now()
		city := strings.SplitN(r.URL.Path, "/", 3)[2]

		temp, err := mw.temperature(city)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		w.Header().Set("Content-Type", "application/json; charset=utf-8")
		json.NewEncoder(w).Encode(map[string]interface{}{
			"city": city,
			"temp": temp,
			"took": time.Since(begin).String(),
		})
	})
	http.ListenAndServe(":8080", nil)
}

// Create interface (like protocol) that requires a temperature function
type weatherProvider interface {
	temperature(city string) (float64, error) // in Kelvin
}

// Create func to query multiple weather providers and return the average temp.
type multiWeatherProvider []weatherProvider

func (w multiWeatherProvider) temperature(city string) (float64, error) {
	sum := 0.0

	for _, provider := range w {
		k, err := provider.temperature(city)
		if err != nil {
			return 0, err
		}

		sum += k
	}

	return sum / float64(len(w)), nil
}

//
type multiWeatherProviders []weatherProvider

// Create OpenWeatherMap-backed weatherProvider implementation
// NOTE: The tutorial currently doesn't have an API key here, but it needs one.
type openWeatherMap struct {
	apiKey string
}

func (w openWeatherMap) temperature(city string) (float64, error) {
	if w.apiKey == "your-key-here" {
		return 0, errors.New("No API key. Open main.go and set an API key.")
	}
	resp, err := http.Get("http://api.openweathermap.org/data/2.5/weather?APPID=" + w.apiKey + "&q=" + city)
	if err != nil {
		return 0, err
	}

	defer resp.Body.Close()

	var d struct {
		Main struct {
			Kelvin float64 `json:"temp"`
		} `json:"main"`
	}

	if err := json.NewDecoder(resp.Body).Decode(&d); err != nil {
		return 0, err
	}

	log.Printf("openWeatherMap: %s: %.2f", city, d.Main.Kelvin)
	return d.Main.Kelvin, nil
}

// Create Weather Underground-backed weatherProvider implementation
type weatherUnderground struct {
	apiKey string
}

func (w weatherUnderground) temperature(city string) (float64, error) {
	if w.apiKey == "your-key-here" {
		return 0, errors.New("No API key. Open main.go and set an API key.")
	}
	resp, err := http.Get("http://api.wunderground.com/api/" + w.apiKey + "/conditions/q/" + city + ".json")
	if err != nil {
		return 0, err
	}

	defer resp.Body.Close()

	var d struct {
		Observation struct {
			Celsius float64 `json:"temp_c"`
		} `json:"current_observation"`
	}

	if err := json.NewDecoder(resp.Body).Decode(&d); err != nil {
		return 0, err
	}

	kelvin := d.Observation.Celsius + 273.15
	log.Printf("weatherUnderground: %s: %.2f", city, kelvin)
	return kelvin, nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	"github.com/Sirupsen/logrus"
	"github.com/joho/godotenv"
	"github.com/urfave/cli"
)

var build = "0" // build number set at compile-time

func main() {
	app := cli.NewApp()
	app.Name = "s3 sync plugin"
	app.Usage = "s3 sync plugin"
	app.Action = run
	app.Version = fmt.Sprintf("1.0.%s", build)
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "access-key",
			Usage:  "aws access key",
			EnvVar: "PLUGIN_ACCESS_KEY,AWS_ACCESS_KEY_ID",
		},
		cli.StringFlag{
			Name:   "secret-key",
			Usage:  "aws secret key",
			EnvVar: "PLUGIN_SECRET_KEY,AWS_SECRET_ACCESS_KEY",
		},
		cli.StringFlag{
			Name:   "bucket",
			Usage:  "name of bucket",
			EnvVar: "PLUGIN_BUCKET",
		},
		cli.StringFlag{
			Name:   "region",
			Usage:  "aws region",
			Value:  "us-east-1",
			EnvVar: "PLUGIN_REGION",
		},
		cli.StringFlag{
			Name:   "source",
			Usage:  "upload source path",
			Value:  ".",
			EnvVar: "PLUGIN_SOURCE",
		},
		cli.StringFlag{
			Name:   "target",
			Usage:  "target path",
			Value:  "/",
			EnvVar: "PLUGIN_TARGET",
		},
		cli.BoolFlag{
			Name:   "delete",
			Usage:  "delete locally removed files from the target",
			EnvVar: "PLUGIN_DELETE",
		},
		cli.GenericFlag{
			Name:   "access",
			Usage:  "access control settings",
			EnvVar: "PLUGIN_ACCESS",
			Value:  &StringMapFlag{},
		},
		cli.GenericFlag{
			Name:   "content-type",
			Usage:  "content-type settings for uploads",
			EnvVar: "PLUGIN_CONTENT_TYPE",
			Value:  &StringMapFlag{},
		},
		cli.GenericFlag{
			Name:   "content-encoding",
			Usage:  "content-encoding settings for uploads",
			EnvVar: "PLUGIN_CONTENT_ENCODING",
			Value:  &StringMapFlag{},
		},
		cli.GenericFlag{
			Name:   "cache-control",
			Usage:  "cache-control settings for uploads",
			EnvVar: "PLUGIN_CACHE_CONTROL",
			Value:  &StringMapFlag{},
		},
		cli.GenericFlag{
			Name:   "metadata",
			Usage:  "additional metadata for uploads",
			EnvVar: "PLUGIN_METADATA",
			Value:  &DeepStringMapFlag{},
		},
		cli.GenericFlag{
			Name:   "redirects",
			Usage:  "redirects to create",
			EnvVar: "PLUGIN_REDIRECTS",
			Value:  &MapFlag{},
		},
		cli.StringFlag{
			Name:   "cloudfront-distribution",
			Usage:  "id of cloudfront distribution to invalidate",
			EnvVar: "PLUGIN_CLOUDFRONT_DISTRIBUTION",
		},
		cli.StringFlag{
			Name:  "env-file",
			Usage: "source env file",
		},
	}

	if err := app.Run(os.Args); err != nil {
		logrus.Fatal(err)
	}
}

func run(c *cli.Context) error {
	if c.String("env-file") != "" {
		_ = godotenv.Load(c.String("env-file"))
	}

	plugin := Plugin{
		Key:                    c.String("access-key"),
		Secret:                 c.String("secret-key"),
		Bucket:                 c.String("bucket"),
		Region:                 c.String("region"),
		Source:                 c.String("source"),
		Target:                 c.String("target"),
		Delete:                 c.Bool("delete"),
		Access:                 c.Generic("access").(*StringMapFlag).Get(),
		CacheControl:           c.Generic("cache-control").(*StringMapFlag).Get(),
		ContentType:            c.Generic("content-type").(*StringMapFlag).Get(),
		ContentEncoding:        c.Generic("content-encoding").(*StringMapFlag).Get(),
		Metadata:               c.Generic("metadata").(*DeepStringMapFlag).Get(),
		Redirects:              c.Generic("redirects").(*MapFlag).Get(),
		CloudFrontDistribution: c.String("cloudfront-distribution"),
	}

	return plugin.Exec()
}
<commit_msg>Support `acl` or `access` in Yaml<commit_after>package main

import (
	"fmt"
	"os"

	"github.com/Sirupsen/logrus"
	"github.com/joho/godotenv"
	"github.com/urfave/cli"
)

var build = "0" // build number set at compile-time

func main() {
	app := cli.NewApp()
	app.Name = "s3 sync plugin"
	app.Usage = "s3 sync plugin"
	app.Action = run
	app.Version = fmt.Sprintf("1.0.%s", build)
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "access-key",
			Usage:  "aws access key",
			EnvVar: "PLUGIN_ACCESS_KEY,AWS_ACCESS_KEY_ID",
		},
		cli.StringFlag{
			Name:   "secret-key",
			Usage:  "aws secret key",
			EnvVar: "PLUGIN_SECRET_KEY,AWS_SECRET_ACCESS_KEY",
		},
		cli.StringFlag{
			Name:   "bucket",
			Usage:  "name of bucket",
			EnvVar: "PLUGIN_BUCKET",
		},
		cli.StringFlag{
			Name:   "region",
			Usage:  "aws region",
			Value:  "us-east-1",
			EnvVar: "PLUGIN_REGION",
		},
		cli.StringFlag{
			Name:   "source",
			Usage:  "upload source path",
			Value:  ".",
			EnvVar: "PLUGIN_SOURCE",
		},
		cli.StringFlag{
			Name:   "target",
			Usage:  "target path",
			Value:  "/",
			EnvVar: "PLUGIN_TARGET",
		},
		cli.BoolFlag{
			Name:   "delete",
			Usage:  "delete locally removed files from the target",
			EnvVar: "PLUGIN_DELETE",
		},
		cli.GenericFlag{
			Name:   "access",
			Usage:  "access control settings",
			EnvVar: "PLUGIN_ACCESS,PLUGIN_ACL",
			Value:  &StringMapFlag{},
		},
		cli.GenericFlag{
			Name:   "content-type",
			Usage:  "content-type settings for uploads",
			EnvVar: "PLUGIN_CONTENT_TYPE",
			Value:  &StringMapFlag{},
		},
		cli.GenericFlag{
			Name:   "content-encoding",
			Usage:  "content-encoding settings for uploads",
			EnvVar: "PLUGIN_CONTENT_ENCODING",
			Value:  &StringMapFlag{},
		},
		cli.GenericFlag{
			Name:   "cache-control",
			Usage:  "cache-control settings for uploads",
			EnvVar: "PLUGIN_CACHE_CONTROL",
			Value:  &StringMapFlag{},
		},
		cli.GenericFlag{
			Name:   "metadata",
			Usage:  "additional metadata for uploads",
			EnvVar: "PLUGIN_METADATA",
			Value:  &DeepStringMapFlag{},
		},
		cli.GenericFlag{
			Name:   "redirects",
			Usage:  "redirects to create",
			EnvVar: "PLUGIN_REDIRECTS",
			Value:  &MapFlag{},
		},
		cli.StringFlag{
			Name:   "cloudfront-distribution",
			Usage:  "id of cloudfront distribution to invalidate",
			EnvVar: "PLUGIN_CLOUDFRONT_DISTRIBUTION",
		},
		cli.StringFlag{
			Name:  "env-file",
			Usage: "source env file",
		},
	}

	if err := app.Run(os.Args); err != nil {
		logrus.Fatal(err)
	}
}

func run(c *cli.Context) error {
	if c.String("env-file") != "" {
		_ = godotenv.Load(c.String("env-file"))
	}

	plugin := Plugin{
		Key:                    c.String("access-key"),
		Secret:                 c.String("secret-key"),
		Bucket:                 c.String("bucket"),
		Region:                 c.String("region"),
		Source:                 c.String("source"),
		Target:                 c.String("target"),
		Delete:                 c.Bool("delete"),
		Access:                 c.Generic("access").(*StringMapFlag).Get(),
		CacheControl:           c.Generic("cache-control").(*StringMapFlag).Get(),
		ContentType:            c.Generic("content-type").(*StringMapFlag).Get(),
		ContentEncoding:        c.Generic("content-encoding").(*StringMapFlag).Get(),
		Metadata:               c.Generic("metadata").(*DeepStringMapFlag).Get(),
		Redirects:              c.Generic("redirects").(*MapFlag).Get(),
		CloudFrontDistribution: c.String("cloudfront-distribution"),
	}

	return plugin.Exec()
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/disiqueira/tindergo"
)

func main() {
	token := flag.String("token", "", "Your Facebook Token.")

	flag.Parse()

	if *token == "" {
		fmt.Println("You must provide a valid Facebook Token.")
		os.Exit(2)
	}

	t := tindergo.New()

	err := t.Authenticate(*token)
	checkError(err)

	profile, err := t.Profile()
	checkError(err)

	fmt.Println("Your Profile:")
	fmt.Println("Name: " + profile.Name)
	fmt.Println("")

	err = getRecs(t)
	checkError(err)
}

func getRecs(t *tindergo.TinderGo) error {
	var allRecs map[string]tindergo.RecsCoreUser
	var countRecs map[string]int

	for j := 0; j <= 3; j++ {
		recs, err := t.RecsCore()
		if err != nil {
			return err
		}

		for _, elem := range recs {
			_, exist := allRecs[elem.ID]
			if exist {
				countRecs[elem.ID] = countRecs[elem.ID] + 1
			} else {
				countRecs[elem.ID] = 1
				allRecs[elem.ID] = elem
			}
		}
	}
}

// checkError Panic application if has an error returned.
func checkError(err error) {
	if err != nil {
		panic(err)
	}
}
<commit_msg>Creating a func to find equal recs<commit_after>package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/disiqueira/tindergo"
)

func main() {
	token := flag.String("token", "", "Your Facebook Token.")

	flag.Parse()

	if *token == "" {
		fmt.Println("You must provide a valid Facebook Token.")
		os.Exit(2)
	}

	t := tindergo.New()

	err := t.Authenticate(*token)
	checkError(err)

	profile, err := t.Profile()
	checkError(err)

	fmt.Println("Your Profile:")
	fmt.Println("Name: " + profile.Name)
	fmt.Println("")

	err = getRecs(t)
	checkError(err)
}

// getRecs makes four requests to find common results.
func getRecs(t *tindergo.TinderGo) error {
	var allRecs map[string]tindergo.RecsCoreUser
	var countRecs map[string]int

	for j := 0; j <= 3; j++ {
		recs, err := t.RecsCore()
		if err != nil {
			return err
		}

		for _, elem := range recs {
			_, exist := allRecs[elem.ID]
			if exist {
				countRecs[elem.ID] = countRecs[elem.ID] + 1
			} else {
				countRecs[elem.ID] = 1
				allRecs[elem.ID] = elem
			}
		}
	}
}

// checkError Panic application if has an error returned.
func checkError(err error) {
	if err != nil {
		panic(err)
	}
}
<|endoftext|>