<commit_before>package cmd

import (
	"os/exec"

	"github.com/gobuffalo/buffalo/buffalo/cmd/generate"
	"github.com/markbates/gentronics"
)

func newAppGenerator(data gentronics.Data) *gentronics.Generator {
	g := gentronics.New()
	g.Add(gentronics.NewFile("main.go", nMain))
	g.Add(gentronics.NewFile("Procfile", nProcfile))
	g.Add(gentronics.NewFile("Procfile.development", nProcfileDev))
	g.Add(gentronics.NewFile(".buffalo.dev.yml", nRefresh))
	g.Add(gentronics.NewFile("actions/app.go", nApp))
	g.Add(gentronics.NewFile("actions/home.go", nHomeHandler))
	g.Add(gentronics.NewFile("actions/home_test.go", nHomeHandlerTest))
	g.Add(gentronics.NewFile("actions/render.go", nRender))
	g.Add(gentronics.NewFile("grifts/routes.go", nGriftRoutes))
	g.Add(gentronics.NewFile("templates/index.html", nIndexHTML))
	g.Add(gentronics.NewFile("templates/application.html", nApplicationHTML))
	g.Add(&gentronics.RemoteFile{
		File:       gentronics.NewFile("assets/images/logo.svg", ""),
		RemotePath: "https://raw.githubusercontent.com/gobuffalo/buffalo/master/logo.svg",
	})
	g.Add(gentronics.NewFile(".gitignore", nGitignore))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/markbates/refresh/...")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/markbates/refresh")))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/markbates/grift/...")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/markbates/grift")))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/motemen/gore")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/motemen/gore")))
	g.Add(generate.NewWebpackGenerator(data))
	g.Add(newSodaGenerator())
	g.Add(gentronics.NewCommand(appGoGet()))
	g.Add(generate.Fmt)
	return g
}

func appGoGet() *exec.Cmd {
	appArgs := []string{"get", "-t"}
	if verbose {
		appArgs = append(appArgs, "-v")
	}
	appArgs = append(appArgs, "./...")
	return exec.Command("go", appArgs...)
}

const nMain = `package main

import (
	"fmt"
	"log"
	"net/http"
	"os"

	"{{actionsPath}}"
	"github.com/markbates/going/defaults"
)

func main() {
	port := defaults.String(os.Getenv("PORT"), "3000")
	log.Printf("Starting {{name}} on port %s\n", port)
	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), actions.App()))
}

`
const nApp = `package actions

import (
	"os"

	"github.com/gobuffalo/buffalo"
	{{#if withPop }}
	"github.com/gobuffalo/buffalo/middleware"
	"{{modelsPath}}"
	{{/if}}
	"github.com/markbates/going/defaults"
)

// ENV is used to help switch settings based on where the
// application is being run. Default is "development".
var ENV = defaults.String(os.Getenv("GO_ENV"), "development")
var app *buffalo.App

// App is where all routes and middleware for buffalo
// should be defined. This is the nerve center of your
// application.
func App() *buffalo.App {
	if app == nil {
		app = buffalo.Automatic(buffalo.Options{
			Env: ENV,
		})

		{{#if withPop }}
		app.Use(middleware.PopTransaction(models.DB))
		{{/if}}

		app.GET("/", HomeHandler)

		app.ServeFiles("/assets", assetsPath())
	}

	return app
}
`

const nRender = `package actions

import (
	"net/http"

	rice "github.com/GeertJohan/go.rice"
	"github.com/gobuffalo/buffalo/render"
	"github.com/gobuffalo/buffalo/render/resolvers"
)

var r *render.Engine
var resolver = &resolvers.RiceBox{
	Box: rice.MustFindBox("../templates"),
}

func init() {
	r = render.New(render.Options{
		HTMLLayout:     "application.html",
		CacheTemplates: ENV == "production",
		FileResolver:   resolver,
	})
}

func assetsPath() http.FileSystem {
	box := rice.MustFindBox("../public/assets")
	return box.HTTPBox()
}
`

const nHomeHandler = `package actions

import "github.com/gobuffalo/buffalo"

// HomeHandler is a default handler to serve up
// a home page.
func HomeHandler(c buffalo.Context) error {
	return c.Render(200, r.HTML("index.html"))
}
`

const nHomeHandlerTest = `package actions_test

import (
	"testing"

	"{{actionsPath}}"
	"github.com/markbates/willie"
	"github.com/stretchr/testify/require"
)

func Test_HomeHandler(t *testing.T) {
	r := require.New(t)

	w := willie.New(actions.App())
	res := w.Request("/").Get()

	r.Equal(200, res.Code)
	r.Contains(res.Body.String(), "Welcome to Buffalo!")
}
`

const nIndexHTML = `

Welcome to Buffalo! [v{{version}}]

       https://github.com/gobuffalo/buffalo

       Documentation

Defined Routes

          METHOD
          PATH
          HANDLER

        \{{#each routes as |r|}}

          \{{r.Method}}
          \{{r.Path}}
          \{{r.HandlerName}}

        \{{/each}}

`

const nApplicationHTML = `

  <meta charset="utf-8">
  <title>Buffalo - {{ titleName }}</title>
  <link rel="stylesheet" href="/assets/application.css" type="text/css" media="all" />

    \{{ yield }}

`

const nGitignore = `vendor/
**/*.log
**/*.sqlite
bin/
node_modules/
.sass-cache/
{{ name }}
`

const nGriftRoutes = `package grifts

import (
	"os"

	. "github.com/markbates/grift/grift"
	"{{actionsPath}}"
	"github.com/olekukonko/tablewriter"
)

var _ = Add("routes", func(c *Context) error {
	a := actions.App()
	routes := a.Routes()

	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Method", "Path", "Handler"})
	for _, r := range routes {
		table.Append([]string{r.Method, r.Path, r.HandlerName})
	}
	table.SetCenterSeparator("|")
	table.SetAlignment(tablewriter.ALIGN_LEFT)
	table.Render()
	return nil
})`

const nRefresh = `app_root: .
ignored_folders:
- vendor
- log
- logs
- assets
- public
- grifts
- tmp
- node_modules
- .sass-cache
included_extensions:
- .go
- .html
- .md
- .js
- .tmpl
build_path: /tmp
build_delay: 200ns
binary_name: {{name}}-build
command_flags: []
enable_colors: true
log_name: buffalo
`

const nProcfile = `web: {{name}}`
const nProcfileDev = `web: buffalo dev
{{#if withWebpack}}
assets: webpack --watch
{{/if}}
`
<commit_msg>issue-35: readme generator<commit_after>package cmd

import (
	"os/exec"

	"github.com/gobuffalo/buffalo/buffalo/cmd/generate"
	"github.com/markbates/gentronics"
)

func newAppGenerator(data gentronics.Data) *gentronics.Generator {
	g := gentronics.New()
	g.Add(gentronics.NewFile("README.md", nREADME))
	g.Add(gentronics.NewFile("main.go", nMain))
	g.Add(gentronics.NewFile("Procfile", nProcfile))
	g.Add(gentronics.NewFile("Procfile.development", nProcfileDev))
	g.Add(gentronics.NewFile(".buffalo.dev.yml", nRefresh))
	g.Add(gentronics.NewFile("actions/app.go", nApp))
	g.Add(gentronics.NewFile("actions/home.go", nHomeHandler))
	g.Add(gentronics.NewFile("actions/home_test.go", nHomeHandlerTest))
	g.Add(gentronics.NewFile("actions/render.go", nRender))
	g.Add(gentronics.NewFile("grifts/routes.go", nGriftRoutes))
	g.Add(gentronics.NewFile("templates/index.html", nIndexHTML))
	g.Add(gentronics.NewFile("templates/application.html", nApplicationHTML))
	g.Add(&gentronics.RemoteFile{
		File:       gentronics.NewFile("assets/images/logo.svg", ""),
		RemotePath: "https://raw.githubusercontent.com/gobuffalo/buffalo/master/logo.svg",
	})
	g.Add(gentronics.NewFile(".gitignore", nGitignore))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/markbates/refresh/...")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/markbates/refresh")))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/markbates/grift/...")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/markbates/grift")))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/motemen/gore")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/motemen/gore")))
	g.Add(generate.NewWebpackGenerator(data))
	g.Add(newSodaGenerator())
	g.Add(gentronics.NewCommand(appGoGet()))
	g.Add(generate.Fmt)
	return g
}

func appGoGet() *exec.Cmd {
	appArgs := []string{"get", "-t"}
	if verbose {
		appArgs = append(appArgs, "-v")
	}
	appArgs = append(appArgs, "./...")
	return exec.Command("go", appArgs...)
}

const nREADME = `# {{name}}

## Documentation

To view generated docs for {{name}}, run the below command and point your brower to http://127.0.0.1:6060

 godoc -http=:6060 2>/dev/null &

`

const nMain = `package main

import (
	"fmt"
	"log"
	"net/http"
	"os"

	"{{actionsPath}}"
	"github.com/markbates/going/defaults"
)

func main() {
	port := defaults.String(os.Getenv("PORT"), "3000")
	log.Printf("Starting {{name}} on port %s\n", port)
	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), actions.App()))
}

`
const nApp = `package actions

import (
	"os"

	"github.com/gobuffalo/buffalo"
	{{#if withPop }}
	"github.com/gobuffalo/buffalo/middleware"
	"{{modelsPath}}"
	{{/if}}
	"github.com/markbates/going/defaults"
)

// ENV is used to help switch settings based on where the
// application is being run. Default is "development".
var ENV = defaults.String(os.Getenv("GO_ENV"), "development")
var app *buffalo.App

// App is where all routes and middleware for buffalo
// should be defined. This is the nerve center of your
// application.
func App() *buffalo.App {
	if app == nil {
		app = buffalo.Automatic(buffalo.Options{
			Env: ENV,
		})

		{{#if withPop }}
		app.Use(middleware.PopTransaction(models.DB))
		{{/if}}

		app.GET("/", HomeHandler)

		app.ServeFiles("/assets", assetsPath())
	}

	return app
}
`

const nRender = `package actions

import (
	"net/http"

	rice "github.com/GeertJohan/go.rice"
	"github.com/gobuffalo/buffalo/render"
	"github.com/gobuffalo/buffalo/render/resolvers"
)

var r *render.Engine
var resolver = &resolvers.RiceBox{
	Box: rice.MustFindBox("../templates"),
}

func init() {
	r = render.New(render.Options{
		HTMLLayout:     "application.html",
		CacheTemplates: ENV == "production",
		FileResolver:   resolver,
	})
}

func assetsPath() http.FileSystem {
	box := rice.MustFindBox("../public/assets")
	return box.HTTPBox()
}
`

const nHomeHandler = `package actions

import "github.com/gobuffalo/buffalo"

// HomeHandler is a default handler to serve up
// a home page.
func HomeHandler(c buffalo.Context) error {
	return c.Render(200, r.HTML("index.html"))
}
`

const nHomeHandlerTest = `package actions_test

import (
	"testing"

	"{{actionsPath}}"
	"github.com/markbates/willie"
	"github.com/stretchr/testify/require"
)

func Test_HomeHandler(t *testing.T) {
	r := require.New(t)

	w := willie.New(actions.App())
	res := w.Request("/").Get()

	r.Equal(200, res.Code)
	r.Contains(res.Body.String(), "Welcome to Buffalo!")
}
`

const nIndexHTML = `

Welcome to Buffalo! [v{{version}}]

       https://github.com/gobuffalo/buffalo

       Documentation

Defined Routes

          METHOD
          PATH
          HANDLER

        \{{#each routes as |r|}}

          \{{r.Method}}
          \{{r.Path}}
          \{{r.HandlerName}}

        \{{/each}}

`

const nApplicationHTML = `

  <meta charset="utf-8">
  <title>Buffalo - {{ titleName }}</title>
  <link rel="stylesheet" href="/assets/application.css" type="text/css" media="all" />

    \{{ yield }}

`

const nGitignore = `vendor/
**/*.log
**/*.sqlite
bin/
node_modules/
.sass-cache/
{{ name }}
`

const nGriftRoutes = `package grifts

import (
	"os"

	. "github.com/markbates/grift/grift"
	"{{actionsPath}}"
	"github.com/olekukonko/tablewriter"
)

var _ = Add("routes", func(c *Context) error {
	a := actions.App()
	routes := a.Routes()

	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Method", "Path", "Handler"})
	for _, r := range routes {
		table.Append([]string{r.Method, r.Path, r.HandlerName})
	}
	table.SetCenterSeparator("|")
	table.SetAlignment(tablewriter.ALIGN_LEFT)
	table.Render()
	return nil
})`

const nRefresh = `app_root: .
ignored_folders:
- vendor
- log
- logs
- assets
- public
- grifts
- tmp
- node_modules
- .sass-cache
included_extensions:
- .go
- .html
- .md
- .js
- .tmpl
build_path: /tmp
build_delay: 200ns
binary_name: {{name}}-build
command_flags: []
enable_colors: true
log_name: buffalo
`

const nProcfile = `web: {{name}}`
const nProcfileDev = `web: buffalo dev
{{#if withWebpack}}
assets: webpack --watch
{{/if}}
`
<|endoftext|>


<commit_before>package cmd

import (
	"os/exec"

	"github.com/gobuffalo/buffalo/buffalo/cmd/generate"
	"github.com/markbates/gentronics"
)

func newAppGenerator(data gentronics.Data) *gentronics.Generator {
	g := gentronics.New()
	g.Add(gentronics.NewFile("README.md", nREADME))
	g.Add(gentronics.NewFile("main.go", nMain))
	g.Add(gentronics.NewFile(".buffalo.dev.yml", nRefresh))
	g.Add(gentronics.NewFile(".codeclimate.yml", nCodeClimate))
	g.Add(gentronics.NewFile("actions/app.go", nApp))
	g.Add(gentronics.NewFile("actions/home.go", nHomeHandler))
	g.Add(gentronics.NewFile("actions/home_test.go", nHomeHandlerTest))
	g.Add(gentronics.NewFile("actions/render.go", nRender))
	g.Add(gentronics.NewFile("grifts/routes.go", nGriftRoutes))
	g.Add(gentronics.NewFile("templates/index.html", nIndexHTML))
	g.Add(gentronics.NewFile("templates/application.html", nApplicationHTML))
	g.Add(gentronics.NewFile(".gitignore", nGitignore))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/markbates/refresh/...")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/markbates/refresh")))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/markbates/grift/...")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/markbates/grift")))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/motemen/gore")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/motemen/gore")))
	g.Add(generate.NewWebpackGenerator(data))
	g.Add(newSodaGenerator())
	g.Add(gentronics.NewCommand(appGoGet()))
	g.Add(generate.Fmt)
	return g
}

func appGoGet() *exec.Cmd {
	appArgs := []string{"get", "-t"}
	if verbose {
		appArgs = append(appArgs, "-v")
	}
	appArgs = append(appArgs, "./...")
	return exec.Command("go", appArgs...)
}

const nREADME = `# {{name}}

## Documentation

To view generated docs for {{name}}, run the below command and point your browser to http://127.0.0.1:6060/pkg/

    godoc -http=:6060 2>/dev/null &

### Buffalo

http://gobuffalo.io/docs/getting-started

### Pop/Soda

http://gobuffalo.io/docs/db

## Database Configuration

 	development:
 		dialect: postgres
 		database: {{name}}_development
 		user: <username>
 		password: <password>
 		host: 127.0.0.1
 		pool: 5

 	test:
 		dialect: postgres
 		database: {{name}}_test
 		user: <username>
 		password: <password>
 		host: 127.0.0.1

 	production:
 		dialect: postgres
 		database: {{name}}_production
 		user: <username>
 		password: <password>
 		host: 127.0.0.1
 		pool: 25

 ### Running Migrations

    buffalo soda migrate

 ## Run Tests

    buffalo test

 ## Run in dev

    buffalo dev

[Powered by Buffalo](http://gobuffalo.io)

`
const nMain = `package main

import (
	"fmt"
	"log"
	"net/http"
	"os"

	"{{actionsPath}}"
	"github.com/markbates/going/defaults"
)

func main() {
	port := defaults.String(os.Getenv("PORT"), "3000")
	log.Printf("Starting {{name}} on port %s\n", port)
	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), actions.App()))
}

`
const nApp = `package actions

import (
	"os"

	"github.com/gobuffalo/buffalo"
	{{#if withPop }}
	"github.com/gobuffalo/buffalo/middleware"
	"{{modelsPath}}"
	{{/if}}
	"github.com/markbates/going/defaults"
)

// ENV is used to help switch settings based on where the
// application is being run. Default is "development".
var ENV = defaults.String(os.Getenv("GO_ENV"), "development")
var app *buffalo.App

// App is where all routes and middleware for buffalo
// should be defined. This is the nerve center of your
// application.
func App() *buffalo.App {
	if app == nil {
		app = buffalo.Automatic(buffalo.Options{
			Env: ENV,
		})

		{{#if withPop }}
		app.Use(middleware.PopTransaction(models.DB))
		{{/if}}

		app.GET("/", HomeHandler)

		app.ServeFiles("/assets", assetsPath())
	}

	return app
}
`

const nRender = `package actions

import (
	"net/http"

	rice "github.com/GeertJohan/go.rice"
	"github.com/gobuffalo/buffalo/render"
	"github.com/gobuffalo/buffalo/render/resolvers"
)

var r *render.Engine

func init() {
	r = render.New(render.Options{
		HTMLLayout:     "application.html",
		CacheTemplates: ENV == "production",
		FileResolverFunc: func() resolvers.FileResolver {
			return &resolvers.RiceBox{
				Box: rice.MustFindBox("../templates"),
			}
		},
	})
}

func assetsPath() http.FileSystem {
	box := rice.MustFindBox("../public/assets")
	return box.HTTPBox()
}
`

const nHomeHandler = `package actions

import "github.com/gobuffalo/buffalo"

// HomeHandler is a default handler to serve up
// a home page.
func HomeHandler(c buffalo.Context) error {
	return c.Render(200, r.HTML("index.html"))
}
`

const nHomeHandlerTest = `package actions_test

import (
	"testing"

	"{{actionsPath}}"
	"github.com/markbates/willie"
	"github.com/stretchr/testify/require"
)

func Test_HomeHandler(t *testing.T) {
	r := require.New(t)

	w := willie.New(actions.App())
	res := w.Request("/").Get()

	r.Equal(200, res.Code)
	r.Contains(res.Body.String(), "Welcome to Buffalo!")
}
`

const nIndexHTML = `

Welcome to Buffalo! [v{{version}}]

       https://github.com/gobuffalo/buffalo

       Documentation

Defined Routes

          METHOD
          PATH
          HANDLER

        \{{#each routes as |r|}}

          \{{r.Method}}
          \{{r.Path}}
          \{{r.HandlerName}}

        \{{/each}}

`

const nApplicationHTML = `

  <meta charset="utf-8">
  <title>Buffalo - {{ titleName }}</title>
  <link rel="stylesheet" href="/assets/application.css" type="text/css" media="all" />

    \{{ yield }}

`

const nGitignore = `vendor/
**/*.log
**/*.sqlite
.idea/
bin/
tmp/
node_modules/
.sass-cache/
rice-box.go
public/assets/
{{ name }}
`

const nGriftRoutes = `package grifts

import (
	"os"

	. "github.com/markbates/grift/grift"
	"{{actionsPath}}"
	"github.com/olekukonko/tablewriter"
)

var _ = Add("routes", func(c *Context) error {
	a := actions.App()
	routes := a.Routes()

	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Method", "Path", "Handler"})
	for _, r := range routes {
		table.Append([]string{r.Method, r.Path, r.HandlerName})
	}
	table.SetCenterSeparator("|")
	table.SetAlignment(tablewriter.ALIGN_LEFT)
	table.Render()
	return nil
})`

const nRefresh = `app_root: .
ignored_folders:
- vendor
- log
- logs
- assets
- public
- grifts
- tmp
- bin
- node_modules
- .sass-cache
included_extensions:
- .go
- .html
- .md
- .js
- .tmpl
build_path: tmp
build_delay: 200ns
binary_name: {{name}}-build
command_flags: []
enable_colors: true
log_name: buffalo
`

const nCodeClimate = `engines:
  golint:
    enabled: true
  govet:
    enabled: true
  gofmt:
    enabled: true
  fixme:
    enabled: true
 ratings:
   paths:
    - "**.go"
 exclude_paths:
   - "grifts/**/*"
   - "**/*_test.go"
   - "*_test.go"
   - "**_test.go"
   - "logs/*"
   - "public/*"
   - "templates/*"

`
<commit_msg>Fixes #173<commit_after>package cmd

import (
	"os/exec"

	"github.com/gobuffalo/buffalo/buffalo/cmd/generate"
	"github.com/markbates/gentronics"
)

func newAppGenerator(data gentronics.Data) *gentronics.Generator {
	g := gentronics.New()
	g.Add(gentronics.NewFile("README.md", nREADME))
	g.Add(gentronics.NewFile("main.go", nMain))
	g.Add(gentronics.NewFile(".buffalo.dev.yml", nRefresh))
	g.Add(gentronics.NewFile(".codeclimate.yml", nCodeClimate))
	g.Add(gentronics.NewFile("actions/app.go", nApp))
	g.Add(gentronics.NewFile("actions/home.go", nHomeHandler))
	g.Add(gentronics.NewFile("actions/home_test.go", nHomeHandlerTest))
	g.Add(gentronics.NewFile("actions/render.go", nRender))
	g.Add(gentronics.NewFile("grifts/routes.go", nGriftRoutes))
	g.Add(gentronics.NewFile("templates/index.html", nIndexHTML))
	g.Add(gentronics.NewFile("templates/application.html", nApplicationHTML))
	g.Add(gentronics.NewFile(".gitignore", nGitignore))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/markbates/refresh/...")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/markbates/refresh")))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/markbates/grift/...")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/markbates/grift")))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/motemen/gore")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/motemen/gore")))
	g.Add(generate.NewWebpackGenerator(data))
	g.Add(newSodaGenerator())
	g.Add(gentronics.NewCommand(appGoGet()))
	g.Add(generate.Fmt)
	return g
}

func appGoGet() *exec.Cmd {
	appArgs := []string{"get", "-t"}
	if verbose {
		appArgs = append(appArgs, "-v")
	}
	appArgs = append(appArgs, "./...")
	return exec.Command("go", appArgs...)
}

const nREADME = `# {{name}}

## Documentation

To view generated docs for {{name}}, run the below command and point your browser to http://127.0.0.1:6060/pkg/

    godoc -http=:6060 2>/dev/null &

### Buffalo

http://gobuffalo.io/docs/getting-started

### Pop/Soda

http://gobuffalo.io/docs/db

## Database Configuration

 	development:
 		dialect: postgres
 		database: {{name}}_development
 		user: <username>
 		password: <password>
 		host: 127.0.0.1
 		pool: 5

 	test:
 		dialect: postgres
 		database: {{name}}_test
 		user: <username>
 		password: <password>
 		host: 127.0.0.1

 	production:
 		dialect: postgres
 		database: {{name}}_production
 		user: <username>
 		password: <password>
 		host: 127.0.0.1
 		pool: 25

 ### Running Migrations

    buffalo soda migrate

 ## Run Tests

    buffalo test

 ## Run in dev

    buffalo dev

[Powered by Buffalo](http://gobuffalo.io)

`
const nMain = `package main

import (
	"fmt"
	"log"
	"net/http"
	"os"

	"{{actionsPath}}"
	"github.com/markbates/going/defaults"
)

func main() {
	port := defaults.String(os.Getenv("PORT"), "3000")
	log.Printf("Starting {{name}} on port %s\n", port)
	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), actions.App()))
}

`
const nApp = `package actions

import (
	"os"

	"github.com/gobuffalo/buffalo"
	{{#if withPop }}
	"github.com/gobuffalo/buffalo/middleware"
	"{{modelsPath}}"
	{{/if}}
	"github.com/markbates/going/defaults"
)

// ENV is used to help switch settings based on where the
// application is being run. Default is "development".
var ENV = defaults.String(os.Getenv("GO_ENV"), "development")
var app *buffalo.App

// App is where all routes and middleware for buffalo
// should be defined. This is the nerve center of your
// application.
func App() *buffalo.App {
	if app == nil {
		app = buffalo.Automatic(buffalo.Options{
			Env: ENV,
		})

		{{#if withPop }}
		app.Use(middleware.PopTransaction(models.DB))
		{{/if}}

		app.GET("/", HomeHandler)

		app.ServeFiles("/assets", assetsPath())
	}

	return app
}
`

const nRender = `package actions

import (
	"net/http"

	rice "github.com/GeertJohan/go.rice"
	"github.com/gobuffalo/buffalo/render"
	"github.com/gobuffalo/buffalo/render/resolvers"
)

var r *render.Engine

func init() {
	r = render.New(render.Options{
		HTMLLayout:     "application.html",
		CacheTemplates: ENV == "production",
		FileResolverFunc: func() resolvers.FileResolver {
			return &resolvers.RiceBox{
				Box: rice.MustFindBox("../templates"),
			}
		},
	})
}

func assetsPath() http.FileSystem {
	box := rice.MustFindBox("../public/assets")
	return box.HTTPBox()
}
`

const nHomeHandler = `package actions

import "github.com/gobuffalo/buffalo"

// HomeHandler is a default handler to serve up
// a home page.
func HomeHandler(c buffalo.Context) error {
	return c.Render(200, r.HTML("index.html"))
}
`

const nHomeHandlerTest = `package actions_test

import (
	"testing"

	"{{actionsPath}}"
	"github.com/markbates/willie"
	"github.com/stretchr/testify/require"
)

func Test_HomeHandler(t *testing.T) {
	r := require.New(t)

	w := willie.New(actions.App())
	res := w.Request("/").Get()

	r.Equal(200, res.Code)
	r.Contains(res.Body.String(), "Welcome to Buffalo!")
}
`

const nIndexHTML = `

Welcome to Buffalo! [v{{version}}]

       https://github.com/gobuffalo/buffalo

       Documentation

Defined Routes

          METHOD
          PATH
          HANDLER

        \{{#each routes as |r|}}

          \{{r.Method}}
          \{{r.Path}}
          \{{r.HandlerName}}

        \{{/each}}

`

const nApplicationHTML = `

  <meta charset="utf-8">
  <title>Buffalo - {{ titleName }}</title>
  <link rel="stylesheet" href="/assets/application.css" type="text/css" media="all" />

    \{{ yield }}

`

const nGitignore = `vendor/
**/*.log
**/*.sqlite
.idea/
bin/
tmp/
node_modules/
.sass-cache/
rice-box.go
public/assets/
{{ name }}
`

const nGriftRoutes = `package grifts

import (
	"os"

	. "github.com/markbates/grift/grift"
	"{{actionsPath}}"
	"github.com/olekukonko/tablewriter"
)

var _ = Add("routes", func(c *Context) error {
	a := actions.App()
	routes := a.Routes()

	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Method", "Path", "Handler"})
	for _, r := range routes {
		table.Append([]string{r.Method, r.Path, r.HandlerName})
	}
	table.SetCenterSeparator("|")
	table.SetAlignment(tablewriter.ALIGN_LEFT)
	table.Render()
	return nil
})`

const nRefresh = `app_root: .
ignored_folders:
- vendor
- log
- logs
- assets
- public
- grifts
- tmp
- bin
- node_modules
- .sass-cache
included_extensions:
- .go
- .html
- .md
- .js
- .tmpl
build_path: tmp
build_delay: 200ns
binary_name: {{name}}-build
command_flags: []
enable_colors: true
log_name: buffalo
`

const nCodeClimate = `engines:
  fixme:
    enabled: true
  gofmt:
    enabled: true
  golint:
    enabled: true
  govet:
    enabled: true
exclude_paths:
  - grifts/**/*
  - "**/*_test.go"
  - "*_test.go"
  - "**_test.go"
  - logs/*
  - public/*
  - templates/*
ratings:
  paths:
    - "**.go"

`
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/conformal/btcutil"
	"github.com/conformal/go-flags"
	"os"
	"path/filepath"
	"strings"
)

var (
	btcdHomeDir        = btcutil.AppDataDir("btcd", false)
	btcctlHomeDir      = btcutil.AppDataDir("btcctl", false)
	defaultConfigFile  = filepath.Join(btcctlHomeDir, "btcctl.conf")
	defaultRPCCertFile = filepath.Join(btcdHomeDir, "rpc.cert")
)

// config defines the configuration options for btcctl.
//
// See loadConfig for details on the configuration load process.
type config struct {
	ShowVersion   bool   `short:"V" long:"version" description:"Display version information and exit"`
	ConfigFile    string `short:"C" long:"configfile" description:"Path to configuration file"`
	RPCUser       string `short:"u" long:"rpcuser" description:"RPC username"`
	RPCPassword   string `short:"P" long:"rpcpass" default-mask:"-" description:"RPC password"`
	RPCServer     string `short:"s" long:"rpcserver" description:"RPC server to connect to"`
	RPCCert       string `short:"c" long:"rpccert" description:"RPC server certificate chain for validation"`
	NoTls         bool   `long:"notls" description:"Disable TLS"`
	TlsSkipVerify bool   `long:"skipverify" description:"Do not verify tls certificates (not recommended!)"`
}

// loadConfig initializes and parses the config using a config file and command
// line options.
//
// The configuration proceeds as follows:
// 	1) Start with a default config with sane settings
// 	2) Pre-parse the command line to check for an alternative config file
// 	3) Load configuration file overwriting defaults with any specified options
// 	4) Parse CLI options and overwrite/add any specified options
//
// The above results in functioning properly without any config settings
// while still allowing the user to override settings with config files and
// command line options.  Command line options always take precedence.
func loadConfig() (*flags.Parser, *config, []string, error) {
	// Default config.
	cfg := config{
		ConfigFile: defaultConfigFile,
		RPCServer:  "localhost:8334",
		RPCCert:    defaultRPCCertFile,
	}

	// Create the home directory if it doesn't already exist.
	err := os.MkdirAll(btcdHomeDir, 0700)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%v\n", err)
		os.Exit(-1)
	}

	// Pre-parse the command line options to see if an alternative config
	// file or the version flag was specified.  Any errors can be ignored
	// here since they will be caught be the final parse below.
	preCfg := cfg
	preParser := flags.NewParser(&preCfg, flags.None)
	preParser.Parse()

	// Show the version and exit if the version flag was specified.
	if preCfg.ShowVersion {
		appName := filepath.Base(os.Args[0])
		appName = strings.TrimSuffix(appName, filepath.Ext(appName))
		fmt.Println(appName, "version", version())
		os.Exit(0)
	}

	// Load additional config from file.
	parser := flags.NewParser(&cfg, flags.PassDoubleDash|flags.HelpFlag)
	err = flags.NewIniParser(parser).ParseFile(preCfg.ConfigFile)
	if err != nil {
		if _, ok := err.(*os.PathError); !ok {
			fmt.Fprintln(os.Stderr, err)
			return parser, nil, nil, err
		}
	}

	// Parse command line options again to ensure they take precedence.
	remainingArgs, err := parser.Parse()
	if err != nil {
		return parser, nil, nil, err
	}

	return parser, &cfg, remainingArgs, nil
}
<commit_msg>Expand btcctl RPC cert path to from config file.<commit_after>package main

import (
	"fmt"
	"github.com/conformal/btcutil"
	"github.com/conformal/go-flags"
	"os"
	"path/filepath"
	"strings"
)

var (
	btcdHomeDir        = btcutil.AppDataDir("btcd", false)
	btcctlHomeDir      = btcutil.AppDataDir("btcctl", false)
	defaultConfigFile  = filepath.Join(btcctlHomeDir, "btcctl.conf")
	defaultRPCCertFile = filepath.Join(btcdHomeDir, "rpc.cert")
)

// config defines the configuration options for btcctl.
//
// See loadConfig for details on the configuration load process.
type config struct {
	ShowVersion   bool   `short:"V" long:"version" description:"Display version information and exit"`
	ConfigFile    string `short:"C" long:"configfile" description:"Path to configuration file"`
	RPCUser       string `short:"u" long:"rpcuser" description:"RPC username"`
	RPCPassword   string `short:"P" long:"rpcpass" default-mask:"-" description:"RPC password"`
	RPCServer     string `short:"s" long:"rpcserver" description:"RPC server to connect to"`
	RPCCert       string `short:"c" long:"rpccert" description:"RPC server certificate chain for validation"`
	NoTls         bool   `long:"notls" description:"Disable TLS"`
	TlsSkipVerify bool   `long:"skipverify" description:"Do not verify tls certificates (not recommended!)"`
}

// cleanAndExpandPath expands environement variables and leading ~ in the
// passed path, cleans the result, and returns it.
func cleanAndExpandPath(path string) string {
	// Expand initial ~ to OS specific home directory.
	if strings.HasPrefix(path, "~") {
		homeDir := filepath.Dir(btcctlHomeDir)
		path = strings.Replace(path, "~", homeDir, 1)
	}

	// NOTE: The os.ExpandEnv doesn't work with Windows-style %VARIABLE%,
	// but they variables can still be expanded via POSIX-style $VARIABLE.
	return filepath.Clean(os.ExpandEnv(path))
}

// loadConfig initializes and parses the config using a config file and command
// line options.
//
// The configuration proceeds as follows:
// 	1) Start with a default config with sane settings
// 	2) Pre-parse the command line to check for an alternative config file
// 	3) Load configuration file overwriting defaults with any specified options
// 	4) Parse CLI options and overwrite/add any specified options
//
// The above results in functioning properly without any config settings
// while still allowing the user to override settings with config files and
// command line options.  Command line options always take precedence.
func loadConfig() (*flags.Parser, *config, []string, error) {
	// Default config.
	cfg := config{
		ConfigFile: defaultConfigFile,
		RPCServer:  "localhost:8334",
		RPCCert:    defaultRPCCertFile,
	}

	// Create the home directory if it doesn't already exist.
	err := os.MkdirAll(btcdHomeDir, 0700)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%v\n", err)
		os.Exit(-1)
	}

	// Pre-parse the command line options to see if an alternative config
	// file or the version flag was specified.  Any errors can be ignored
	// here since they will be caught be the final parse below.
	preCfg := cfg
	preParser := flags.NewParser(&preCfg, flags.None)
	preParser.Parse()

	// Show the version and exit if the version flag was specified.
	if preCfg.ShowVersion {
		appName := filepath.Base(os.Args[0])
		appName = strings.TrimSuffix(appName, filepath.Ext(appName))
		fmt.Println(appName, "version", version())
		os.Exit(0)
	}

	// Load additional config from file.
	parser := flags.NewParser(&cfg, flags.PassDoubleDash|flags.HelpFlag)
	err = flags.NewIniParser(parser).ParseFile(preCfg.ConfigFile)
	if err != nil {
		if _, ok := err.(*os.PathError); !ok {
			fmt.Fprintln(os.Stderr, err)
			return parser, nil, nil, err
		}
	}

	// Parse command line options again to ensure they take precedence.
	remainingArgs, err := parser.Parse()
	if err != nil {
		return parser, nil, nil, err
	}

	// Handle environment variable expansion in the RPC certificate path.
	cfg.RPCCert = cleanAndExpandPath(cfg.RPCCert)

	return parser, &cfg, remainingArgs, nil
}
<|endoftext|>


<commit_before>package health

import (
	"encoding/json"
	"fmt"
	"github.com/Comcast/webpa-common/logging"
	"net/http"
	"sync"
	"time"
)

// StatsListener receives Stats on regular intervals.
type StatsListener interface {
	// OnStats is called with a copy of the health's stats map
	// at regular intervals.
	OnStats(Stats)
}

// StatsListenerFunc is a function type that implements StatsListener.
type StatsListenerFunc func(Stats)

func (f StatsListenerFunc) OnStats(stats Stats) {
	f(stats)
}

// Health is the central type of this package.  It defines and endpoint for tracking
// and updating various statistics.  It also dispatches events to one or more StatsListeners
// at regular intervals.
type Health struct {
	stats            Stats
	statDumpInterval time.Duration
	log              logging.Logger
	events           chan HealthFunc
	statsListeners   []StatsListener
	memInfoReader    *MemInfoReader
	once             sync.Once
}

// AddStatsListener adds a new listener to this Health.  This method
// is asynchronous.  The listener will eventually receive events, but callers
// should not assume events will be dispatched immediately after this method call.
func (h *Health) AddStatsListener(listener StatsListener) {
	h.SendEvent(func(stat Stats) {
		h.statsListeners = append(h.statsListeners, listener)
	})
}

// SendEvent dispatches a HealthFunc to the internal event queue
func (h *Health) SendEvent(healthFunc HealthFunc) {
	h.events <- healthFunc
}

// New creates a Health object with the given statistics.
func New(interval time.Duration, log logging.Logger, options ...Option) *Health {
	initialStats := commonStats.Clone()
	initialStats.Apply(options...)

	return &Health{
		stats:            initialStats,
		statDumpInterval: interval,
		log:              log,
		memInfoReader:    &MemInfoReader{},
	}
}

// Run executes this Health object.  This method is idempotent:  once a
// Health object is Run, it cannot be Run again.
func (h *Health) Run(waitGroup *sync.WaitGroup, shutdown <-chan struct{}) error {
	h.once.Do(func() {
		h.log.Debug("Health Monitor Started")
		h.events = make(chan HealthFunc, 100)

		waitGroup.Add(1)
		go func() {
			defer waitGroup.Done()
			ticker := time.NewTicker(h.statDumpInterval)
			defer ticker.Stop()
			defer h.log.Debug("Health Monitor Stopped")
			defer close(h.events)

			for {
				select {
				case <-shutdown:
					return

				case hf := <-h.events:
					hf(h.stats)

				case <-ticker.C:
					h.stats.UpdateMemory(h.memInfoReader)
					dispatchStats := h.stats.Clone()
					for _, statsListener := range h.statsListeners {
						statsListener.OnStats(dispatchStats)
					}
				}
			}
		}()
	})

	return nil
}

func (h *Health) ServeHTTP(response http.ResponseWriter, request *http.Request) {
	ch := make(chan Stats)
	defer close(ch)

	h.SendEvent(func(stats Stats) {
		stats.UpdateMemory(h.memInfoReader)
		jsonmsg, err := json.Marshal(stats)
		response.Header().Set("Content-Type", "application/json")

		// TODO: leverage the standard error writing elsewhere in webpa-common
		if err != nil {
			h.log.Error("Could not marshal stats: %v", err)
			response.WriteHeader(http.StatusInternalServerError)
			fmt.Fprintf(response, `{"message": "%s"}\n`, err.Error())
		} else {
			fmt.Fprintf(response, "%s", jsonmsg)
		}
	})
}
<commit_msg>Fixed the issue with no output from ServeHTTP<commit_after>package health

import (
	"encoding/json"
	"fmt"
	"github.com/Comcast/webpa-common/logging"
	"net/http"
	"sync"
	"time"
)

// StatsListener receives Stats on regular intervals.
type StatsListener interface {
	// OnStats is called with a copy of the health's stats map
	// at regular intervals.
	OnStats(Stats)
}

// StatsListenerFunc is a function type that implements StatsListener.
type StatsListenerFunc func(Stats)

func (f StatsListenerFunc) OnStats(stats Stats) {
	f(stats)
}

// Health is the central type of this package.  It defines and endpoint for tracking
// and updating various statistics.  It also dispatches events to one or more StatsListeners
// at regular intervals.
type Health struct {
	stats            Stats
	statDumpInterval time.Duration
	log              logging.Logger
	events           chan HealthFunc
	statsListeners   []StatsListener
	memInfoReader    *MemInfoReader
	once             sync.Once
}

// AddStatsListener adds a new listener to this Health.  This method
// is asynchronous.  The listener will eventually receive events, but callers
// should not assume events will be dispatched immediately after this method call.
func (h *Health) AddStatsListener(listener StatsListener) {
	h.SendEvent(func(stat Stats) {
		h.statsListeners = append(h.statsListeners, listener)
	})
}

// SendEvent dispatches a HealthFunc to the internal event queue
func (h *Health) SendEvent(healthFunc HealthFunc) {
	h.events <- healthFunc
}

// New creates a Health object with the given statistics.
func New(interval time.Duration, log logging.Logger, options ...Option) *Health {
	initialStats := commonStats.Clone()
	initialStats.Apply(options...)

	return &Health{
		stats:            initialStats,
		statDumpInterval: interval,
		log:              log,
		memInfoReader:    &MemInfoReader{},
	}
}

// Run executes this Health object.  This method is idempotent:  once a
// Health object is Run, it cannot be Run again.
func (h *Health) Run(waitGroup *sync.WaitGroup, shutdown <-chan struct{}) error {
	h.once.Do(func() {
		h.log.Debug("Health Monitor Started")
		h.events = make(chan HealthFunc, 100)

		waitGroup.Add(1)
		go func() {
			defer waitGroup.Done()
			ticker := time.NewTicker(h.statDumpInterval)
			defer ticker.Stop()
			defer h.log.Debug("Health Monitor Stopped")
			defer close(h.events)

			for {
				select {
				case <-shutdown:
					return

				case hf := <-h.events:
					hf(h.stats)

				case <-ticker.C:
					h.stats.UpdateMemory(h.memInfoReader)
					dispatchStats := h.stats.Clone()
					for _, statsListener := range h.statsListeners {
						statsListener.OnStats(dispatchStats)
					}
				}
			}
		}()
	})

	return nil
}

func (h *Health) ServeHTTP(response http.ResponseWriter, request *http.Request) {
	output := make(chan Stats, 1)
	defer close(output)

	h.SendEvent(func(stats Stats) {
		stats.UpdateMemory(h.memInfoReader)
		output <- stats.Clone()
	})

	stats := <-output
	response.Header().Set("Content-Type", "application/json")
	data, err := json.Marshal(stats)

	// TODO: leverage the standard error writing elsewhere in webpa-common
	if err != nil {
		h.log.Error("Could not marshal stats: %v", err)
		response.WriteHeader(http.StatusInternalServerError)
		fmt.Fprintf(response, `{"message": "%s"}\n`, err.Error())
	} else {
		fmt.Fprintf(response, "%s", data)
	}
}
<|endoftext|>


<commit_before>package health

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"sync"
	"time"

	"golang.org/x/sync/errgroup"

	"github.com/robustirc/internal/robusthttp"
)

type ServerStatus struct {
	Server string

	State          string
	Leader         string
	Peers          []string
	AppliedIndex   uint64
	CommitIndex    uint64
	LastContact    time.Time
	ExecutableHash string
	CurrentTime    time.Time
}

func GetServerStatus(server, networkPassword string) (ServerStatus, error) {
	var status ServerStatus
	if !strings.HasPrefix(server, "https://") {
		server = fmt.Sprintf("https://%s/", server)
	}
	req, err := http.NewRequest("GET", server, nil)
	if err != nil {
		return status, err
	}
	req.Header.Set("Accept", "application/json")
	resp, err := robusthttp.Client(networkPassword, true).Do(req)
	if err != nil {
		return status, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return status, fmt.Errorf("Expected HTTP OK, got %v", resp.Status)
	}

	err = json.NewDecoder(resp.Body).Decode(&status)
	ioutil.ReadAll(resp.Body)
	return status, err
}

func CollectStatuses(servers []string, networkPassword string) (map[string]ServerStatus, error) {
	var (
		statuses   = make(map[string]ServerStatus, len(servers))
		statusesMu sync.Mutex
		g          errgroup.Group
	)
	setStatus := func(status ServerStatus) {
		statusesMu.Lock()
		defer statusesMu.Unlock()
		statuses[status.Server] = status
	}
	for _, server := range servers {
		server := server // capture range variable
		g.Go(func() error {
			status, err := GetServerStatus(server, networkPassword)
			if err != nil {
				return err
			}
			status.Server = server
			setStatus(status)
			return nil
		})
	}
	return statuses, g.Wait()
}
<commit_msg>health: GetServerStatus: set 5 second deadline via context<commit_after>package health

import (
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"sync"
	"time"

	"golang.org/x/sync/errgroup"

	"github.com/robustirc/internal/robusthttp"
)

type ServerStatus struct {
	Server string

	State          string
	Leader         string
	Peers          []string
	AppliedIndex   uint64
	CommitIndex    uint64
	LastContact    time.Time
	ExecutableHash string
	CurrentTime    time.Time
}

func GetServerStatus(server, networkPassword string) (ServerStatus, error) {
	var status ServerStatus
	if !strings.HasPrefix(server, "https://") {
		server = fmt.Sprintf("https://%s/", server)
	}
	req, err := http.NewRequest("GET", server, nil)
	if err != nil {
		return status, err
	}
	ctx, canc := context.WithTimeout(context.Background(), 5*time.Second)
	defer canc()
	req = req.WithContext(ctx)
	req.Header.Set("Accept", "application/json")
	resp, err := robusthttp.Client(networkPassword, true).Do(req)
	if err != nil {
		return status, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return status, fmt.Errorf("Expected HTTP OK, got %v", resp.Status)
	}

	err = json.NewDecoder(resp.Body).Decode(&status)
	ioutil.ReadAll(resp.Body)
	return status, err
}

func CollectStatuses(servers []string, networkPassword string) (map[string]ServerStatus, error) {
	var (
		statuses   = make(map[string]ServerStatus, len(servers))
		statusesMu sync.Mutex
		g          errgroup.Group
	)
	setStatus := func(status ServerStatus) {
		statusesMu.Lock()
		defer statusesMu.Unlock()
		statuses[status.Server] = status
	}
	for _, server := range servers {
		server := server // capture range variable
		g.Go(func() error {
			status, err := GetServerStatus(server, networkPassword)
			if err != nil {
				return err
			}
			status.Server = server
			setStatus(status)
			return nil
		})
	}
	return statuses, g.Wait()
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/goji/httpauth"
	"github.com/vanng822/r2router"
	"net/http"
)

// Example how to use basic auth together with r2router
func main() {
	router := r2router.NewSeeforRouter()

	// basic auth for entire route
	http.Handle("/", httpauth.SimpleBasicAuth("testuser", "testpw")(router))

	router.Get("/hello/:name", func(w http.ResponseWriter, r *http.Request, p r2router.Params) {
		w.Write([]byte( p.Get("name")))
	})

	http.ListenAndServe("127.0.0.1:8080", nil)
}<commit_msg>We can now use SimpleBasicAuth as Before middleware<commit_after>package main

import (
	"github.com/goji/httpauth"
	"github.com/vanng822/r2router"
	"net/http"
)

// Example how to use basic auth together with r2router
func main() {
	router := r2router.NewSeeforRouter()

	// basic auth for entire router
	router.Before(httpauth.SimpleBasicAuth("testuser", "testpw"))

	router.Get("/hello/:name", func(w http.ResponseWriter, r *http.Request, p r2router.Params) {
		w.Write([]byte( p.Get("name")))
	})

	http.ListenAndServe("127.0.0.1:8080", router)
}<|endoftext|>


<commit_before>package vagrant

import (
	"bytes"
	"fmt"
	"log"
	"os"
	"os/exec"
	"regexp"
	"strings"
	"time"

	"github.com/hashicorp/go-version"
)

const VAGRANT_MIN_VERSION = ">= 2.0.2"

type Vagrant_2_2_Driver struct {
	vagrantBinary string
	VagrantCWD    string
}

// Calls "vagrant init"
func (d *Vagrant_2_2_Driver) Init(args []string) error {
	_, _, err := d.vagrantCmd(append([]string{"init"}, args...)...)
	return err
}

// Calls "vagrant add"
func (d *Vagrant_2_2_Driver) Add(args []string) error {
	// vagrant box add partyvm ubuntu-14.04.vmware.box
	_, _, err := d.vagrantCmd(append([]string{"box", "add"}, args...)...)
	return err
}

// Calls "vagrant up"
func (d *Vagrant_2_2_Driver) Up(args []string) (string, string, error) {
	stdout, stderr, err := d.vagrantCmd(append([]string{"up"}, args...)...)
	return stdout, stderr, err
}

// Calls "vagrant halt"
func (d *Vagrant_2_2_Driver) Halt(id string) error {
	args := []string{"halt"}
	if id != "" {
		args = append(args, id)
	}
	_, _, err := d.vagrantCmd(args...)
	return err
}

// Calls "vagrant suspend"
func (d *Vagrant_2_2_Driver) Suspend(id string) error {
	args := []string{"suspend"}
	if id != "" {
		args = append(args, id)
	}
	_, _, err := d.vagrantCmd(args...)
	return err
}

// Calls "vagrant destroy"
func (d *Vagrant_2_2_Driver) Destroy(id string) error {
	args := []string{"destroy", "-f"}
	if id != "" {
		args = append(args, id)
	}
	_, _, err := d.vagrantCmd(args...)
	return err
}

// Calls "vagrant package"
func (d *Vagrant_2_2_Driver) Package(args []string) error {
	// Ideally we'd pass vagrantCWD into the package command but
	// we have to change directory into the vagrant cwd instead in order to
	// work around an upstream bug with the vagrant-libvirt plugin.
	// We can stop doing this when
	// https://github.com/vagrant-libvirt/vagrant-libvirt/issues/765
	// is fixed.
	oldDir, _ := os.Getwd()
	os.Chdir(d.VagrantCWD)
	defer os.Chdir(oldDir)
	args = append(args, "--output", "package.box")
	_, _, err := d.vagrantCmd(append([]string{"package"}, args...)...)
	return err
}

// Verify makes sure that Vagrant exists at the given path
func (d *Vagrant_2_2_Driver) Verify() error {
	vagrantPath, err := exec.LookPath(d.vagrantBinary)
	if err != nil {
		return fmt.Errorf("Can't find Vagrant binary!")
	}
	_, err = os.Stat(vagrantPath)
	if err != nil {
		return fmt.Errorf("Can't find Vagrant binary.")
	}

	constraints, err := version.NewConstraint(VAGRANT_MIN_VERSION)
	if err != nil {
		return fmt.Errorf("error parsing vagrant minimum version: %v", err)
	}
	vers, err := d.Version()
	if err != nil {
		return fmt.Errorf("error getting virtualbox version: %v", err)
	}
	v, err := version.NewVersion(vers)
	if err != nil {
		return fmt.Errorf("Error figuring out Vagrant version.")
	}

	if !constraints.Check(v) {
		return fmt.Errorf("installed Vagrant version must be >=2.0.2")
	}

	return nil
}

type VagrantSSHConfig struct {
	Hostname               string
	User                   string
	Port                   string
	UserKnownHostsFile     string
	StrictHostKeyChecking  bool
	PasswordAuthentication bool
	IdentityFile           string
	IdentitiesOnly         bool
	LogLevel               string
}

func parseSSHConfig(lines []string, value string) string {
	out := ""
	for _, line := range lines {
		if index := strings.Index(line, value); index != -1 {
			out = line[index+len(value):]
		}
	}
	return strings.Trim(out, "\r\n")
}

func yesno(yn string) bool {
	if yn == "no" {
		return false
	}
	return true
}

func (d *Vagrant_2_2_Driver) SSHConfig(id string) (*VagrantSSHConfig, error) {
	// vagrant ssh-config --host 8df7860
	args := []string{"ssh-config"}
	if id != "" {
		args = append(args, id)
	}
	stdout, _, err := d.vagrantCmd(args...)
	sshConf := &VagrantSSHConfig{}

	lines := strings.Split(stdout, "\n")
	sshConf.Hostname = parseSSHConfig(lines, "HostName ")
	sshConf.User = parseSSHConfig(lines, "User ")
	sshConf.Port = parseSSHConfig(lines, "Port ")
	sshConf.UserKnownHostsFile = parseSSHConfig(lines, "UserKnownHostsFile ")
	sshConf.IdentityFile = parseSSHConfig(lines, "IdentityFile ")
	sshConf.LogLevel = parseSSHConfig(lines, "LogLevel ")

	// handle the booleans
	sshConf.StrictHostKeyChecking = yesno(parseSSHConfig(lines, "StrictHostKeyChecking "))
	sshConf.PasswordAuthentication = yesno(parseSSHConfig(lines, "PasswordAuthentication "))
	sshConf.IdentitiesOnly = yesno((parseSSHConfig(lines, "IdentitiesOnly ")))

	return sshConf, err
}

// Version reads the version of VirtualBox that is installed.
func (d *Vagrant_2_2_Driver) Version() (string, error) {
	stdoutString, _, err := d.vagrantCmd([]string{"--version"}...)
	// Example stdout:

	// 	Installed Version: 2.2.3
	//
	// Vagrant was unable to check for the latest version of Vagrant.
	// Please check manually at https://www.vagrantup.com

	// Use regex to find version
	reg := regexp.MustCompile(`(\d+\.)?(\d+\.)?(\*|\d+)`)
	version := reg.FindString(stdoutString)
	if version == "" {
		return "", err
	}

	return version, nil
}

func (d *Vagrant_2_2_Driver) vagrantCmd(args ...string) (string, string, error) {
	var stdout, stderr bytes.Buffer

	log.Printf("Calling Vagrant CLI: %#v", args)
	cmd := exec.Command(d.vagrantBinary, args...)
	cmd.Env = append(os.Environ(), fmt.Sprintf("VAGRANT_CWD=%s", d.VagrantCWD))
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr

	err := cmd.Start()
	if err != nil {
		return "", "", fmt.Errorf("Error starting vagrant command with args: %q",
			strings.Join(args, " "))
	}

	stdoutString := ""
	stderrString := ""

	donech := make(chan bool)

	go func() {
		for {
			select {
			case <-donech:
				line := stdout.String()
				if line != "" {
					log.Printf("[vagrant driver] stdout: %s", line)
				}
				stdoutString += line
				line = stderr.String()
				if line != "" {
					log.Printf("[vagrant driver] stderr: %s", line)
				}
				stderrString += line
			default:
				line, _ := stdout.ReadString('\n')
				if line != "" {
					log.Printf("[vagrant driver] stdout: %s", line)
					stdoutString += line

				}
				line, _ = stderr.ReadString('\n')
				if line != "" {
					log.Printf("[vagrant driver] stderr: %s", line)
					stderrString += line

				}
				time.Sleep(500)
			}
		}
	}()

	err = cmd.Wait()

	donech <- true

	if _, ok := err.(*exec.ExitError); ok {
		err = fmt.Errorf("Vagrant error: %s", stderrString)
	}

	return stdoutString, stderrString, err
}
<commit_msg>break out of loop once channel is read from.<commit_after>package vagrant

import (
	"bytes"
	"fmt"
	"log"
	"os"
	"os/exec"
	"regexp"
	"strings"
	"time"

	"github.com/hashicorp/go-version"
)

const VAGRANT_MIN_VERSION = ">= 2.0.2"

type Vagrant_2_2_Driver struct {
	vagrantBinary string
	VagrantCWD    string
}

// Calls "vagrant init"
func (d *Vagrant_2_2_Driver) Init(args []string) error {
	_, _, err := d.vagrantCmd(append([]string{"init"}, args...)...)
	return err
}

// Calls "vagrant add"
func (d *Vagrant_2_2_Driver) Add(args []string) error {
	// vagrant box add partyvm ubuntu-14.04.vmware.box
	_, _, err := d.vagrantCmd(append([]string{"box", "add"}, args...)...)
	return err
}

// Calls "vagrant up"
func (d *Vagrant_2_2_Driver) Up(args []string) (string, string, error) {
	stdout, stderr, err := d.vagrantCmd(append([]string{"up"}, args...)...)
	return stdout, stderr, err
}

// Calls "vagrant halt"
func (d *Vagrant_2_2_Driver) Halt(id string) error {
	args := []string{"halt"}
	if id != "" {
		args = append(args, id)
	}
	_, _, err := d.vagrantCmd(args...)
	return err
}

// Calls "vagrant suspend"
func (d *Vagrant_2_2_Driver) Suspend(id string) error {
	args := []string{"suspend"}
	if id != "" {
		args = append(args, id)
	}
	_, _, err := d.vagrantCmd(args...)
	return err
}

// Calls "vagrant destroy"
func (d *Vagrant_2_2_Driver) Destroy(id string) error {
	args := []string{"destroy", "-f"}
	if id != "" {
		args = append(args, id)
	}
	_, _, err := d.vagrantCmd(args...)
	return err
}

// Calls "vagrant package"
func (d *Vagrant_2_2_Driver) Package(args []string) error {
	// Ideally we'd pass vagrantCWD into the package command but
	// we have to change directory into the vagrant cwd instead in order to
	// work around an upstream bug with the vagrant-libvirt plugin.
	// We can stop doing this when
	// https://github.com/vagrant-libvirt/vagrant-libvirt/issues/765
	// is fixed.
	oldDir, _ := os.Getwd()
	os.Chdir(d.VagrantCWD)
	defer os.Chdir(oldDir)
	args = append(args, "--output", "package.box")
	_, _, err := d.vagrantCmd(append([]string{"package"}, args...)...)
	return err
}

// Verify makes sure that Vagrant exists at the given path
func (d *Vagrant_2_2_Driver) Verify() error {
	vagrantPath, err := exec.LookPath(d.vagrantBinary)
	if err != nil {
		return fmt.Errorf("Can't find Vagrant binary!")
	}
	_, err = os.Stat(vagrantPath)
	if err != nil {
		return fmt.Errorf("Can't find Vagrant binary.")
	}

	constraints, err := version.NewConstraint(VAGRANT_MIN_VERSION)
	if err != nil {
		return fmt.Errorf("error parsing vagrant minimum version: %v", err)
	}
	vers, err := d.Version()
	if err != nil {
		return fmt.Errorf("error getting virtualbox version: %v", err)
	}
	v, err := version.NewVersion(vers)
	if err != nil {
		return fmt.Errorf("Error figuring out Vagrant version.")
	}

	if !constraints.Check(v) {
		return fmt.Errorf("installed Vagrant version must be >=2.0.2")
	}

	return nil
}

type VagrantSSHConfig struct {
	Hostname               string
	User                   string
	Port                   string
	UserKnownHostsFile     string
	StrictHostKeyChecking  bool
	PasswordAuthentication bool
	IdentityFile           string
	IdentitiesOnly         bool
	LogLevel               string
}

func parseSSHConfig(lines []string, value string) string {
	out := ""
	for _, line := range lines {
		if index := strings.Index(line, value); index != -1 {
			out = line[index+len(value):]
		}
	}
	return strings.Trim(out, "\r\n")
}

func yesno(yn string) bool {
	if yn == "no" {
		return false
	}
	return true
}

func (d *Vagrant_2_2_Driver) SSHConfig(id string) (*VagrantSSHConfig, error) {
	// vagrant ssh-config --host 8df7860
	args := []string{"ssh-config"}
	if id != "" {
		args = append(args, id)
	}
	stdout, _, err := d.vagrantCmd(args...)
	sshConf := &VagrantSSHConfig{}

	lines := strings.Split(stdout, "\n")
	sshConf.Hostname = parseSSHConfig(lines, "HostName ")
	sshConf.User = parseSSHConfig(lines, "User ")
	sshConf.Port = parseSSHConfig(lines, "Port ")
	sshConf.UserKnownHostsFile = parseSSHConfig(lines, "UserKnownHostsFile ")
	sshConf.IdentityFile = parseSSHConfig(lines, "IdentityFile ")
	sshConf.LogLevel = parseSSHConfig(lines, "LogLevel ")

	// handle the booleans
	sshConf.StrictHostKeyChecking = yesno(parseSSHConfig(lines, "StrictHostKeyChecking "))
	sshConf.PasswordAuthentication = yesno(parseSSHConfig(lines, "PasswordAuthentication "))
	sshConf.IdentitiesOnly = yesno((parseSSHConfig(lines, "IdentitiesOnly ")))

	return sshConf, err
}

// Version reads the version of VirtualBox that is installed.
func (d *Vagrant_2_2_Driver) Version() (string, error) {
	stdoutString, _, err := d.vagrantCmd([]string{"--version"}...)
	// Example stdout:

	// 	Installed Version: 2.2.3
	//
	// Vagrant was unable to check for the latest version of Vagrant.
	// Please check manually at https://www.vagrantup.com

	// Use regex to find version
	reg := regexp.MustCompile(`(\d+\.)?(\d+\.)?(\*|\d+)`)
	version := reg.FindString(stdoutString)
	if version == "" {
		return "", err
	}

	return version, nil
}

func (d *Vagrant_2_2_Driver) vagrantCmd(args ...string) (string, string, error) {
	var stdout, stderr bytes.Buffer

	log.Printf("Calling Vagrant CLI: %#v", args)
	cmd := exec.Command(d.vagrantBinary, args...)
	cmd.Env = append(os.Environ(), fmt.Sprintf("VAGRANT_CWD=%s", d.VagrantCWD))
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr

	err := cmd.Start()
	if err != nil {
		return "", "", fmt.Errorf("Error starting vagrant command with args: %q",
			strings.Join(args, " "))
	}

	stdoutString := ""
	stderrString := ""

	donech := make(chan bool)

	go func() {
		for {
			select {
			case <-donech:
				line := stdout.String()
				if line != "" {
					log.Printf("[vagrant driver] stdout: %s", line)
				}
				stdoutString += line
				line = stderr.String()
				if line != "" {
					log.Printf("[vagrant driver] stderr: %s", line)
				}
				stderrString += line
				break
			default:
				line, _ := stdout.ReadString('\n')
				if line != "" {
					log.Printf("[vagrant driver] stdout: %s", line)
					stdoutString += line

				}
				line, _ = stderr.ReadString('\n')
				if line != "" {
					log.Printf("[vagrant driver] stderr: %s", line)
					stderrString += line

				}
				time.Sleep(500)
			}
		}
	}()

	err = cmd.Wait()

	donech <- true

	if _, ok := err.(*exec.ExitError); ok {
		err = fmt.Errorf("Vagrant error: %s", stderrString)
	}

	return stdoutString, stderrString, err
}
<|endoftext|>


<commit_before>package ai

import (
	"bytes"
	"log"

	"nelhage.com/tak/ptn"
	"nelhage.com/tak/tak"
)

const (
	maxEval int64 = 1 << 30
	minEval       = -maxEval
)

type MinimaxAI struct {
	depth int

	Debug bool
}

func formatpv(ms []tak.Move) string {
	var out bytes.Buffer
	out.WriteString("[")
	for i, m := range ms {
		if i != 0 {
			out.WriteString(" ")
		}
		out.WriteString(ptn.FormatMove(&m))
	}
	out.WriteString("]")
	return out.String()
}

func (m *MinimaxAI) GetMove(p *tak.Position) tak.Move {
	ms, _ := m.Analyze(p)
	return ms[0]
}

func (m *MinimaxAI) Analyze(p *tak.Position) ([]tak.Move, int64) {
	var ms []tak.Move
	var v int64
	for i := 1; i <= m.depth; i++ {
		ms, v = m.minimax(p, i, ms, minEval-1, maxEval+1)
		if m.Debug {
			log.Printf("[minimax] depth=%d val=%d pv=%s",
				i, v, formatpv(ms))
		}
	}
	return ms, v
}

func (ai *MinimaxAI) minimax(
	p *tak.Position,
	depth int,
	pv []tak.Move,
	α, β int64) ([]tak.Move, int64) {
	over, _ := p.GameOver()
	if depth == 0 || over {
		return nil, ai.evaluate(p)
	}

	if p.MoveNumber() < 2 {
		for _, c := range [][]int{{0, 0}, {p.Size() - 1, 0}, {0, p.Size() - 1}, {p.Size() - 1, p.Size() - 1}} {
			x, y := c[0], c[1]
			if len(p.At(x, y)) == 0 {
				return []tak.Move{{X: x, Y: y, Type: tak.PlaceFlat}}, 0
			}
		}
	}
	moves := p.AllMoves()
	if len(pv) > 0 {
		for i, m := range moves {
			if m.Equal(&pv[0]) {
				moves[0], moves[i] = moves[i], moves[0]
				break
			}
		}
	}

	best := make([]tak.Move, 1, depth)
	max := minEval - 1
	for _, m := range moves {
		child, e := p.Move(&m)
		if e != nil {
			continue
		}
		ms, v := ai.minimax(child, depth-1, nil, -β, -α)
		v = -v
		if v > max {
			max = v
			best[0] = m
			best = append(best[:1], ms...)
		}
		if v > α {
			α = v
			if α >= β {
				break
			}
		}
	}
	return best, max
}

func imin(a, b int) int {
	if a < b {
		return a
	}
	return b
}

const (
	weightFlat       = 1
	weightCaptured   = 1
	weightControlled = 5
)

func (m *MinimaxAI) evaluate(p *tak.Position) int64 {
	if over, winner := p.GameOver(); over {
		switch winner {
		case tak.NoColor:
			return 0
		case p.ToMove():
			return maxEval - int64(p.MoveNumber())
		default:
			return minEval + int64(p.MoveNumber())
		}
	}
	mine, theirs := 0, 0
	me := p.ToMove()
	addw := func(c tak.Color, w int) {
		if c == me {
			mine += w
		} else {
			theirs += w
		}
	}
	for x := 0; x < p.Size(); x++ {
		for y := 0; y < p.Size(); y++ {
			sq := p.At(x, y)
			if len(sq) == 0 {
				continue
			}
			addw(sq[0].Color(), weightControlled)
			for i, stone := range sq {
				if i > 0 && i < p.Size() {
					addw(sq[0].Color(), weightCaptured)
				}
				if stone.Kind() == tak.Flat {
					addw(stone.Color(), weightFlat)
				}
			}
		}
	}

	return int64(mine - theirs)
}

func NewMinimax(depth int) *MinimaxAI {
	return &MinimaxAI{depth: depth}
}
<commit_msg>killer heuristic<commit_after>package ai

import (
	"bytes"
	"log"

	"nelhage.com/tak/ptn"
	"nelhage.com/tak/tak"
)

const (
	maxEval int64 = 1 << 30
	minEval       = -maxEval
)

type MinimaxAI struct {
	depth int

	Debug bool
}

func formatpv(ms []tak.Move) string {
	var out bytes.Buffer
	out.WriteString("[")
	for i, m := range ms {
		if i != 0 {
			out.WriteString(" ")
		}
		out.WriteString(ptn.FormatMove(&m))
	}
	out.WriteString("]")
	return out.String()
}

func (m *MinimaxAI) GetMove(p *tak.Position) tak.Move {
	ms, _ := m.Analyze(p)
	return ms[0]
}

func (m *MinimaxAI) Analyze(p *tak.Position) ([]tak.Move, int64) {
	var ms []tak.Move
	var v int64
	for i := 1; i <= m.depth; i++ {
		ms, v = m.minimax(p, i, ms, minEval-1, maxEval+1)
		if m.Debug {
			log.Printf("[minimax] depth=%d val=%d pv=%s",
				i, v, formatpv(ms))
		}
	}
	return ms, v
}

func (ai *MinimaxAI) minimax(
	p *tak.Position,
	depth int,
	pv []tak.Move,
	α, β int64) ([]tak.Move, int64) {
	over, _ := p.GameOver()
	if depth == 0 || over {
		return nil, ai.evaluate(p)
	}

	if p.MoveNumber() < 2 {
		for _, c := range [][]int{{0, 0}, {p.Size() - 1, 0}, {0, p.Size() - 1}, {p.Size() - 1, p.Size() - 1}} {
			x, y := c[0], c[1]
			if len(p.At(x, y)) == 0 {
				return []tak.Move{{X: x, Y: y, Type: tak.PlaceFlat}}, 0
			}
		}
	}
	moves := p.AllMoves()
	if len(pv) > 0 {
		for i, m := range moves {
			if m.Equal(&pv[0]) {
				moves[0], moves[i] = moves[i], moves[0]
				break
			}
		}
	}

	best := make([]tak.Move, 0, depth)
	max := minEval - 1
	for _, m := range moves {
		child, e := p.Move(&m)
		if e != nil {
			continue
		}
		var ms []tak.Move
		var v int64
		if len(best) == 0 {
			ms, v = ai.minimax(child, depth-1, nil, -β, -α)
		} else {
			ms, v = ai.minimax(child, depth-1, best[1:], -β, -α)
		}
		v = -v
		if v > max {
			max = v
			best = append(best[:0], m)
			best = append(best, ms...)
		}
		if v > α {
			α = v
			if α >= β {
				break
			}
		}
	}
	return best, max
}

func imin(a, b int) int {
	if a < b {
		return a
	}
	return b
}

const (
	weightFlat       = 1
	weightCaptured   = 1
	weightControlled = 5
)

func (m *MinimaxAI) evaluate(p *tak.Position) int64 {
	if over, winner := p.GameOver(); over {
		switch winner {
		case tak.NoColor:
			return 0
		case p.ToMove():
			return maxEval - int64(p.MoveNumber())
		default:
			return minEval + int64(p.MoveNumber())
		}
	}
	mine, theirs := 0, 0
	me := p.ToMove()
	addw := func(c tak.Color, w int) {
		if c == me {
			mine += w
		} else {
			theirs += w
		}
	}
	for x := 0; x < p.Size(); x++ {
		for y := 0; y < p.Size(); y++ {
			sq := p.At(x, y)
			if len(sq) == 0 {
				continue
			}
			addw(sq[0].Color(), weightControlled)
			for i, stone := range sq {
				if i > 0 && i < p.Size() {
					addw(sq[0].Color(), weightCaptured)
				}
				if stone.Kind() == tak.Flat {
					addw(stone.Color(), weightFlat)
				}
			}
		}
	}

	return int64(mine - theirs)
}

func NewMinimax(depth int) *MinimaxAI {
	return &MinimaxAI{depth: depth}
}
<|endoftext|>


<commit_before>// Package devicefilter containes eBPF device filter program
//
// The implementation is based on https://github.com/containers/crun/blob/0.10.2/src/libcrun/ebpf.c
//
// Although ebpf.c is originally licensed under LGPL-3.0-or-later, the author (Giuseppe Scrivano)
// agreed to relicense the file in Apache License 2.0: https://github.com/opencontainers/runc/issues/2144#issuecomment-543116397
package devicefilter

import (
	"fmt"
	"math"

	"github.com/cilium/ebpf/asm"
	"github.com/opencontainers/runc/libcontainer/configs"
	"github.com/pkg/errors"
	"golang.org/x/sys/unix"
)

const (
	// license string format is same as kernel MODULE_LICENSE macro
	license = "Apache"
)

// DeviceFilter returns eBPF device filter program and its license string
func DeviceFilter(devices []*configs.Device) (asm.Instructions, string, error) {
	p := &program{}
	p.init()
	for i := len(devices) - 1; i >= 0; i-- {
		if err := p.appendDevice(devices[i]); err != nil {
			return nil, "", err
		}
	}
	insts, err := p.finalize()
	return insts, license, err
}

type program struct {
	insts       asm.Instructions
	hasWildCard bool
	blockID     int
}

func (p *program) init() {
	// struct bpf_cgroup_dev_ctx: https://elixir.bootlin.com/linux/v5.3.6/source/include/uapi/linux/bpf.h#L3423
	/*
		u32 access_type
		u32 major
		u32 minor
	*/
	// R2 <- type (lower 16 bit of u32 access_type at R1[0])
	p.insts = append(p.insts,
		asm.LoadMem(asm.R2, asm.R1, 0, asm.Half))

	// R3 <- access (upper 16 bit of u32 access_type at R1[0])
	p.insts = append(p.insts,
		asm.LoadMem(asm.R3, asm.R1, 0, asm.Word),
		// RSh: bitwise shift right
		asm.RSh.Imm32(asm.R3, 16))

	// R4 <- major (u32 major at R1[4])
	p.insts = append(p.insts,
		asm.LoadMem(asm.R4, asm.R1, 4, asm.Word))

	// R5 <- minor (u32 minor at R1[8])
	p.insts = append(p.insts,
		asm.LoadMem(asm.R5, asm.R1, 8, asm.Word))
}

// appendDevice needs to be called from the last element of OCI linux.resources.devices to the head element.
func (p *program) appendDevice(dev *configs.Device) error {
	if p.blockID < 0 {
		return errors.New("the program is finalized")
	}
	if p.hasWildCard {
		// All entries after wildcard entry are ignored
		return nil
	}

	bpfType := int32(-1)
	hasType := true
	switch dev.Type {
	case 'c':
		bpfType = int32(unix.BPF_DEVCG_DEV_CHAR)
	case 'b':
		bpfType = int32(unix.BPF_DEVCG_DEV_BLOCK)
	case 'a':
		hasType = false
	default:
		// if not specified in OCI json, typ is set to DeviceTypeAll
		return errors.Errorf("invalid DeviceType %q", string(dev.Type))
	}
	if dev.Major > math.MaxUint32 {
		return errors.Errorf("invalid major %d", dev.Major)
	}
	if dev.Minor > math.MaxUint32 {
		return errors.Errorf("invalid minor %d", dev.Major)
	}
	hasMajor := dev.Major >= 0 // if not specified in OCI json, major is set to -1
	hasMinor := dev.Minor >= 0
	bpfAccess := int32(0)
	for _, r := range dev.Permissions {
		switch r {
		case 'r':
			bpfAccess |= unix.BPF_DEVCG_ACC_READ
		case 'w':
			bpfAccess |= unix.BPF_DEVCG_ACC_WRITE
		case 'm':
			bpfAccess |= unix.BPF_DEVCG_ACC_MKNOD
		default:
			return errors.Errorf("unknown device access %v", r)
		}
	}
	// If the access is rwm, skip the check.
	hasAccess := bpfAccess != (unix.BPF_DEVCG_ACC_READ | unix.BPF_DEVCG_ACC_WRITE | unix.BPF_DEVCG_ACC_MKNOD)

	blockSym := fmt.Sprintf("block-%d", p.blockID)
	nextBlockSym := fmt.Sprintf("block-%d", p.blockID+1)
	prevBlockLastIdx := len(p.insts) - 1
	if hasType {
		p.insts = append(p.insts,
			// if (R2 != bpfType) goto next
			asm.JNE.Imm(asm.R2, bpfType, nextBlockSym),
		)
	}
	if hasAccess {
		p.insts = append(p.insts,
			// if (R3 & bpfAccess == 0 /* use R1 as a temp var */) goto next
			asm.Mov.Reg32(asm.R1, asm.R3),
			asm.And.Imm32(asm.R1, bpfAccess),
			asm.JEq.Imm(asm.R1, 0, nextBlockSym),
		)
	}
	if hasMajor {
		p.insts = append(p.insts,
			// if (R4 != major) goto next
			asm.JNE.Imm(asm.R4, int32(dev.Major), nextBlockSym),
		)
	}
	if hasMinor {
		p.insts = append(p.insts,
			// if (R5 != minor) goto next
			asm.JNE.Imm(asm.R5, int32(dev.Minor), nextBlockSym),
		)
	}
	if !hasType && !hasAccess && !hasMajor && !hasMinor {
		p.hasWildCard = true
	}
	p.insts = append(p.insts, acceptBlock(dev.Allow)...)
	// set blockSym to the first instruction we added in this iteration
	p.insts[prevBlockLastIdx+1] = p.insts[prevBlockLastIdx+1].Sym(blockSym)
	p.blockID++
	return nil
}

func (p *program) finalize() (asm.Instructions, error) {
	if p.hasWildCard {
		// acceptBlock with asm.Return() is already inserted
		return p.insts, nil
	}
	blockSym := fmt.Sprintf("block-%d", p.blockID)
	p.insts = append(p.insts,
		// R0 <- 0
		asm.Mov.Imm32(asm.R0, 0).Sym(blockSym),
		asm.Return(),
	)
	p.blockID = -1
	return p.insts, nil
}

func acceptBlock(accept bool) asm.Instructions {
	v := int32(0)
	if accept {
		v = 1
	}
	return []asm.Instruction{
		// R0 <- v
		asm.Mov.Imm32(asm.R0, v),
		asm.Return(),
	}
}
<commit_msg>ebpf: fix big endian issue for s390x<commit_after>// Package devicefilter containes eBPF device filter program
//
// The implementation is based on https://github.com/containers/crun/blob/0.10.2/src/libcrun/ebpf.c
//
// Although ebpf.c is originally licensed under LGPL-3.0-or-later, the author (Giuseppe Scrivano)
// agreed to relicense the file in Apache License 2.0: https://github.com/opencontainers/runc/issues/2144#issuecomment-543116397
package devicefilter

import (
	"fmt"
	"math"

	"github.com/cilium/ebpf/asm"
	"github.com/opencontainers/runc/libcontainer/configs"
	"github.com/pkg/errors"
	"golang.org/x/sys/unix"
)

const (
	// license string format is same as kernel MODULE_LICENSE macro
	license = "Apache"
)

// DeviceFilter returns eBPF device filter program and its license string
func DeviceFilter(devices []*configs.Device) (asm.Instructions, string, error) {
	p := &program{}
	p.init()
	for i := len(devices) - 1; i >= 0; i-- {
		if err := p.appendDevice(devices[i]); err != nil {
			return nil, "", err
		}
	}
	insts, err := p.finalize()
	return insts, license, err
}

type program struct {
	insts       asm.Instructions
	hasWildCard bool
	blockID     int
}

func (p *program) init() {
	// struct bpf_cgroup_dev_ctx: https://elixir.bootlin.com/linux/v5.3.6/source/include/uapi/linux/bpf.h#L3423
	/*
		u32 access_type
		u32 major
		u32 minor
	*/
	// R2 <- type (lower 16 bit of u32 access_type at R1[0])
	p.insts = append(p.insts,
		asm.LoadMem(asm.R2, asm.R1, 0, asm.Word),
		asm.And.Imm32(asm.R2, 0xFFFF))

	// R3 <- access (upper 16 bit of u32 access_type at R1[0])
	p.insts = append(p.insts,
		asm.LoadMem(asm.R3, asm.R1, 0, asm.Word),
		// RSh: bitwise shift right
		asm.RSh.Imm32(asm.R3, 16))

	// R4 <- major (u32 major at R1[4])
	p.insts = append(p.insts,
		asm.LoadMem(asm.R4, asm.R1, 4, asm.Word))

	// R5 <- minor (u32 minor at R1[8])
	p.insts = append(p.insts,
		asm.LoadMem(asm.R5, asm.R1, 8, asm.Word))
}

// appendDevice needs to be called from the last element of OCI linux.resources.devices to the head element.
func (p *program) appendDevice(dev *configs.Device) error {
	if p.blockID < 0 {
		return errors.New("the program is finalized")
	}
	if p.hasWildCard {
		// All entries after wildcard entry are ignored
		return nil
	}

	bpfType := int32(-1)
	hasType := true
	switch dev.Type {
	case 'c':
		bpfType = int32(unix.BPF_DEVCG_DEV_CHAR)
	case 'b':
		bpfType = int32(unix.BPF_DEVCG_DEV_BLOCK)
	case 'a':
		hasType = false
	default:
		// if not specified in OCI json, typ is set to DeviceTypeAll
		return errors.Errorf("invalid DeviceType %q", string(dev.Type))
	}
	if dev.Major > math.MaxUint32 {
		return errors.Errorf("invalid major %d", dev.Major)
	}
	if dev.Minor > math.MaxUint32 {
		return errors.Errorf("invalid minor %d", dev.Major)
	}
	hasMajor := dev.Major >= 0 // if not specified in OCI json, major is set to -1
	hasMinor := dev.Minor >= 0
	bpfAccess := int32(0)
	for _, r := range dev.Permissions {
		switch r {
		case 'r':
			bpfAccess |= unix.BPF_DEVCG_ACC_READ
		case 'w':
			bpfAccess |= unix.BPF_DEVCG_ACC_WRITE
		case 'm':
			bpfAccess |= unix.BPF_DEVCG_ACC_MKNOD
		default:
			return errors.Errorf("unknown device access %v", r)
		}
	}
	// If the access is rwm, skip the check.
	hasAccess := bpfAccess != (unix.BPF_DEVCG_ACC_READ | unix.BPF_DEVCG_ACC_WRITE | unix.BPF_DEVCG_ACC_MKNOD)

	blockSym := fmt.Sprintf("block-%d", p.blockID)
	nextBlockSym := fmt.Sprintf("block-%d", p.blockID+1)
	prevBlockLastIdx := len(p.insts) - 1
	if hasType {
		p.insts = append(p.insts,
			// if (R2 != bpfType) goto next
			asm.JNE.Imm(asm.R2, bpfType, nextBlockSym),
		)
	}
	if hasAccess {
		p.insts = append(p.insts,
			// if (R3 & bpfAccess == 0 /* use R1 as a temp var */) goto next
			asm.Mov.Reg32(asm.R1, asm.R3),
			asm.And.Imm32(asm.R1, bpfAccess),
			asm.JEq.Imm(asm.R1, 0, nextBlockSym),
		)
	}
	if hasMajor {
		p.insts = append(p.insts,
			// if (R4 != major) goto next
			asm.JNE.Imm(asm.R4, int32(dev.Major), nextBlockSym),
		)
	}
	if hasMinor {
		p.insts = append(p.insts,
			// if (R5 != minor) goto next
			asm.JNE.Imm(asm.R5, int32(dev.Minor), nextBlockSym),
		)
	}
	if !hasType && !hasAccess && !hasMajor && !hasMinor {
		p.hasWildCard = true
	}
	p.insts = append(p.insts, acceptBlock(dev.Allow)...)
	// set blockSym to the first instruction we added in this iteration
	p.insts[prevBlockLastIdx+1] = p.insts[prevBlockLastIdx+1].Sym(blockSym)
	p.blockID++
	return nil
}

func (p *program) finalize() (asm.Instructions, error) {
	if p.hasWildCard {
		// acceptBlock with asm.Return() is already inserted
		return p.insts, nil
	}
	blockSym := fmt.Sprintf("block-%d", p.blockID)
	p.insts = append(p.insts,
		// R0 <- 0
		asm.Mov.Imm32(asm.R0, 0).Sym(blockSym),
		asm.Return(),
	)
	p.blockID = -1
	return p.insts, nil
}

func acceptBlock(accept bool) asm.Instructions {
	v := int32(0)
	if accept {
		v = 1
	}
	return []asm.Instruction{
		// R0 <- v
		asm.Mov.Imm32(asm.R0, v),
		asm.Return(),
	}
}
<|endoftext|>


<commit_before>// Define the Web GUI helpers

package webgui

import (
	"archive/zip"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	"github.com/pkg/errors"
	"github.com/rclone/rclone/fs"
)

// GetLatestReleaseURL returns the latest release details of the rclone-webui-react
func GetLatestReleaseURL(fetchURL string) (string, string, int, error) {
	resp, err := http.Get(fetchURL)
	if err != nil {
		return "", "", 0, errors.Wrap(err, "failed getting latest release of rclone-webui")
	}
	defer fs.CheckClose(resp.Body, &err)
	if resp.StatusCode != http.StatusOK {
		return "", "", 0, errors.Errorf("bad HTTP status %d (%s) when fetching %s", resp.StatusCode, resp.Status, fetchURL)
	}
	results := gitHubRequest{}
	if err := json.NewDecoder(resp.Body).Decode(&results); err != nil {
		return "", "", 0, errors.Wrap(err, "could not decode results from http request")
	}
	if len(results.Assets) < 1 {
		return "", "", 0, errors.New("could not find an asset in the release. " +
			"check if asset was successfully added in github release assets")
	}
	res := results.Assets[0].BrowserDownloadURL
	tag := results.TagName
	size := results.Assets[0].Size

	return res, tag, size, nil
}

// CheckAndDownloadWebGUIRelease is a helper function to download and setup latest release of rclone-webui-react
func CheckAndDownloadWebGUIRelease(checkUpdate bool, forceUpdate bool, fetchURL string, cacheDir string) (err error) {
	cachePath := filepath.Join(cacheDir, "webgui")
	tagPath := filepath.Join(cachePath, "tag")
	extractPath := filepath.Join(cachePath, "current")

	extractPathExist, extractPathStat, err := exists(extractPath)
	if err != nil {
		return err
	}

	if extractPathExist && !extractPathStat.IsDir() {
		return errors.New("Web GUI path exists, but is a file instead of folder. Please check the path " + extractPath)
	}

	// if the old file exists does not exist or forced update is enforced.
	// TODO: Add hashing to check integrity of the previous update.
	if !extractPathExist || checkUpdate || forceUpdate {
		// Get the latest release details
		WebUIURL, tag, size, err := GetLatestReleaseURL(fetchURL)
		if err != nil {
			return err
		}

		dat, err := ioutil.ReadFile(tagPath)
		if err == nil && string(dat) == tag {
			fs.Logf(nil, "No update to Web GUI available.")
			if !forceUpdate {
				return nil
			}
			fs.Logf(nil, "Force update the Web GUI binary.")
		}

		zipName := tag + ".zip"
		zipPath := filepath.Join(cachePath, zipName)

		cachePathExist, cachePathStat, _ := exists(cachePath)
		if !cachePathExist {
			if err := os.MkdirAll(cachePath, 0755); err != nil {
				return errors.New("Error creating cache directory: " + cachePath)
			}
		}

		if cachePathExist && !cachePathStat.IsDir() {
			return errors.New("Web GUI path is a file instead of folder. Please check it " + extractPath)
		}

		fs.Logf(nil, "A new release for gui is present at "+WebUIURL)
		fs.Logf(nil, "Downloading webgui binary. Please wait. [Size: %s, Path :  %s]\n", strconv.Itoa(size), zipPath)

		// download the zip from latest url
		err = DownloadFile(zipPath, WebUIURL)
		if err != nil {
			return err
		}

		err = os.RemoveAll(extractPath)
		if err != nil {
			fs.Logf(nil, "No previous downloads to remove")
		}
		fs.Logf(nil, "Unzipping webgui binary")

		err = Unzip(zipPath, extractPath)
		if err != nil {
			return err
		}

		err = os.RemoveAll(zipPath)
		if err != nil {
			fs.Logf(nil, "Downloaded ZIP cannot be deleted")
		}

		err = ioutil.WriteFile(tagPath, []byte(tag), 0644)
		if err != nil {
			fs.Infof(nil, "Cannot write tag file. You may be required to redownload the binary next time.")
		}
	} else {
		fs.Logf(nil, "Web GUI exists. Update skipped.")
	}

	return nil
}

// DownloadFile is a helper function to download a file from url to the filepath
func DownloadFile(filepath string, url string) (err error) {
	// Get the data
	resp, err := http.Get(url)
	if err != nil {
		return err
	}
	defer fs.CheckClose(resp.Body, &err)
	if resp.StatusCode != http.StatusOK {
		return errors.Errorf("bad HTTP status %d (%s) when fetching %s", resp.StatusCode, resp.Status, url)
	}

	// Create the file
	out, err := os.Create(filepath)
	if err != nil {
		return err
	}
	defer fs.CheckClose(out, &err)

	// Write the body to file
	_, err = io.Copy(out, resp.Body)
	return err
}

// Unzip is a helper function to Unzip a file specified in src to path dest
func Unzip(src, dest string) (err error) {
	dest = filepath.Clean(dest) + string(os.PathSeparator)

	r, err := zip.OpenReader(src)
	if err != nil {
		return err
	}
	defer fs.CheckClose(r, &err)

	if err := os.MkdirAll(dest, 0755); err != nil {
		return err
	}

	// Closure to address file descriptors issue with all the deferred .Close() methods
	extractAndWriteFile := func(f *zip.File) error {
		path := filepath.Join(dest, f.Name)
		// Check for Zip Slip: https://github.com/rclone/rclone/issues/3529
		if !strings.HasPrefix(path, dest) {
			return fmt.Errorf("%s: illegal file path", path)
		}

		rc, err := f.Open()
		if err != nil {
			return err
		}
		defer fs.CheckClose(rc, &err)

		if f.FileInfo().IsDir() {
			if err := os.MkdirAll(path, 0755); err != nil {
				return err
			}
		} else {
			if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
				return err
			}
			f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
			if err != nil {
				return err
			}
			defer fs.CheckClose(f, &err)

			_, err = io.Copy(f, rc)
			if err != nil {
				return err
			}
		}
		return nil
	}

	for _, f := range r.File {
		err := extractAndWriteFile(f)
		if err != nil {
			return err
		}
	}

	return nil
}

func exists(path string) (existence bool, stat os.FileInfo, err error) {
	stat, err = os.Stat(path)
	if err == nil {
		return true, stat, nil
	}
	if os.IsNotExist(err) {
		return false, nil, nil
	}
	return false, stat, err
}

// CreatePathIfNotExist creates the path to a folder if it does not exist
func CreatePathIfNotExist(path string) (err error) {
	exists, stat, _ := exists(path)
	if !exists {
		if err := os.MkdirAll(path, 0755); err != nil {
			return errors.New("Error creating : " + path)
		}
	}

	if exists && !stat.IsDir() {
		return errors.New("Path is a file instead of folder. Please check it " + path)
	}

	return nil
}

// gitHubRequest Maps the GitHub API request to structure
type gitHubRequest struct {
	URL string `json:"url"`

	Prerelease  bool      `json:"prerelease"`
	CreatedAt   time.Time `json:"created_at"`
	PublishedAt time.Time `json:"published_at"`
	TagName     string    `json:"tag_name"`
	Assets      []struct {
		URL                string    `json:"url"`
		ID                 int       `json:"id"`
		NodeID             string    `json:"node_id"`
		Name               string    `json:"name"`
		Label              string    `json:"label"`
		ContentType        string    `json:"content_type"`
		State              string    `json:"state"`
		Size               int       `json:"size"`
		DownloadCount      int       `json:"download_count"`
		CreatedAt          time.Time `json:"created_at"`
		UpdatedAt          time.Time `json:"updated_at"`
		BrowserDownloadURL string    `json:"browser_download_url"`
	} `json:"assets"`
	TarballURL string `json:"tarball_url"`
	ZipballURL string `json:"zipball_url"`
	Body       string `json:"body"`
}
<commit_msg>webui: Prompt user for updating webui if an update is available<commit_after>// Define the Web GUI helpers

package webgui

import (
	"archive/zip"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	"github.com/pkg/errors"
	"github.com/rclone/rclone/fs"
)

// GetLatestReleaseURL returns the latest release details of the rclone-webui-react
func GetLatestReleaseURL(fetchURL string) (string, string, int, error) {
	resp, err := http.Get(fetchURL)
	if err != nil {
		return "", "", 0, errors.Wrap(err, "failed getting latest release of rclone-webui")
	}
	defer fs.CheckClose(resp.Body, &err)
	if resp.StatusCode != http.StatusOK {
		return "", "", 0, errors.Errorf("bad HTTP status %d (%s) when fetching %s", resp.StatusCode, resp.Status, fetchURL)
	}
	results := gitHubRequest{}
	if err := json.NewDecoder(resp.Body).Decode(&results); err != nil {
		return "", "", 0, errors.Wrap(err, "could not decode results from http request")
	}
	if len(results.Assets) < 1 {
		return "", "", 0, errors.New("could not find an asset in the release. " +
			"check if asset was successfully added in github release assets")
	}
	res := results.Assets[0].BrowserDownloadURL
	tag := results.TagName
	size := results.Assets[0].Size

	return res, tag, size, nil
}

// CheckAndDownloadWebGUIRelease is a helper function to download and setup latest release of rclone-webui-react
func CheckAndDownloadWebGUIRelease(checkUpdate bool, forceUpdate bool, fetchURL string, cacheDir string) (err error) {
	cachePath := filepath.Join(cacheDir, "webgui")
	tagPath := filepath.Join(cachePath, "tag")
	extractPath := filepath.Join(cachePath, "current")

	extractPathExist, extractPathStat, err := exists(extractPath)
	if err != nil {
		return err
	}

	if extractPathExist && !extractPathStat.IsDir() {
		return errors.New("Web GUI path exists, but is a file instead of folder. Please check the path " + extractPath)
	}

	// Get the latest release details
	WebUIURL, tag, size, err := GetLatestReleaseURL(fetchURL)
	if err != nil {
		return errors.Wrap(err, "Error checking for web gui release update, skipping update")
	}
	dat, err := ioutil.ReadFile(tagPath)
	tagsMatch := false
	if err != nil {
		fs.Errorf(nil, "Error reading tag file at %s ", tagPath)
		checkUpdate = true
	} else if string(dat) == tag {
		tagsMatch = true
	}
	fs.Debugf(nil, "Current tag: %s, Release tag: %s", string(dat), tag)

	if !tagsMatch {
		fs.Infof(nil, "A release (%s) for gui is present at %s. Use --rc-web-gui-update to update. Your current version is (%s)", tag, WebUIURL, string(dat))
	}

	// if the old file exists does not exist or forced update is enforced.
	// TODO: Add hashing to check integrity of the previous update.
	if !extractPathExist || checkUpdate || forceUpdate {

		if tagsMatch {
			fs.Logf(nil, "No update to Web GUI available.")
			if !forceUpdate {
				return nil
			}
			fs.Logf(nil, "Force update the Web GUI binary.")
		}

		zipName := tag + ".zip"
		zipPath := filepath.Join(cachePath, zipName)

		cachePathExist, cachePathStat, _ := exists(cachePath)
		if !cachePathExist {
			if err := os.MkdirAll(cachePath, 0755); err != nil {
				return errors.New("Error creating cache directory: " + cachePath)
			}
		}

		if cachePathExist && !cachePathStat.IsDir() {
			return errors.New("Web GUI path is a file instead of folder. Please check it " + extractPath)
		}

		fs.Logf(nil, "A new release for gui (%s) is present at %s", tag, WebUIURL)
		fs.Logf(nil, "Downloading webgui binary. Please wait. [Size: %s, Path :  %s]\n", strconv.Itoa(size), zipPath)

		// download the zip from latest url
		err = DownloadFile(zipPath, WebUIURL)
		if err != nil {
			return err
		}

		err = os.RemoveAll(extractPath)
		if err != nil {
			fs.Logf(nil, "No previous downloads to remove")
		}
		fs.Logf(nil, "Unzipping webgui binary")

		err = Unzip(zipPath, extractPath)
		if err != nil {
			return err
		}

		err = os.RemoveAll(zipPath)
		if err != nil {
			fs.Logf(nil, "Downloaded ZIP cannot be deleted")
		}

		err = ioutil.WriteFile(tagPath, []byte(tag), 0644)
		if err != nil {
			fs.Infof(nil, "Cannot write tag file. You may be required to redownload the binary next time.")
		}
	} else {
		fs.Logf(nil, "Web GUI exists. Update skipped.")
	}

	return nil
}

// DownloadFile is a helper function to download a file from url to the filepath
func DownloadFile(filepath string, url string) (err error) {
	// Get the data
	resp, err := http.Get(url)
	if err != nil {
		return err
	}
	defer fs.CheckClose(resp.Body, &err)
	if resp.StatusCode != http.StatusOK {
		return errors.Errorf("bad HTTP status %d (%s) when fetching %s", resp.StatusCode, resp.Status, url)
	}

	// Create the file
	out, err := os.Create(filepath)
	if err != nil {
		return err
	}
	defer fs.CheckClose(out, &err)

	// Write the body to file
	_, err = io.Copy(out, resp.Body)
	return err
}

// Unzip is a helper function to Unzip a file specified in src to path dest
func Unzip(src, dest string) (err error) {
	dest = filepath.Clean(dest) + string(os.PathSeparator)

	r, err := zip.OpenReader(src)
	if err != nil {
		return err
	}
	defer fs.CheckClose(r, &err)

	if err := os.MkdirAll(dest, 0755); err != nil {
		return err
	}

	// Closure to address file descriptors issue with all the deferred .Close() methods
	extractAndWriteFile := func(f *zip.File) error {
		path := filepath.Join(dest, f.Name)
		// Check for Zip Slip: https://github.com/rclone/rclone/issues/3529
		if !strings.HasPrefix(path, dest) {
			return fmt.Errorf("%s: illegal file path", path)
		}

		rc, err := f.Open()
		if err != nil {
			return err
		}
		defer fs.CheckClose(rc, &err)

		if f.FileInfo().IsDir() {
			if err := os.MkdirAll(path, 0755); err != nil {
				return err
			}
		} else {
			if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
				return err
			}
			f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
			if err != nil {
				return err
			}
			defer fs.CheckClose(f, &err)

			_, err = io.Copy(f, rc)
			if err != nil {
				return err
			}
		}
		return nil
	}

	for _, f := range r.File {
		err := extractAndWriteFile(f)
		if err != nil {
			return err
		}
	}

	return nil
}

func exists(path string) (existence bool, stat os.FileInfo, err error) {
	stat, err = os.Stat(path)
	if err == nil {
		return true, stat, nil
	}
	if os.IsNotExist(err) {
		return false, nil, nil
	}
	return false, stat, err
}

// CreatePathIfNotExist creates the path to a folder if it does not exist
func CreatePathIfNotExist(path string) (err error) {
	exists, stat, _ := exists(path)
	if !exists {
		if err := os.MkdirAll(path, 0755); err != nil {
			return errors.New("Error creating : " + path)
		}
	}

	if exists && !stat.IsDir() {
		return errors.New("Path is a file instead of folder. Please check it " + path)
	}

	return nil
}

// gitHubRequest Maps the GitHub API request to structure
type gitHubRequest struct {
	URL string `json:"url"`

	Prerelease  bool      `json:"prerelease"`
	CreatedAt   time.Time `json:"created_at"`
	PublishedAt time.Time `json:"published_at"`
	TagName     string    `json:"tag_name"`
	Assets      []struct {
		URL                string    `json:"url"`
		ID                 int       `json:"id"`
		NodeID             string    `json:"node_id"`
		Name               string    `json:"name"`
		Label              string    `json:"label"`
		ContentType        string    `json:"content_type"`
		State              string    `json:"state"`
		Size               int       `json:"size"`
		DownloadCount      int       `json:"download_count"`
		CreatedAt          time.Time `json:"created_at"`
		UpdatedAt          time.Time `json:"updated_at"`
		BrowserDownloadURL string    `json:"browser_download_url"`
	} `json:"assets"`
	TarballURL string `json:"tarball_url"`
	ZipballURL string `json:"zipball_url"`
	Body       string `json:"body"`
}
<|endoftext|>


<commit_before>package model

import (
	"time"

	"github.com/mjibson/goon"
	"github.com/pkg/errors"
	"golang.org/x/net/context"
	"google.golang.org/appengine/datastore"
)

const (
	ReminderOnce Type = iota
	ReminderWeekly
)

type Type int

type Reminder struct {
	Id      int64 `datastore:"-" goon:"id"`
	Text    string
	Type    Type
	Enabled bool

	// Once
	RemindAt time.Time

	// Weekly
	Weekday time.Weekday
	Hour    int
	Minute  int
}

func NewReminderOnce(text string, remindAt time.Time) *Reminder {
	return &Reminder{
		Text:     text,
		Type:     ReminderOnce,
		Enabled:  true,
		RemindAt: remindAt,
	}
}

func NewReminderWeekly(text string, weekday time.Weekday, hour int, minute int) *Reminder {
	return &Reminder{
		Text:    text,
		Type:    ReminderWeekly,
		Enabled: true,
		Weekday: weekday,
		Hour:    hour,
		Minute:  minute,
	}
}

func (r *Reminder) Put(ctx context.Context) error {
	g := goon.FromContext(ctx)
	_, err := g.Put(r)
	return err
}

func (r *Reminder) Disable(ctx context.Context) error {
	g := goon.FromContext(ctx)
	r.Enabled = false
	_, err := g.Put(r)
	return err
}

func (r *Reminder) IsOnce() bool {
	return r.Type == ReminderOnce
}

func (r *Reminder) Valid(now time.Time) (bool, error) {
	switch r.Type {
	case ReminderOnce:
		r.RemindAt = r.RemindAt.In(now.Location())
		if r.RemindAt.Year() == now.Year() || r.RemindAt.Month() == now.Month() || r.RemindAt.Day() == now.Day() ||
			r.RemindAt.Hour() == now.Hour() || r.RemindAt.Minute() == now.Minute() {
			return true, nil
		}
	case ReminderWeekly:
		if r.Weekday == now.Weekday() || r.Hour == now.Hour() || r.Minute == now.Minute() {
			return true, nil
		}
	default:
		return false, errors.Errorf("Invalid reminder type. reminder:%#v", r)
	}
	return false, nil
}

type ReminderQuery struct {
	context context.Context
}

func NewReminderQuery(ctx context.Context) *ReminderQuery {
	return &ReminderQuery{context: ctx}
}

func (r *ReminderQuery) GetAll() ([]*Reminder, error) {
	q := datastore.NewQuery("Reminder").Filter("Enabled =", true)

	var dst []*Reminder
	_, err := q.GetAll(r.context, &dst)
	if err != nil {
		return nil, errors.Wrap(err, "Failed to get all Reminders.")
	}
	return dst, nil
}
<commit_msg>Fix Reminder Valid method<commit_after>package model

import (
	"time"

	"github.com/mjibson/goon"
	"github.com/pkg/errors"
	"golang.org/x/net/context"
	"google.golang.org/appengine/datastore"
)

const (
	ReminderOnce Type = iota
	ReminderWeekly
)

type Type int

type Reminder struct {
	Id      int64 `datastore:"-" goon:"id"`
	Text    string
	Type    Type
	Enabled bool

	// Once
	RemindAt time.Time

	// Weekly
	Weekday time.Weekday
	Hour    int
	Minute  int
}

func NewReminderOnce(text string, remindAt time.Time) *Reminder {
	return &Reminder{
		Text:     text,
		Type:     ReminderOnce,
		Enabled:  true,
		RemindAt: remindAt,
	}
}

func NewReminderWeekly(text string, weekday time.Weekday, hour int, minute int) *Reminder {
	return &Reminder{
		Text:    text,
		Type:    ReminderWeekly,
		Enabled: true,
		Weekday: weekday,
		Hour:    hour,
		Minute:  minute,
	}
}

func (r *Reminder) Put(ctx context.Context) error {
	g := goon.FromContext(ctx)
	_, err := g.Put(r)
	return err
}

func (r *Reminder) Disable(ctx context.Context) error {
	g := goon.FromContext(ctx)
	r.Enabled = false
	_, err := g.Put(r)
	return err
}

func (r *Reminder) IsOnce() bool {
	return r.Type == ReminderOnce
}

func (r *Reminder) Valid(now time.Time) (bool, error) {
	switch r.Type {
	case ReminderOnce:
		r.RemindAt = r.RemindAt.In(now.Location())
		if r.RemindAt.Year() == now.Year() && r.RemindAt.Month() == now.Month() && r.RemindAt.Day() == now.Day() &&
			r.RemindAt.Hour() == now.Hour() && r.RemindAt.Minute() == now.Minute() {
			return true, nil
		}
	case ReminderWeekly:
		if r.Weekday == now.Weekday() && r.Hour == now.Hour() && r.Minute == now.Minute() {
			return true, nil
		}
	default:
		return false, errors.Errorf("Invalid reminder type. reminder:%#v", r)
	}
	return false, nil
}

type ReminderQuery struct {
	context context.Context
}

func NewReminderQuery(ctx context.Context) *ReminderQuery {
	return &ReminderQuery{context: ctx}
}

func (r *ReminderQuery) GetAll() ([]*Reminder, error) {
	q := datastore.NewQuery("Reminder").Filter("Enabled =", true)

	var dst []*Reminder
	_, err := q.GetAll(r.context, &dst)
	if err != nil {
		return nil, errors.Wrap(err, "Failed to get all Reminders.")
	}
	return dst, nil
}
<|endoftext|>


<commit_before>package autoupdate

import (
	"net/http"
	"sync"
	"sync/atomic"
	"time"

	"github.com/getlantern/autoupdate"
	"github.com/getlantern/flashlight/config"
	"github.com/getlantern/flashlight/util"
	"github.com/getlantern/golog"
)

const (
	serviceURL = "https://update.getlantern.org/update"
)

var (
	PublicKey []byte
	Version   string
)

var (
	log = golog.LoggerFor("flashlight.autoupdate")

	cfgMutex    sync.Mutex
	updateMutex sync.Mutex

	httpClient *http.Client
	watching   int32 = 0

	applyNextAttemptTime = time.Hour * 2
	lastAddr             string
)

func Configure(cfg *config.Config) {
	cfgMutex.Lock()
	if cfg.Addr == lastAddr {
		cfgMutex.Unlock()
		log.Debug("Autoupdate configuration unchanged")
		return
	}

	go func() {
		lastAddr = cfg.Addr
		enableAutoupdate(cfg)
		cfgMutex.Unlock()
	}()

}

func enableAutoupdate(cfg *config.Config) {
	var err error

	if cfg.Addr == "" {
		log.Error("No known proxy, disabling auto updates.")
		return
	}

	httpClient, err = util.HTTPClient(cfg.CloudConfigCA, cfg.Addr)
	if err != nil {
		log.Errorf("Could not create proxied HTTP client, disabling auto-updates: %v", err)
		return
	}

	go watchForUpdate()
}

func watchForUpdate() {
	if atomic.LoadInt32(&watching) < 1 {

		atomic.AddInt32(&watching, 1)

		log.Errorf("Software version: %s", Version)

		for {
			applyNext()
			// At this point we either updated the binary or failed to recover from a
			// update error, let's wait a bit before looking for a another update.
			time.Sleep(applyNextAttemptTime)
		}
	}
}

func applyNext() {
	updateMutex.Lock()
	defer updateMutex.Unlock()

	if httpClient != nil {
		err := autoupdate.ApplyNext(&autoupdate.Config{
			CurrentVersion: Version,
			URL:            serviceURL,
			PublicKey:      PublicKey,
			HTTPClient:     httpClient,
		})
		if err != nil {
			log.Debugf("Error getting update: %v", err)
			return
		}
		log.Debugf("Got update.")
	}
}
<commit_msg>Fixing wrong log level.<commit_after>package autoupdate

import (
	"net/http"
	"sync"
	"sync/atomic"
	"time"

	"github.com/getlantern/autoupdate"
	"github.com/getlantern/flashlight/config"
	"github.com/getlantern/flashlight/util"
	"github.com/getlantern/golog"
)

const (
	serviceURL = "https://update.getlantern.org/update"
)

var (
	PublicKey []byte
	Version   string
)

var (
	log = golog.LoggerFor("flashlight.autoupdate")

	cfgMutex    sync.Mutex
	updateMutex sync.Mutex

	httpClient *http.Client
	watching   int32 = 0

	applyNextAttemptTime = time.Hour * 2
	lastAddr             string
)

func Configure(cfg *config.Config) {
	cfgMutex.Lock()
	if cfg.Addr == lastAddr {
		cfgMutex.Unlock()
		log.Debug("Autoupdate configuration unchanged")
		return
	}

	go func() {
		lastAddr = cfg.Addr
		enableAutoupdate(cfg)
		cfgMutex.Unlock()
	}()

}

func enableAutoupdate(cfg *config.Config) {
	var err error

	if cfg.Addr == "" {
		log.Error("No known proxy, disabling auto updates.")
		return
	}

	httpClient, err = util.HTTPClient(cfg.CloudConfigCA, cfg.Addr)
	if err != nil {
		log.Errorf("Could not create proxied HTTP client, disabling auto-updates: %v", err)
		return
	}

	go watchForUpdate()
}

func watchForUpdate() {
	if atomic.LoadInt32(&watching) < 1 {

		atomic.AddInt32(&watching, 1)

		log.Debugf("Software version: %s", Version)

		for {
			applyNext()
			// At this point we either updated the binary or failed to recover from a
			// update error, let's wait a bit before looking for a another update.
			time.Sleep(applyNextAttemptTime)
		}
	}
}

func applyNext() {
	updateMutex.Lock()
	defer updateMutex.Unlock()

	if httpClient != nil {
		err := autoupdate.ApplyNext(&autoupdate.Config{
			CurrentVersion: Version,
			URL:            serviceURL,
			PublicKey:      PublicKey,
			HTTPClient:     httpClient,
		})
		if err != nil {
			log.Debugf("Error getting update: %v", err)
			return
		}
		log.Debugf("Got update.")
	}
}
<|endoftext|>