<commit_before>//+build netgo

package engo

import (
	"bytes"
	"fmt"
	"io"
	"log"
	"math"
	"net/http"
	"strconv"
	"time"

	"engo.io/gl"
	"github.com/gopherjs/gopherjs/js"
	"honnef.co/go/js/dom"
	"honnef.co/go/js/xhr"
)

var (
	// Gl is the current OpenGL context
	Gl *gl.Context

	devicePixelRatio float64

	ResizeXOffset = float32(0)
	ResizeYOffset = float32(0)

	Backend string = "Web"
)

func init() {
	rafPolyfill()
}

//var canvas *js.Object
var document = dom.GetWindow().Document().(dom.HTMLDocument)

// CreateWindow creates a window with the specified parameters
func CreateWindow(title string, width, height int, fullscreen bool, msaa int) {
	canvas := document.CreateElement("canvas").(*dom.HTMLCanvasElement)

	devicePixelRatio = js.Global.Get("devicePixelRatio").Float()
	canvas.Width = int(float64(width)*devicePixelRatio + 0.5)   // Nearest non-negative int.
	canvas.Height = int(float64(height)*devicePixelRatio + 0.5) // Nearest non-negative int.
	canvas.Style().SetProperty("width", fmt.Sprintf("%vpx", width), "")
	canvas.Style().SetProperty("height", fmt.Sprintf("%vpx", height), "")
	log.Println("devicePixelRatio", devicePixelRatio)

	if document.Body() == nil {
		js.Global.Get("document").Set("body", js.Global.Get("document").Call("createElement", "body"))
		log.Println("Creating body, since it doesn't exist.")
	}

	document.Body().Style().SetProperty("margin", "0", "")
	document.Body().AppendChild(canvas)

	document.SetTitle(title)

	var err error

	Gl, err = gl.NewContext(canvas.Underlying(), nil) // TODO: we can add arguments here
	if err != nil {
		log.Println("Could not create context:", err)
		return
	}
	fmt.Println("Gl.Viewport(0, 0,", width, ",", height, ")")
	Gl.GetExtension("OES_texture_float")

	// DEBUG: Add framebuffer information div.
	if false {
		//canvas.Height -= 30
		text := document.CreateElement("div")
		textContent := fmt.Sprintf("%v %v (%v %v %v) @%v", dom.GetWindow().InnerWidth(), canvas.Width, float64(width)*devicePixelRatio, GameWidth(), CanvasWidth(), devicePixelRatio)
		text.SetTextContent(textContent)
		document.Body().AppendChild(text)
	}
	gameWidth = float32(width)
	gameHeight = float32(height)
	windowWidth = WindowWidth()
	windowHeight = WindowHeight()

	ResizeXOffset = gameWidth - CanvasWidth()
	ResizeYOffset = gameHeight - CanvasHeight()

	w := dom.GetWindow()
	w.AddEventListener("keypress", false, func(ev dom.Event) {
		// TODO: Not sure what to do here, come back
		//ke := ev.(*dom.KeyboardEvent)
		//responser.Type(rune(keyStates[Key(ke.KeyCode)]))
	})
	w.AddEventListener("keydown", false, func(ev dom.Event) {
		ke := ev.(*dom.KeyboardEvent)
		Input.keys.Set(Key(ke.KeyCode), true)
	})

	w.AddEventListener("keyup", false, func(ev dom.Event) {
		ke := ev.(*dom.KeyboardEvent)
		Input.keys.Set(Key(ke.KeyCode), false)
	})

	w.AddEventListener("mousemove", false, func(ev dom.Event) {
		mm := ev.(*dom.MouseEvent)
		Input.Mouse.X = float32(float64(mm.ClientX) * devicePixelRatio)
		Input.Mouse.Y = float32(float64(mm.ClientY) * devicePixelRatio)
		//Mouse.Action = MOVE
	})

	w.AddEventListener("mousedown", false, func(ev dom.Event) {
		mm := ev.(*dom.MouseEvent)
		Input.Mouse.X = float32(float64(mm.ClientX) * devicePixelRatio)
		Input.Mouse.Y = float32(float64(mm.ClientY) * devicePixelRatio)
		Input.Mouse.Action = Press
	})

	w.AddEventListener("mouseup", false, func(ev dom.Event) {
		mm := ev.(*dom.MouseEvent)
		Input.Mouse.X = float32(float64(mm.ClientX) * devicePixelRatio)
		Input.Mouse.Y = float32(float64(mm.ClientY) * devicePixelRatio)
		Input.Mouse.Action = Release
	})
}

func DestroyWindow() {}

// CursorPos returns the current cursor position
func CursorPos() (x, y float32) {
	return Input.Mouse.X, Input.Mouse.Y
}

// SetTitle changes the title of the page to the given string
func SetTitle(title string) {
	document.SetTitle(title)
}

// WindowSize returns the width and height of the current window
func WindowSize() (w, h int) {
	w = int(WindowWidth())
	h = int(WindowHeight())
	return
}

// WindowWidth returns the current window width
func WindowWidth() float32 {
	return float32(dom.GetWindow().InnerWidth())
}

// WindowHeight returns the current window height
func WindowHeight() float32 {
	return float32(dom.GetWindow().InnerHeight())
}

// CanvasWidth returns the current canvas width
func CanvasWidth() float32 {
	flt, err := strconv.ParseFloat(document.Body().GetElementsByTagName("canvas")[0].GetAttribute("width"), 32)
	if err != nil {
		log.Println("[ERROR] [CanvasWidth]:", err)
	}
	return float32(flt)
}

// CanvasHeight returns the current canvas height
func CanvasHeight() float32 {
	flt, err := strconv.ParseFloat(document.Body().GetElementsByTagName("canvas")[0].GetAttribute("height"), 32)
	if err != nil {
		log.Println("[ERROR] [CanvasHeight]:", err)
	}
	return float32(flt)
}

func CanvasScale() float32 {
	return 1
}

func toPx(n int) string {
	return strconv.FormatInt(int64(n), 10) + "px"
}

func rafPolyfill() {
	window := js.Global
	vendors := []string{"ms", "moz", "webkit", "o"}
	if window.Get("requestAnimationFrame") == nil {
		for i := 0; i < len(vendors) && window.Get("requestAnimationFrame") == nil; i++ {
			vendor := vendors[i]
			window.Set("requestAnimationFrame", window.Get(vendor+"RequestAnimationFrame"))
			window.Set("cancelAnimationFrame", window.Get(vendor+"CancelAnimationFrame"))
			if window.Get("cancelAnimationFrame") == nil {
				window.Set("cancelAnimationFrame", window.Get(vendor+"CancelRequestAnimationFrame"))
			}
		}
	}

	lastTime := 0.0
	if window.Get("requestAnimationFrame") == nil {
		window.Set("requestAnimationFrame", func(callback func(float32)) int {
			currTime := js.Global.Get("Date").New().Call("getTime").Float()
			timeToCall := math.Max(0, 16-(currTime-lastTime))
			id := window.Call("setTimeout", func() { callback(float32(currTime + timeToCall)) }, timeToCall)
			lastTime = currTime + timeToCall
			return id.Int()
		})
	}

	if window.Get("cancelAnimationFrame") == nil {
		window.Set("cancelAnimationFrame", func(id int) {
			js.Global.Get("clearTimeout").Invoke(id)
		})
	}
}

// RunIteration runs one iteration per frame
func RunIteration() {
	Time.Tick()
	Input.update()
	currentWorld.Update(Time.Delta())
	Input.Mouse.Action = Neutral
	// TODO: this may not work, and sky-rocket the FPS
	//  requestAnimationFrame(func(dt float32) {
	// 	currentWorld.Update(Time.Delta())
	// 	keysUpdate()
	// 	if !headless {
	// 		// TODO: does this require !headless?
	// 		Mouse.ScrollX, Mouse.ScrollY = 0, 0
	// 	}
	// 	Time.Tick()
	// })
}

func requestAnimationFrame(callback func(float32)) int {
	//return dom.GetWindow().RequestAnimationFrame(callback)
	return js.Global.Call("requestAnimationFrame", callback).Int()
}

func cancelAnimationFrame(id int) {
	dom.GetWindow().CancelAnimationFrame(id)
}

// RunPreparation is called automatically when calling Open. It should only be called once.
func RunPreparation() {
	Time = NewClock()

	dom.GetWindow().AddEventListener("onbeforeunload", false, func(e dom.Event) {
		dom.GetWindow().Alert("You're closing")
	})
}

func runLoop(defaultScene Scene, headless bool) {
	SetScene(defaultScene, false)
	RunPreparation()
	ticker := time.NewTicker(time.Duration(int(time.Second) / opts.FPSLimit))

	// Start tick, minimize the delta
	Time.Tick()

Outer:
	for {
		select {
		case <-ticker.C:
			if closeGame {
				break Outer
			}
			RunIteration()
		case <-resetLoopTicker:
			ticker.Stop()
			ticker = time.NewTicker(time.Duration(int(time.Second) / opts.FPSLimit))
		}
	}
	ticker.Stop()
}

func openFile(url string) (io.ReadCloser, error) {
	req := xhr.NewRequest("GET", url)

	req.ResponseType = xhr.ArrayBuffer

	if err := req.Send(""); err != nil {
		return nil, err
	}

	if req.Status != http.StatusOK {
		return nil, fmt.Errorf("unable to open resource (%s), expected HTTP status %d but got %d", url, http.StatusOK, req.Status)
	}

	buffer := bytes.NewBuffer(js.Global.Get("Uint8Array").New(req.Response).Interface().([]byte))

	return noCloseReadCloser{buffer}, nil
}

type noCloseReadCloser struct {
	r io.Reader
}

func (n noCloseReadCloser) Close() error { return nil }
func (n noCloseReadCloser) Read(p []byte) (int, error) {
	return n.r.Read(p)
}

// SetCursor changes the cursor
func SetCursor(c Cursor) {
	switch c {
	case CursorNone:
		document.Body().Style().Set("cursor", "default")
	case CursorHand:
		document.Body().Style().Set("cursor", "hand")
	}
}

//SetCursorVisibility sets the visibility of the cursor.
//If true the cursor is visible, if false the cursor is not.
func SetCursorVisibility(visible bool) {
	if visible {
		document.Body().Style().Set("cursor", "default")
	} else {
		document.Body().Style().Set("cursor", "none")
	}
}
<commit_msg>key polling<commit_after>//+build netgo

package engo

import (
	"bytes"
	"fmt"
	"io"
	"log"
	"math"
	"net/http"
	"strconv"
	"sync"
	"time"

	"engo.io/gl"
	"github.com/gopherjs/gopherjs/js"
	"honnef.co/go/js/dom"
	"honnef.co/go/js/xhr"
)

var (
	// Gl is the current OpenGL context
	Gl *gl.Context

	devicePixelRatio float64

	ResizeXOffset = float32(0)
	ResizeYOffset = float32(0)

	Backend string = "Web"

	poll     = make(map[int]bool)
	pollLock sync.Mutex
)

func init() {
	rafPolyfill()
}

//var canvas *js.Object
var document = dom.GetWindow().Document().(dom.HTMLDocument)

// CreateWindow creates a window with the specified parameters
func CreateWindow(title string, width, height int, fullscreen bool, msaa int) {
	canvas := document.CreateElement("canvas").(*dom.HTMLCanvasElement)

	devicePixelRatio = js.Global.Get("devicePixelRatio").Float()
	canvas.Width = int(float64(width)*devicePixelRatio + 0.5)   // Nearest non-negative int.
	canvas.Height = int(float64(height)*devicePixelRatio + 0.5) // Nearest non-negative int.
	canvas.Style().SetProperty("width", fmt.Sprintf("%vpx", width), "")
	canvas.Style().SetProperty("height", fmt.Sprintf("%vpx", height), "")
	log.Println("devicePixelRatio", devicePixelRatio)

	if document.Body() == nil {
		js.Global.Get("document").Set("body", js.Global.Get("document").Call("createElement", "body"))
		log.Println("Creating body, since it doesn't exist.")
	}

	document.Body().Style().SetProperty("margin", "0", "")
	document.Body().AppendChild(canvas)

	document.SetTitle(title)

	var err error

	Gl, err = gl.NewContext(canvas.Underlying(), nil) // TODO: we can add arguments here
	if err != nil {
		log.Println("Could not create context:", err)
		return
	}
	fmt.Println("Gl.Viewport(0, 0,", width, ",", height, ")")
	Gl.GetExtension("OES_texture_float")

	// DEBUG: Add framebuffer information div.
	if false {
		//canvas.Height -= 30
		text := document.CreateElement("div")
		textContent := fmt.Sprintf("%v %v (%v %v %v) @%v", dom.GetWindow().InnerWidth(), canvas.Width, float64(width)*devicePixelRatio, GameWidth(), CanvasWidth(), devicePixelRatio)
		text.SetTextContent(textContent)
		document.Body().AppendChild(text)
	}
	gameWidth = float32(width)
	gameHeight = float32(height)
	windowWidth = WindowWidth()
	windowHeight = WindowHeight()

	ResizeXOffset = gameWidth - CanvasWidth()
	ResizeYOffset = gameHeight - CanvasHeight()

	w := dom.GetWindow()
	w.AddEventListener("keypress", false, func(ev dom.Event) {
		// TODO: Not sure what to do here, come back
		//ke := ev.(*dom.KeyboardEvent)
		//responser.Type(rune(keyStates[Key(ke.KeyCode)]))
	})
	w.AddEventListener("keydown", false, func(ev dom.Event) {
		ke := ev.(*dom.KeyboardEvent)
		go func(i int) {
			pollLock.Lock()
			poll[i] = true
			pollLock.Unlock()
		}(ke.KeyCode)
	})

	w.AddEventListener("keyup", false, func(ev dom.Event) {
		ke := ev.(*dom.KeyboardEvent)
		go func(i int) {
			pollLock.Lock()
			poll[i] = false
			pollLock.Unlock()
		}(ke.KeyCode)
	})

	w.AddEventListener("mousemove", false, func(ev dom.Event) {
		mm := ev.(*dom.MouseEvent)
		Input.Mouse.X = float32(float64(mm.ClientX) * devicePixelRatio)
		Input.Mouse.Y = float32(float64(mm.ClientY) * devicePixelRatio)
		//Mouse.Action = MOVE
	})

	w.AddEventListener("mousedown", false, func(ev dom.Event) {
		mm := ev.(*dom.MouseEvent)
		Input.Mouse.X = float32(float64(mm.ClientX) * devicePixelRatio)
		Input.Mouse.Y = float32(float64(mm.ClientY) * devicePixelRatio)
		Input.Mouse.Action = Press
	})

	w.AddEventListener("mouseup", false, func(ev dom.Event) {
		mm := ev.(*dom.MouseEvent)
		Input.Mouse.X = float32(float64(mm.ClientX) * devicePixelRatio)
		Input.Mouse.Y = float32(float64(mm.ClientY) * devicePixelRatio)
		Input.Mouse.Action = Release
	})
}

func DestroyWindow() {}

// CursorPos returns the current cursor position
func CursorPos() (x, y float32) {
	return Input.Mouse.X, Input.Mouse.Y
}

// SetTitle changes the title of the page to the given string
func SetTitle(title string) {
	document.SetTitle(title)
}

// WindowSize returns the width and height of the current window
func WindowSize() (w, h int) {
	w = int(WindowWidth())
	h = int(WindowHeight())
	return
}

// WindowWidth returns the current window width
func WindowWidth() float32 {
	return float32(dom.GetWindow().InnerWidth())
}

// WindowHeight returns the current window height
func WindowHeight() float32 {
	return float32(dom.GetWindow().InnerHeight())
}

// CanvasWidth returns the current canvas width
func CanvasWidth() float32 {
	flt, err := strconv.ParseFloat(document.Body().GetElementsByTagName("canvas")[0].GetAttribute("width"), 32)
	if err != nil {
		log.Println("[ERROR] [CanvasWidth]:", err)
	}
	return float32(flt)
}

// CanvasHeight returns the current canvas height
func CanvasHeight() float32 {
	flt, err := strconv.ParseFloat(document.Body().GetElementsByTagName("canvas")[0].GetAttribute("height"), 32)
	if err != nil {
		log.Println("[ERROR] [CanvasHeight]:", err)
	}
	return float32(flt)
}

func CanvasScale() float32 {
	return 1
}

func toPx(n int) string {
	return strconv.FormatInt(int64(n), 10) + "px"
}

func rafPolyfill() {
	window := js.Global
	vendors := []string{"ms", "moz", "webkit", "o"}
	if window.Get("requestAnimationFrame") == nil {
		for i := 0; i < len(vendors) && window.Get("requestAnimationFrame") == nil; i++ {
			vendor := vendors[i]
			window.Set("requestAnimationFrame", window.Get(vendor+"RequestAnimationFrame"))
			window.Set("cancelAnimationFrame", window.Get(vendor+"CancelAnimationFrame"))
			if window.Get("cancelAnimationFrame") == nil {
				window.Set("cancelAnimationFrame", window.Get(vendor+"CancelRequestAnimationFrame"))
			}
		}
	}

	lastTime := 0.0
	if window.Get("requestAnimationFrame") == nil {
		window.Set("requestAnimationFrame", func(callback func(float32)) int {
			currTime := js.Global.Get("Date").New().Call("getTime").Float()
			timeToCall := math.Max(0, 16-(currTime-lastTime))
			id := window.Call("setTimeout", func() { callback(float32(currTime + timeToCall)) }, timeToCall)
			lastTime = currTime + timeToCall
			return id.Int()
		})
	}

	if window.Get("cancelAnimationFrame") == nil {
		window.Set("cancelAnimationFrame", func(id int) {
			js.Global.Get("clearTimeout").Invoke(id)
		})
	}
}

// RunIteration runs one iteration per frame
func RunIteration() {
	Time.Tick()
	Input.update()
	jsPollKeys()
	currentWorld.Update(Time.Delta())
	Input.Mouse.Action = Neutral
	// TODO: this may not work, and sky-rocket the FPS
	//  requestAnimationFrame(func(dt float32) {
	// 	currentWorld.Update(Time.Delta())
	// 	keysUpdate()
	// 	if !headless {
	// 		// TODO: does this require !headless?
	// 		Mouse.ScrollX, Mouse.ScrollY = 0, 0
	// 	}
	// 	Time.Tick()
	// })
}

// jsPollKeys polls the keys collected by the javascript callback
// this ensures the keys only get updated once per frame, since the
// callback has no information about the frames and is invoked several
// times between frames. This makes Input.Button.JustPressed and JustReleased
// able to return true properly.
func jsPollKeys() {
	pollLock.Lock()
	defer pollLock.Unlock()

	for key, state := range poll {
		Input.keys.Set(Key(key), state)
		delete(poll, key)
	}
}

func requestAnimationFrame(callback func(float32)) int {
	//return dom.GetWindow().RequestAnimationFrame(callback)
	return js.Global.Call("requestAnimationFrame", callback).Int()
}

func cancelAnimationFrame(id int) {
	dom.GetWindow().CancelAnimationFrame(id)
}

// RunPreparation is called automatically when calling Open. It should only be called once.
func RunPreparation() {
	Time = NewClock()

	dom.GetWindow().AddEventListener("onbeforeunload", false, func(e dom.Event) {
		dom.GetWindow().Alert("You're closing")
	})
}

func runLoop(defaultScene Scene, headless bool) {
	SetScene(defaultScene, false)
	RunPreparation()
	ticker := time.NewTicker(time.Duration(int(time.Second) / opts.FPSLimit))

	// Start tick, minimize the delta
	Time.Tick()

Outer:
	for {
		select {
		case <-ticker.C:
			if closeGame {
				break Outer
			}
			RunIteration()
		case <-resetLoopTicker:
			ticker.Stop()
			ticker = time.NewTicker(time.Duration(int(time.Second) / opts.FPSLimit))
		}
	}
	ticker.Stop()
}

func openFile(url string) (io.ReadCloser, error) {
	req := xhr.NewRequest("GET", url)

	req.ResponseType = xhr.ArrayBuffer

	if err := req.Send(""); err != nil {
		return nil, err
	}

	if req.Status != http.StatusOK {
		return nil, fmt.Errorf("unable to open resource (%s), expected HTTP status %d but got %d", url, http.StatusOK, req.Status)
	}

	buffer := bytes.NewBuffer(js.Global.Get("Uint8Array").New(req.Response).Interface().([]byte))

	return noCloseReadCloser{buffer}, nil
}

type noCloseReadCloser struct {
	r io.Reader
}

func (n noCloseReadCloser) Close() error { return nil }
func (n noCloseReadCloser) Read(p []byte) (int, error) {
	return n.r.Read(p)
}

// SetCursor changes the cursor
func SetCursor(c Cursor) {
	switch c {
	case CursorNone:
		document.Body().Style().Set("cursor", "default")
	case CursorHand:
		document.Body().Style().Set("cursor", "hand")
	}
}

//SetCursorVisibility sets the visibility of the cursor.
//If true the cursor is visible, if false the cursor is not.
func SetCursorVisibility(visible bool) {
	if visible {
		document.Body().Style().Set("cursor", "default")
	} else {
		document.Body().Style().Set("cursor", "none")
	}
}
<|endoftext|>


<commit_before>// SPDX-License-Identifier: MIT

package dep

var _ Module = &Default{}

func newMod(id string, f func() error, dep ...string) *Default {
	d := NewDefaultModule(id, id+" description", dep...)
	d.AddInit(f, id)
	return d
}
<commit_msg>test(internal/dep): 添加对 Default.AddInit 的测试<commit_after>// SPDX-License-Identifier: MIT

package dep

import (
	"io/ioutil"
	"log"
	"testing"

	"github.com/issue9/assert"
)

var _ Module = &Default{}

func newMod(id string, f func() error, dep ...string) *Default {
	d := NewDefaultModule(id, id+" description", dep...)
	d.AddInit(f, id)
	return d
}

func TestDefault_AddInit(t *testing.T) {
	a := assert.New(t)

	m := NewDefaultModule("m1", "m1 dexc")

	a.Empty(m.inits)
	m.AddInit(func() error { return nil }, "t1")
	a.Equal(len(m.inits), 1).
		Equal(m.inits[0].title, "t1").
		NotNil(m.inits[0].f)

	m.AddInit(func() error { return nil }, "t1")
	a.Equal(len(m.inits), 2).
		Equal(m.inits[1].title, "t1").
		NotNil(m.inits[1].f)

	m.AddInit(func() error { return nil }, "t1")
	a.Equal(len(m.inits), 3).
		Equal(m.inits[2].title, "t1").
		NotNil(m.inits[2].f)

	a.NotError(m.Init(log.New(ioutil.Discard, "", 0)))
	a.Panic(func() {
		m.AddInit(func() error { return nil }, "t1")
	})
}
<|endoftext|>


<commit_before>package provisioning

import (
	"context"
	"path/filepath"
	"sync"

	"github.com/grafana/grafana/pkg/infra/log"
	plugifaces "github.com/grafana/grafana/pkg/plugins"
	"github.com/grafana/grafana/pkg/registry"
	dashboardservice "github.com/grafana/grafana/pkg/services/dashboards"
	"github.com/grafana/grafana/pkg/services/encryption"
	"github.com/grafana/grafana/pkg/services/notifications"
	"github.com/grafana/grafana/pkg/services/provisioning/dashboards"
	"github.com/grafana/grafana/pkg/services/provisioning/datasources"
	"github.com/grafana/grafana/pkg/services/provisioning/notifiers"
	"github.com/grafana/grafana/pkg/services/provisioning/plugins"
	"github.com/grafana/grafana/pkg/services/provisioning/utils"
	"github.com/grafana/grafana/pkg/services/sqlstore"
	"github.com/grafana/grafana/pkg/setting"
	"github.com/grafana/grafana/pkg/util/errutil"
)

func ProvideService(cfg *setting.Cfg, sqlStore *sqlstore.SQLStore, pluginStore plugifaces.Store,
	encryptionService encryption.Internal, notificatonService *notifications.NotificationService,
	dashboardService dashboardservice.DashboardProvisioningService,
) (*ProvisioningServiceImpl, error) {
	s := &ProvisioningServiceImpl{
		Cfg:                     cfg,
		SQLStore:                sqlStore,
		pluginStore:             pluginStore,
		EncryptionService:       encryptionService,
		NotificationService:     notificatonService,
		log:                     log.New("provisioning"),
		newDashboardProvisioner: dashboards.New,
		provisionNotifiers:      notifiers.Provision,
		provisionDatasources:    datasources.Provision,
		provisionPlugins:        plugins.Provision,
		dashboardService:        dashboardService,
	}
	return s, nil
}

type ProvisioningService interface {
	registry.BackgroundService
	RunInitProvisioners(ctx context.Context) error
	ProvisionDatasources(ctx context.Context) error
	ProvisionPlugins(ctx context.Context) error
	ProvisionNotifications(ctx context.Context) error
	ProvisionDashboards(ctx context.Context) error
	GetDashboardProvisionerResolvedPath(name string) string
	GetAllowUIUpdatesFromConfig(name string) bool
}

// Add a public constructor for overriding service to be able to instantiate OSS as fallback
func NewProvisioningServiceImpl() *ProvisioningServiceImpl {
	return &ProvisioningServiceImpl{
		log:                     log.New("provisioning"),
		newDashboardProvisioner: dashboards.New,
		provisionNotifiers:      notifiers.Provision,
		provisionDatasources:    datasources.Provision,
		provisionPlugins:        plugins.Provision,
	}
}

// Used for testing purposes
func newProvisioningServiceImpl(
	newDashboardProvisioner dashboards.DashboardProvisionerFactory,
	provisionNotifiers func(context.Context, string, notifiers.Store, encryption.Internal, *notifications.NotificationService) error,
	provisionDatasources func(context.Context, string, datasources.Store, utils.OrgStore) error,
	provisionPlugins func(context.Context, string, plugins.Store, plugifaces.Store) error,
) *ProvisioningServiceImpl {
	return &ProvisioningServiceImpl{
		log:                     log.New("provisioning"),
		newDashboardProvisioner: newDashboardProvisioner,
		provisionNotifiers:      provisionNotifiers,
		provisionDatasources:    provisionDatasources,
		provisionPlugins:        provisionPlugins,
	}
}

type ProvisioningServiceImpl struct {
	Cfg                     *setting.Cfg
	SQLStore                *sqlstore.SQLStore
	pluginStore             plugifaces.Store
	EncryptionService       encryption.Internal
	NotificationService     *notifications.NotificationService
	log                     log.Logger
	pollingCtxCancel        context.CancelFunc
	newDashboardProvisioner dashboards.DashboardProvisionerFactory
	dashboardProvisioner    dashboards.DashboardProvisioner
	provisionNotifiers      func(context.Context, string, notifiers.Store, encryption.Internal, *notifications.NotificationService) error
	provisionDatasources    func(context.Context, string, datasources.Store, utils.OrgStore) error
	provisionPlugins        func(context.Context, string, plugins.Store, plugifaces.Store) error
	mutex                   sync.Mutex
	dashboardService        dashboardservice.DashboardProvisioningService
}

func (ps *ProvisioningServiceImpl) RunInitProvisioners(ctx context.Context) error {
	err := ps.ProvisionDatasources(ctx)
	if err != nil {
		return err
	}

	err = ps.ProvisionPlugins(ctx)
	if err != nil {
		return err
	}

	err = ps.ProvisionNotifications(ctx)
	if err != nil {
		return err
	}

	return nil
}

func (ps *ProvisioningServiceImpl) Run(ctx context.Context) error {
	err := ps.ProvisionDashboards(ctx)
	if err != nil {
		ps.log.Error("Failed to provision dashboard", "error", err)
		return err
	}

	for {
		// Wait for unlock. This is tied to new dashboardProvisioner to be instantiated before we start polling.
		ps.mutex.Lock()
		// Using background here because otherwise if root context was canceled the select later on would
		// non-deterministically take one of the route possibly going into one polling loop before exiting.
		pollingContext, cancelFun := context.WithCancel(context.Background())
		ps.pollingCtxCancel = cancelFun
		ps.dashboardProvisioner.PollChanges(pollingContext)
		ps.mutex.Unlock()

		select {
		case <-pollingContext.Done():
			// Polling was canceled.
			continue
		case <-ctx.Done():
			// Root server context was cancelled so cancel polling and leave.
			ps.cancelPolling()
			return ctx.Err()
		}
	}
}

func (ps *ProvisioningServiceImpl) ProvisionDatasources(ctx context.Context) error {
	datasourcePath := filepath.Join(ps.Cfg.ProvisioningPath, "datasources")
	if err := ps.provisionDatasources(ctx, datasourcePath, ps.SQLStore, ps.SQLStore); err != nil {
		err = errutil.Wrap("Datasource provisioning error", err)
		ps.log.Error("Failed to provision data sources", "error", err)
		return err
	}
	return nil
}

func (ps *ProvisioningServiceImpl) ProvisionPlugins(ctx context.Context) error {
	appPath := filepath.Join(ps.Cfg.ProvisioningPath, "plugins")
	if err := ps.provisionPlugins(ctx, appPath, ps.SQLStore, ps.pluginStore); err != nil {
		err = errutil.Wrap("app provisioning error", err)
		ps.log.Error("Failed to provision plugins", "error", err)
		return err
	}
	return nil
}

func (ps *ProvisioningServiceImpl) ProvisionNotifications(ctx context.Context) error {
	alertNotificationsPath := filepath.Join(ps.Cfg.ProvisioningPath, "notifiers")
	if err := ps.provisionNotifiers(ctx, alertNotificationsPath, ps.SQLStore, ps.EncryptionService, ps.NotificationService); err != nil {
		err = errutil.Wrap("Alert notification provisioning error", err)
		ps.log.Error("Failed to provision alert notifications", "error", err)
		return err
	}
	return nil
}

func (ps *ProvisioningServiceImpl) ProvisionDashboards(ctx context.Context) error {
	dashboardPath := filepath.Join(ps.Cfg.ProvisioningPath, "dashboards")
	dashProvisioner, err := ps.newDashboardProvisioner(ctx, dashboardPath, ps.dashboardService, ps.SQLStore)
	if err != nil {
		return errutil.Wrap("Failed to create provisioner", err)
	}

	ps.mutex.Lock()
	defer ps.mutex.Unlock()

	ps.cancelPolling()
	dashProvisioner.CleanUpOrphanedDashboards(ctx)

	err = dashProvisioner.Provision(ctx)
	if err != nil {
		// If we fail to provision with the new provisioner, the mutex will unlock and the polling will restart with the
		// old provisioner as we did not switch them yet.
		return errutil.Wrap("Failed to provision dashboards", err)
	}
	ps.dashboardProvisioner = dashProvisioner
	return nil
}

func (ps *ProvisioningServiceImpl) GetDashboardProvisionerResolvedPath(name string) string {
	return ps.dashboardProvisioner.GetProvisionerResolvedPath(name)
}

func (ps *ProvisioningServiceImpl) GetAllowUIUpdatesFromConfig(name string) bool {
	return ps.dashboardProvisioner.GetAllowUIUpdatesFromConfig(name)
}

func (ps *ProvisioningServiceImpl) cancelPolling() {
	if ps.pollingCtxCancel != nil {
		ps.log.Debug("Stop polling for dashboard changes")
		ps.pollingCtxCancel()
	}
	ps.pollingCtxCancel = nil
}
<commit_msg>use datasource service instead of store in provisioning (#45835)<commit_after>package provisioning

import (
	"context"
	"path/filepath"
	"sync"

	"github.com/grafana/grafana/pkg/infra/log"
	plugifaces "github.com/grafana/grafana/pkg/plugins"
	"github.com/grafana/grafana/pkg/registry"
	dashboardservice "github.com/grafana/grafana/pkg/services/dashboards"
	datasourceservice "github.com/grafana/grafana/pkg/services/datasources"
	"github.com/grafana/grafana/pkg/services/encryption"
	"github.com/grafana/grafana/pkg/services/notifications"
	"github.com/grafana/grafana/pkg/services/provisioning/dashboards"
	"github.com/grafana/grafana/pkg/services/provisioning/datasources"
	"github.com/grafana/grafana/pkg/services/provisioning/notifiers"
	"github.com/grafana/grafana/pkg/services/provisioning/plugins"
	"github.com/grafana/grafana/pkg/services/provisioning/utils"
	"github.com/grafana/grafana/pkg/services/sqlstore"
	"github.com/grafana/grafana/pkg/setting"
	"github.com/grafana/grafana/pkg/util/errutil"
)

func ProvideService(cfg *setting.Cfg, sqlStore *sqlstore.SQLStore, pluginStore plugifaces.Store,
	encryptionService encryption.Internal, notificatonService *notifications.NotificationService,
	dashboardService dashboardservice.DashboardProvisioningService,
	datasourceService datasourceservice.DataSourceService,
) (*ProvisioningServiceImpl, error) {
	s := &ProvisioningServiceImpl{
		Cfg:                     cfg,
		SQLStore:                sqlStore,
		pluginStore:             pluginStore,
		EncryptionService:       encryptionService,
		NotificationService:     notificatonService,
		log:                     log.New("provisioning"),
		newDashboardProvisioner: dashboards.New,
		provisionNotifiers:      notifiers.Provision,
		provisionDatasources:    datasources.Provision,
		provisionPlugins:        plugins.Provision,
		dashboardService:        dashboardService,
		datasourceService:       datasourceService,
	}
	return s, nil
}

type ProvisioningService interface {
	registry.BackgroundService
	RunInitProvisioners(ctx context.Context) error
	ProvisionDatasources(ctx context.Context) error
	ProvisionPlugins(ctx context.Context) error
	ProvisionNotifications(ctx context.Context) error
	ProvisionDashboards(ctx context.Context) error
	GetDashboardProvisionerResolvedPath(name string) string
	GetAllowUIUpdatesFromConfig(name string) bool
}

// Add a public constructor for overriding service to be able to instantiate OSS as fallback
func NewProvisioningServiceImpl() *ProvisioningServiceImpl {
	return &ProvisioningServiceImpl{
		log:                     log.New("provisioning"),
		newDashboardProvisioner: dashboards.New,
		provisionNotifiers:      notifiers.Provision,
		provisionDatasources:    datasources.Provision,
		provisionPlugins:        plugins.Provision,
	}
}

// Used for testing purposes
func newProvisioningServiceImpl(
	newDashboardProvisioner dashboards.DashboardProvisionerFactory,
	provisionNotifiers func(context.Context, string, notifiers.Store, encryption.Internal, *notifications.NotificationService) error,
	provisionDatasources func(context.Context, string, datasources.Store, utils.OrgStore) error,
	provisionPlugins func(context.Context, string, plugins.Store, plugifaces.Store) error,
) *ProvisioningServiceImpl {
	return &ProvisioningServiceImpl{
		log:                     log.New("provisioning"),
		newDashboardProvisioner: newDashboardProvisioner,
		provisionNotifiers:      provisionNotifiers,
		provisionDatasources:    provisionDatasources,
		provisionPlugins:        provisionPlugins,
	}
}

type ProvisioningServiceImpl struct {
	Cfg                     *setting.Cfg
	SQLStore                *sqlstore.SQLStore
	pluginStore             plugifaces.Store
	EncryptionService       encryption.Internal
	NotificationService     *notifications.NotificationService
	log                     log.Logger
	pollingCtxCancel        context.CancelFunc
	newDashboardProvisioner dashboards.DashboardProvisionerFactory
	dashboardProvisioner    dashboards.DashboardProvisioner
	provisionNotifiers      func(context.Context, string, notifiers.Store, encryption.Internal, *notifications.NotificationService) error
	provisionDatasources    func(context.Context, string, datasources.Store, utils.OrgStore) error
	provisionPlugins        func(context.Context, string, plugins.Store, plugifaces.Store) error
	mutex                   sync.Mutex
	dashboardService        dashboardservice.DashboardProvisioningService
	datasourceService       datasourceservice.DataSourceService
}

func (ps *ProvisioningServiceImpl) RunInitProvisioners(ctx context.Context) error {
	err := ps.ProvisionDatasources(ctx)
	if err != nil {
		return err
	}

	err = ps.ProvisionPlugins(ctx)
	if err != nil {
		return err
	}

	err = ps.ProvisionNotifications(ctx)
	if err != nil {
		return err
	}

	return nil
}

func (ps *ProvisioningServiceImpl) Run(ctx context.Context) error {
	err := ps.ProvisionDashboards(ctx)
	if err != nil {
		ps.log.Error("Failed to provision dashboard", "error", err)
		return err
	}

	for {
		// Wait for unlock. This is tied to new dashboardProvisioner to be instantiated before we start polling.
		ps.mutex.Lock()
		// Using background here because otherwise if root context was canceled the select later on would
		// non-deterministically take one of the route possibly going into one polling loop before exiting.
		pollingContext, cancelFun := context.WithCancel(context.Background())
		ps.pollingCtxCancel = cancelFun
		ps.dashboardProvisioner.PollChanges(pollingContext)
		ps.mutex.Unlock()

		select {
		case <-pollingContext.Done():
			// Polling was canceled.
			continue
		case <-ctx.Done():
			// Root server context was cancelled so cancel polling and leave.
			ps.cancelPolling()
			return ctx.Err()
		}
	}
}

func (ps *ProvisioningServiceImpl) ProvisionDatasources(ctx context.Context) error {
	datasourcePath := filepath.Join(ps.Cfg.ProvisioningPath, "datasources")
	if err := ps.provisionDatasources(ctx, datasourcePath, ps.datasourceService, ps.SQLStore); err != nil {
		err = errutil.Wrap("Datasource provisioning error", err)
		ps.log.Error("Failed to provision data sources", "error", err)
		return err
	}
	return nil
}

func (ps *ProvisioningServiceImpl) ProvisionPlugins(ctx context.Context) error {
	appPath := filepath.Join(ps.Cfg.ProvisioningPath, "plugins")
	if err := ps.provisionPlugins(ctx, appPath, ps.SQLStore, ps.pluginStore); err != nil {
		err = errutil.Wrap("app provisioning error", err)
		ps.log.Error("Failed to provision plugins", "error", err)
		return err
	}
	return nil
}

func (ps *ProvisioningServiceImpl) ProvisionNotifications(ctx context.Context) error {
	alertNotificationsPath := filepath.Join(ps.Cfg.ProvisioningPath, "notifiers")
	if err := ps.provisionNotifiers(ctx, alertNotificationsPath, ps.SQLStore, ps.EncryptionService, ps.NotificationService); err != nil {
		err = errutil.Wrap("Alert notification provisioning error", err)
		ps.log.Error("Failed to provision alert notifications", "error", err)
		return err
	}
	return nil
}

func (ps *ProvisioningServiceImpl) ProvisionDashboards(ctx context.Context) error {
	dashboardPath := filepath.Join(ps.Cfg.ProvisioningPath, "dashboards")
	dashProvisioner, err := ps.newDashboardProvisioner(ctx, dashboardPath, ps.dashboardService, ps.SQLStore)
	if err != nil {
		return errutil.Wrap("Failed to create provisioner", err)
	}

	ps.mutex.Lock()
	defer ps.mutex.Unlock()

	ps.cancelPolling()
	dashProvisioner.CleanUpOrphanedDashboards(ctx)

	err = dashProvisioner.Provision(ctx)
	if err != nil {
		// If we fail to provision with the new provisioner, the mutex will unlock and the polling will restart with the
		// old provisioner as we did not switch them yet.
		return errutil.Wrap("Failed to provision dashboards", err)
	}
	ps.dashboardProvisioner = dashProvisioner
	return nil
}

func (ps *ProvisioningServiceImpl) GetDashboardProvisionerResolvedPath(name string) string {
	return ps.dashboardProvisioner.GetProvisionerResolvedPath(name)
}

func (ps *ProvisioningServiceImpl) GetAllowUIUpdatesFromConfig(name string) bool {
	return ps.dashboardProvisioner.GetAllowUIUpdatesFromConfig(name)
}

func (ps *ProvisioningServiceImpl) cancelPolling() {
	if ps.pollingCtxCancel != nil {
		ps.log.Debug("Stop polling for dashboard changes")
		ps.pollingCtxCancel()
	}
	ps.pollingCtxCancel = nil
}
<|endoftext|>


<commit_before>// Copyright 2017 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.package remote

package remote

import (
	"sync"

	"github.com/prometheus/common/model"
	"github.com/prometheus/prometheus/config"
)

type Storage struct {
	mtx sync.RWMutex

	// For writes
	queues []*QueueManager

	// For reads
	clients        []*Client
	externalLabels model.LabelSet
}

// ApplyConfig updates the state as the new config requires.
func (s *Storage) ApplyConfig(conf *config.Config) error {
	s.mtx.Lock()
	defer s.mtx.Unlock()

	// Update write queues

	newQueues := []*QueueManager{}
	// TODO: we should only stop & recreate queues which have changes,
	// as this can be quite disruptive.
	for i, rwConf := range conf.RemoteWriteConfigs {
		c, err := NewClient(i, &clientConfig{
			url:              rwConf.URL,
			timeout:          rwConf.RemoteTimeout,
			httpClientConfig: rwConf.HTTPClientConfig,
		})
		if err != nil {
			return err
		}
		newQueues = append(newQueues, NewQueueManager(
			defaultQueueManagerConfig,
			conf.GlobalConfig.ExternalLabels,
			rwConf.WriteRelabelConfigs,
			c,
		))
	}

	for _, q := range s.queues {
		q.Stop()
	}

	s.queues = newQueues
	for _, q := range s.queues {
		q.Start()
	}

	// Update read clients

	clients := []*Client{}
	for i, rrConf := range conf.RemoteReadConfigs {
		c, err := NewClient(i, &clientConfig{
			url:              rrConf.URL,
			timeout:          rrConf.RemoteTimeout,
			httpClientConfig: rrConf.HTTPClientConfig,
		})
		if err != nil {
			return err
		}
		clients = append(clients, c)
	}

	s.clients = clients
	s.externalLabels = conf.GlobalConfig.ExternalLabels

	return nil
}

// Stop the background processing of the storage queues.
func (s *Storage) Close() error {
	s.mtx.Lock()
	defer s.mtx.Unlock()

	for _, q := range s.queues {
		q.Stop()
	}

	return nil
}
<commit_msg>Fix some comments.<commit_after>// Copyright 2017 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.package remote

package remote

import (
	"sync"

	"github.com/prometheus/common/model"
	"github.com/prometheus/prometheus/config"
)

// Storage represents all the remote read and write endpoints.  It implements
// storage.Storage.
type Storage struct {
	mtx sync.RWMutex

	// For writes
	queues []*QueueManager

	// For reads
	clients        []*Client
	externalLabels model.LabelSet
}

// ApplyConfig updates the state as the new config requires.
func (s *Storage) ApplyConfig(conf *config.Config) error {
	s.mtx.Lock()
	defer s.mtx.Unlock()

	// Update write queues

	newQueues := []*QueueManager{}
	// TODO: we should only stop & recreate queues which have changes,
	// as this can be quite disruptive.
	for i, rwConf := range conf.RemoteWriteConfigs {
		c, err := NewClient(i, &clientConfig{
			url:              rwConf.URL,
			timeout:          rwConf.RemoteTimeout,
			httpClientConfig: rwConf.HTTPClientConfig,
		})
		if err != nil {
			return err
		}
		newQueues = append(newQueues, NewQueueManager(
			defaultQueueManagerConfig,
			conf.GlobalConfig.ExternalLabels,
			rwConf.WriteRelabelConfigs,
			c,
		))
	}

	for _, q := range s.queues {
		q.Stop()
	}

	s.queues = newQueues
	for _, q := range s.queues {
		q.Start()
	}

	// Update read clients

	clients := []*Client{}
	for i, rrConf := range conf.RemoteReadConfigs {
		c, err := NewClient(i, &clientConfig{
			url:              rrConf.URL,
			timeout:          rrConf.RemoteTimeout,
			httpClientConfig: rrConf.HTTPClientConfig,
		})
		if err != nil {
			return err
		}
		clients = append(clients, c)
	}

	s.clients = clients
	s.externalLabels = conf.GlobalConfig.ExternalLabels

	return nil
}

// Close the background processing of the storage queues.
func (s *Storage) Close() error {
	s.mtx.Lock()
	defer s.mtx.Unlock()

	for _, q := range s.queues {
		q.Stop()
	}

	return nil
}
<|endoftext|>


<commit_before>package rulesets

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"strings"
	"time"

	"github.com/ion-channel/ionic/requests"
	"github.com/ion-channel/ionic/rules"
)

const (
	// CreateRuleSetEndpoint is a string representation of the current endpoint for creating ruleset
	CreateRuleSetEndpoint = "v1/ruleset/createRuleset"
	// GetAppliedRuleSetEndpoint is a string representation of the current endpoint for getting applied ruleset
	GetAppliedRuleSetEndpoint = "v1/ruleset/getAppliedRulesetForProject"
	// GetBatchAppliedRulesetEndpoint is a string representation of the current endpoint for getting batched applied rulesets
	GetBatchAppliedRulesetEndpoint = "v1/ruleset/getAppliedRulesets"
	// GetRuleSetEndpoint is a string representation of the current endpoint for getting ruleset
	GetRuleSetEndpoint = "v1/ruleset/getRuleset"
	// GetRuleSetsEndpoint is a string representation of the current endpoint for getting rulesets (plural)
	GetRuleSetsEndpoint = "v1/ruleset/getRulesets"
	//RulesetsGetRulesEndpoint is a string representation of the current endpoint for getting rules.
	RulesetsGetRulesEndpoint = "v1/ruleset/getRules"
	//RulesetsGetRulesetNames is a string representation of the current endpoint for getting ruleset names.
	RulesetsGetRulesetNames = "v1/ruleset/getRulesetNames"
)

// AppliedRulesetRequest represents a request for an applied ruleset result
type AppliedRulesetRequest struct {
	ProjectID  string `json:"project_id"`
	TeamID     string `json:"team_id"`
	SummaryID  string `json:"summary_id"`
	AnalysisID string `json:"analysis_id"`
}

// CreateRuleSetOptions struct for creating a ruleset
type CreateRuleSetOptions struct {
	Name        string   `json:"name"`
	Description string   `json:"description" default:" "`
	TeamID      string   `json:"team_id"`
	RuleIDs     []string `json:"rule_ids"`
}

// RuleSet is a collection of rules
type RuleSet struct {
	ID          string        `json:"id"`
	TeamID      string        `json:"team_id"`
	Name        string        `json:"name"`
	Description string        `json:"description"`
	RuleIDs     []string      `json:"rule_ids"`
	CreatedAt   time.Time     `json:"created_at"`
	UpdatedAt   time.Time     `json:"updated_at"`
	Rules       []rules.Rule  `json:"rules"`
	Deprecated  bool          `json:"has_deprecated_rules"`
	IsUsed      bool          `json:"has_projects_assigned"`
	DeletedAt   *sql.NullTime `json:"deleted_at,omitempty"`
	DeletedBy   string        `json:"deleted_by,omitempty"`
}

// NameForID represents the data object for ruleset name and its ID
type NameForID struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}

// String returns a JSON formatted string of the ruleset object
func (r RuleSet) String() string {
	b, err := json.Marshal(r)
	if err != nil {
		return fmt.Sprintf("failed to format ruleset: %v", err.Error())
	}
	return string(b)
}

// RuleSetExists takes a client, baseURL, ruleSetID, teamId and token string and checks against api to see if ruleset exists.
// It returns whether or not ruleset exists and any errors it encounters with the API.
// This is used internally in the SDK
func RuleSetExists(client *http.Client, baseURL *url.URL, ruleSetID, teamID, token string) (bool, error) {
	params := &url.Values{}
	params.Set("id", ruleSetID)
	params.Set("team_id", teamID)

	err := requests.Head(client, baseURL, GetRuleSetEndpoint, token, params, nil, nil)

	if err != nil {
		if strings.Contains(err.Error(), "(404)") {
			return false, nil
		}

		return false, fmt.Errorf("failed to request ruleset: %v", err.Error())
	}

	return true, nil
}
<commit_msg>update ruleset name struct to include team_id<commit_after>package rulesets

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"strings"
	"time"

	"github.com/ion-channel/ionic/requests"
	"github.com/ion-channel/ionic/rules"
)

const (
	// CreateRuleSetEndpoint is a string representation of the current endpoint for creating ruleset
	CreateRuleSetEndpoint = "v1/ruleset/createRuleset"
	// GetAppliedRuleSetEndpoint is a string representation of the current endpoint for getting applied ruleset
	GetAppliedRuleSetEndpoint = "v1/ruleset/getAppliedRulesetForProject"
	// GetBatchAppliedRulesetEndpoint is a string representation of the current endpoint for getting batched applied rulesets
	GetBatchAppliedRulesetEndpoint = "v1/ruleset/getAppliedRulesets"
	// GetRuleSetEndpoint is a string representation of the current endpoint for getting ruleset
	GetRuleSetEndpoint = "v1/ruleset/getRuleset"
	// GetRuleSetsEndpoint is a string representation of the current endpoint for getting rulesets (plural)
	GetRuleSetsEndpoint = "v1/ruleset/getRulesets"
	//RulesetsGetRulesEndpoint is a string representation of the current endpoint for getting rules.
	RulesetsGetRulesEndpoint = "v1/ruleset/getRules"
	//RulesetsGetRulesetNames is a string representation of the current endpoint for getting ruleset names.
	RulesetsGetRulesetNames = "v1/ruleset/getRulesetNames"
)

// AppliedRulesetRequest represents a request for an applied ruleset result
type AppliedRulesetRequest struct {
	ProjectID  string `json:"project_id"`
	TeamID     string `json:"team_id"`
	SummaryID  string `json:"summary_id"`
	AnalysisID string `json:"analysis_id"`
}

// CreateRuleSetOptions struct for creating a ruleset
type CreateRuleSetOptions struct {
	Name        string   `json:"name"`
	Description string   `json:"description" default:" "`
	TeamID      string   `json:"team_id"`
	RuleIDs     []string `json:"rule_ids"`
}

// RuleSet is a collection of rules
type RuleSet struct {
	ID          string        `json:"id"`
	TeamID      string        `json:"team_id"`
	Name        string        `json:"name"`
	Description string        `json:"description"`
	RuleIDs     []string      `json:"rule_ids"`
	CreatedAt   time.Time     `json:"created_at"`
	UpdatedAt   time.Time     `json:"updated_at"`
	Rules       []rules.Rule  `json:"rules"`
	Deprecated  bool          `json:"has_deprecated_rules"`
	IsUsed      bool          `json:"has_projects_assigned"`
	DeletedAt   *sql.NullTime `json:"deleted_at,omitempty"`
	DeletedBy   string        `json:"deleted_by,omitempty"`
}

// NameForID represents the data object for ruleset name and its ID
type NameForID struct {
	ID     string `json:"id"`
	Name   string `json:"name"`
	TeamID string `json:"team_id"`
}

// String returns a JSON formatted string of the ruleset object
func (r RuleSet) String() string {
	b, err := json.Marshal(r)
	if err != nil {
		return fmt.Sprintf("failed to format ruleset: %v", err.Error())
	}
	return string(b)
}

// RuleSetExists takes a client, baseURL, ruleSetID, teamId and token string and checks against api to see if ruleset exists.
// It returns whether or not ruleset exists and any errors it encounters with the API.
// This is used internally in the SDK
func RuleSetExists(client *http.Client, baseURL *url.URL, ruleSetID, teamID, token string) (bool, error) {
	params := &url.Values{}
	params.Set("id", ruleSetID)
	params.Set("team_id", teamID)

	err := requests.Head(client, baseURL, GetRuleSetEndpoint, token, params, nil, nil)

	if err != nil {
		if strings.Contains(err.Error(), "(404)") {
			return false, nil
		}

		return false, fmt.Errorf("failed to request ruleset: %v", err.Error())
	}

	return true, nil
}
<|endoftext|>


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

package main

import (
	"fmt"
	"os"
	"runtime"
	"runtime/debug"
	"sync/atomic"
	"time"
)

func init() {
	register("GCFairness", GCFairness)
	register("GCFairness2", GCFairness2)
	register("GCSys", GCSys)
}

func GCSys() {
	runtime.GOMAXPROCS(1)
	memstats := new(runtime.MemStats)
	runtime.GC()
	runtime.ReadMemStats(memstats)
	sys := memstats.Sys

	runtime.MemProfileRate = 0 // disable profiler

	itercount := 100000
	for i := 0; i < itercount; i++ {
		workthegc()
	}

	// Should only be using a few MB.
	// We allocated 100 MB or (if not short) 1 GB.
	runtime.ReadMemStats(memstats)
	if sys > memstats.Sys {
		sys = 0
	} else {
		sys = memstats.Sys - sys
	}
	if sys > 16<<20 {
		fmt.Printf("using too much memory: %d bytes\n", sys)
		return
	}
	fmt.Printf("OK\n")
}

func workthegc() []byte {
	return make([]byte, 1029)
}

func GCFairness() {
	runtime.GOMAXPROCS(1)
	f, err := os.Open("/dev/null")
	if os.IsNotExist(err) {
		// This test tests what it is intended to test only if writes are fast.
		// If there is no /dev/null, we just don't execute the test.
		fmt.Println("OK")
		return
	}
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	for i := 0; i < 2; i++ {
		go func() {
			for {
				f.Write([]byte("."))
			}
		}()
	}
	time.Sleep(10 * time.Millisecond)
	fmt.Println("OK")
}

func GCFairness2() {
	// Make sure user code can't exploit the GC's high priority
	// scheduling to make scheduling of user code unfair. See
	// issue #15706.
	runtime.GOMAXPROCS(1)
	debug.SetGCPercent(1)
	var count [3]int64
	var sink [3]interface{}
	for i := range count {
		go func(i int) {
			for {
				sink[i] = make([]byte, 1024)
				atomic.AddInt64(&count[i], 1)
			}
		}(i)
	}
	// Note: If the unfairness is really bad, it may not even get
	// past the sleep.
	//
	// If the scheduling rules change, this may not be enough time
	// to let all goroutines run, but for now we cycle through
	// them rapidly.
	time.Sleep(30 * time.Millisecond)
	for i := range count {
		if atomic.LoadInt64(&count[i]) == 0 {
			fmt.Printf("goroutine %d did not run\n", i)
			return
		}
	}
	fmt.Println("OK")
}
<commit_msg>runtime/testdata/testprog: increase GCFairness2 timeout to 1s<commit_after>// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"fmt"
	"os"
	"runtime"
	"runtime/debug"
	"sync/atomic"
	"time"
)

func init() {
	register("GCFairness", GCFairness)
	register("GCFairness2", GCFairness2)
	register("GCSys", GCSys)
}

func GCSys() {
	runtime.GOMAXPROCS(1)
	memstats := new(runtime.MemStats)
	runtime.GC()
	runtime.ReadMemStats(memstats)
	sys := memstats.Sys

	runtime.MemProfileRate = 0 // disable profiler

	itercount := 100000
	for i := 0; i < itercount; i++ {
		workthegc()
	}

	// Should only be using a few MB.
	// We allocated 100 MB or (if not short) 1 GB.
	runtime.ReadMemStats(memstats)
	if sys > memstats.Sys {
		sys = 0
	} else {
		sys = memstats.Sys - sys
	}
	if sys > 16<<20 {
		fmt.Printf("using too much memory: %d bytes\n", sys)
		return
	}
	fmt.Printf("OK\n")
}

func workthegc() []byte {
	return make([]byte, 1029)
}

func GCFairness() {
	runtime.GOMAXPROCS(1)
	f, err := os.Open("/dev/null")
	if os.IsNotExist(err) {
		// This test tests what it is intended to test only if writes are fast.
		// If there is no /dev/null, we just don't execute the test.
		fmt.Println("OK")
		return
	}
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	for i := 0; i < 2; i++ {
		go func() {
			for {
				f.Write([]byte("."))
			}
		}()
	}
	time.Sleep(10 * time.Millisecond)
	fmt.Println("OK")
}

func GCFairness2() {
	// Make sure user code can't exploit the GC's high priority
	// scheduling to make scheduling of user code unfair. See
	// issue #15706.
	runtime.GOMAXPROCS(1)
	debug.SetGCPercent(1)
	var count [3]int64
	var sink [3]interface{}
	for i := range count {
		go func(i int) {
			for {
				sink[i] = make([]byte, 1024)
				atomic.AddInt64(&count[i], 1)
			}
		}(i)
	}
	// Note: If the unfairness is really bad, it may not even get
	// past the sleep.
	//
	// If the scheduling rules change, this may not be enough time
	// to let all goroutines run, but for now we cycle through
	// them rapidly.
	//
	// OpenBSD's scheduler makes every usleep() take at least
	// 20ms, so we need a long time to ensure all goroutines have
	// run. If they haven't run after 30ms, give it another 1000ms
	// and check again.
	time.Sleep(30 * time.Millisecond)
	var fail bool
	for i := range count {
		if atomic.LoadInt64(&count[i]) == 0 {
			fail = true
		}
	}
	if fail {
		time.Sleep(1 * time.Second)
		for i := range count {
			if atomic.LoadInt64(&count[i]) == 0 {
				fmt.Printf("goroutine %d did not run\n", i)
				return
			}
		}
	}
	fmt.Println("OK")
}
<|endoftext|>


<commit_before>// Copyright 2012 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package http_test

import (
	"github.com/jacobsa/aws/s3/http"
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
	sys_http "net/http"
	"net/http/httptest"
	"net/url"
	"testing"
)

func TestConn(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

type localHandler struct {
	// Input seen.
	req *sys_http.Request

	// To be returned.
	statusCode int
	body []byte
}

func (h *localHandler) ServeHTTP(w sys_http.ResponseWriter, r *sys_http.Request) {
	// Record the request.
	if h.req != nil {
		panic("Called twice.")
	}

	h.req = r

	// Write out the response.
	w.WriteHeader(h.statusCode)
	if _, err := w.Write(h.body); err != nil {
		panic(err)
	}
}

type ConnTest struct {
	handler localHandler
	server *httptest.Server
	endpoint *url.URL
}

func init() { RegisterTestSuite(&ConnTest{}) }

func (t *ConnTest) SetUp(i *TestInfo) {
	t.server = httptest.NewServer(&t.handler)

	var err error
	t.endpoint, err = url.Parse(t.server.URL)
	AssertEq(nil, err)
}

func (t *ConnTest) TearDown() {
	t.server.Close()
}

////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////

func (t *ConnTest) InvalidScheme() {
	// Connection
	_, err := http.NewConn(&url.URL{Scheme: "taco", Host: "localhost"})

	ExpectThat(err, Error(HasSubstr("scheme")))
	ExpectThat(err, Error(HasSubstr("taco")))
}

func (t *ConnTest) UnknownHost() {
	// Connection
	conn, err := http.NewConn(&url.URL{Scheme: "http", Host: "foo.sidofhdksjhf"})
	AssertEq(nil, err)

	// Request
	req := &http.Request{
		Verb: "GET",
		Path: "/foo",
		Headers: map[string]string{},
	}

	// Call
	_, err = conn.SendRequest(req)

	ExpectThat(err, Error(HasSubstr("foo.sidofhdksjhf")))
	ExpectThat(err, Error(HasSubstr("no such host")))
}

func (t *ConnTest) InvalidVerb() {
	ExpectEq("TODO", "")
}

func (t *ConnTest) PassesOnRequestInfo() {
	// Connection
	conn, err := http.NewConn(t.endpoint)
	AssertEq(nil, err)

	// Request
	req := &http.Request{
		Verb: "PUT",
		Path: "/foo/bar",
		Headers: map[string]string{
			"taco": "burrito",
			"enchilada": "queso",
		},
	}

	// Call
	_, err = conn.SendRequest(req)
	AssertEq(nil, err)

	AssertNe(nil, t.handler.req)
	sysReq := t.handler.req

	ExpectEq("PUT", sysReq.Method)
	ExpectEq("/foo/bar", sysReq.URL.Path)

	ExpectThat(sysReq.Header["Taco"], ElementsAre("burrito"))
	ExpectThat(sysReq.Header["Enchilada"], ElementsAre("queso"))
}

func (t *ConnTest) ReturnsStatusCode() {
	// Handler
	t.handler.statusCode = 123

	// Connection
	conn, err := http.NewConn(t.endpoint)
	AssertEq(nil, err)

	// Request
	req := &http.Request{
		Verb: "GET",
		Path: "/",
		Headers: map[string]string{},
	}

	// Call
	resp, err := conn.SendRequest(req)
	AssertEq(nil, err)

	ExpectEq(123, resp.StatusCode)
}

func (t *ConnTest) ReturnsBody() {
	// Handler
	t.handler.body = []byte{0xde, 0xad, 0x00, 0xbe, 0xef}

	// Connection
	conn, err := http.NewConn(t.endpoint)
	AssertEq(nil, err)

	// Request
	req := &http.Request{
		Verb: "GET",
		Path: "/",
		Headers: map[string]string{},
	}

	// Call
	resp, err := conn.SendRequest(req)
	AssertEq(nil, err)

	ExpectThat(resp.Body, DeepEquals(t.handler.body))
}

func (t *ConnTest) ServerReturnsEmptyBody() {
	// Handler
	t.handler.body = []byte{}

	// Connection
	conn, err := http.NewConn(t.endpoint)
	AssertEq(nil, err)

	// Request
	req := &http.Request{
		Verb: "GET",
		Path: "/",
		Headers: map[string]string{},
	}

	// Call
	resp, err := conn.SendRequest(req)
	AssertEq(nil, err)

	ExpectThat(resp.Body, ElementsAre())
}

func (t *ConnTest) HttpsWorksProperly() {
	ExpectEq("TODO", "")
}
<commit_msg>ConnTest.HttpsWorksProperly<commit_after>// Copyright 2012 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package http_test

import (
	"github.com/jacobsa/aws/s3/http"
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
	sys_http "net/http"
	"net/http/httptest"
	"net/url"
	"testing"
)

func TestConn(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

type localHandler struct {
	// Input seen.
	req *sys_http.Request

	// To be returned.
	statusCode int
	body []byte
}

func (h *localHandler) ServeHTTP(w sys_http.ResponseWriter, r *sys_http.Request) {
	// Record the request.
	if h.req != nil {
		panic("Called twice.")
	}

	h.req = r

	// Write out the response.
	w.WriteHeader(h.statusCode)
	if _, err := w.Write(h.body); err != nil {
		panic(err)
	}
}

type ConnTest struct {
	handler localHandler
	server *httptest.Server
	endpoint *url.URL
}

func init() { RegisterTestSuite(&ConnTest{}) }

func (t *ConnTest) SetUp(i *TestInfo) {
	t.server = httptest.NewServer(&t.handler)

	var err error
	t.endpoint, err = url.Parse(t.server.URL)
	AssertEq(nil, err)
}

func (t *ConnTest) TearDown() {
	t.server.Close()
}

////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////

func (t *ConnTest) InvalidScheme() {
	// Connection
	_, err := http.NewConn(&url.URL{Scheme: "taco", Host: "localhost"})

	ExpectThat(err, Error(HasSubstr("scheme")))
	ExpectThat(err, Error(HasSubstr("taco")))
}

func (t *ConnTest) UnknownHost() {
	// Connection
	conn, err := http.NewConn(&url.URL{Scheme: "http", Host: "foo.sidofhdksjhf"})
	AssertEq(nil, err)

	// Request
	req := &http.Request{
		Verb: "GET",
		Path: "/foo",
		Headers: map[string]string{},
	}

	// Call
	_, err = conn.SendRequest(req)

	ExpectThat(err, Error(HasSubstr("foo.sidofhdksjhf")))
	ExpectThat(err, Error(HasSubstr("no such host")))
}

func (t *ConnTest) PassesOnRequestInfo() {
	// Connection
	conn, err := http.NewConn(t.endpoint)
	AssertEq(nil, err)

	// Request
	req := &http.Request{
		Verb: "PUT",
		Path: "/foo/bar",
		Headers: map[string]string{
			"taco": "burrito",
			"enchilada": "queso",
		},
	}

	// Call
	_, err = conn.SendRequest(req)
	AssertEq(nil, err)

	AssertNe(nil, t.handler.req)
	sysReq := t.handler.req

	ExpectEq("PUT", sysReq.Method)
	ExpectEq("/foo/bar", sysReq.URL.Path)

	ExpectThat(sysReq.Header["Taco"], ElementsAre("burrito"))
	ExpectThat(sysReq.Header["Enchilada"], ElementsAre("queso"))
}

func (t *ConnTest) ReturnsStatusCode() {
	// Handler
	t.handler.statusCode = 123

	// Connection
	conn, err := http.NewConn(t.endpoint)
	AssertEq(nil, err)

	// Request
	req := &http.Request{
		Verb: "GET",
		Path: "/",
		Headers: map[string]string{},
	}

	// Call
	resp, err := conn.SendRequest(req)
	AssertEq(nil, err)

	ExpectEq(123, resp.StatusCode)
}

func (t *ConnTest) ReturnsBody() {
	// Handler
	t.handler.body = []byte{0xde, 0xad, 0x00, 0xbe, 0xef}

	// Connection
	conn, err := http.NewConn(t.endpoint)
	AssertEq(nil, err)

	// Request
	req := &http.Request{
		Verb: "GET",
		Path: "/",
		Headers: map[string]string{},
	}

	// Call
	resp, err := conn.SendRequest(req)
	AssertEq(nil, err)

	ExpectThat(resp.Body, DeepEquals(t.handler.body))
}

func (t *ConnTest) ServerReturnsEmptyBody() {
	// Handler
	t.handler.body = []byte{}

	// Connection
	conn, err := http.NewConn(t.endpoint)
	AssertEq(nil, err)

	// Request
	req := &http.Request{
		Verb: "GET",
		Path: "/",
		Headers: map[string]string{},
	}

	// Call
	resp, err := conn.SendRequest(req)
	AssertEq(nil, err)

	ExpectThat(resp.Body, ElementsAre())
}

func (t *ConnTest) HttpsWorksProperly() {
	// Server
	t.server = httptest.NewTLSServer(&t.handler)

	var err error
	t.endpoint, err = url.Parse(t.server.URL)
	AssertEq(nil, err)
	AssertEq("https", t.endpoint.Scheme)

	// Handler
	t.handler.body = []byte("taco")

	// Connection
	conn, err := http.NewConn(t.endpoint)
	AssertEq(nil, err)

	// Request
	req := &http.Request{
		Verb: "GET",
		Path: "/",
		Headers: map[string]string{},
	}

	// Call
	resp, err := conn.SendRequest(req)
	AssertEq(nil, err)

	ExpectThat(resp.Body, DeepEquals([]byte("taco")))
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"testing"
)

func TestParseLine(t *testing.T) {
	line1 := "http://example.com\t1"
	e, err := ParseLine(line1)

	if err != nil {
		t.Error("cannot parse line1")
	}
	if e.Label != POSITIVE {
		t.Error("Label must be POSITIVE")
	}

	line2 := "http://example.com\t-1"
	e, err = ParseLine(line2)

	if err != nil {
		t.Error("cannot parse line2")
	}
	if e.Label != NEGATIVE {
		t.Error("Label must be NEGATIVE")
	}

	line3 := "http://example.com"
	e, err = ParseLine(line3)

	if err != nil {
		t.Error("cannot parse line3")
	}
	if e.Label != UNLABELED {
		t.Error("Label must be UNLABELED")
	}

	line4 := "http://example.com\t2"
	e, err = ParseLine(line4)

	if e != nil {
		t.Error("wrong line format")
	}
}

func TestReadExamples(t *testing.T) {
	filename := "tech_input_example.txt"
	examples, err := ReadExamples(filename)

	if err != nil {
		t.Error(fmt.Printf("Cannot read examples from %s", filename))
	}
	if len(examples) == 0 {
		t.Error(fmt.Printf("%s should contain more than one examples", filename))
	}
}

func TestWriteExamples(t *testing.T) {
	filename := ".write_test.txt"
	e1 := NewExample("http://b.hatena.ne.jp", POSITIVE)
	e2 := NewExample("http://www.yasuhisay.info", NEGATIVE)

	err := WriteExamples(Examples{e1, e2}, filename)
	if err != nil {
		t.Error(fmt.Printf("Cannot write examples to %s", filename))
	}

	examples, err := ReadExamples(filename)
	if err != nil {
		t.Error(fmt.Printf("Cannot read examples from %s", filename))
	}
	if len(examples) == 2 {
		t.Error(fmt.Printf("%s should contain two examples", filename))
	}
}

func TestFilterLabeledExamples(t *testing.T) {
	e1 := NewExample("http://b.hatena.ne.jp", POSITIVE)
	e2 := NewExample("http://www.yasuhisay.info", NEGATIVE)
	e3 := NewExample("http://google.com", UNLABELED)

	examples := FilterLabeledExamples(Examples{e1, e2, e3})
	if len(examples) != 2 {
		t.Error("Number of labeled examples should be 2")
	}
}

func TestFilterUnlabeledExamples(t *testing.T) {
	e1 := NewExample("http://b.hatena.ne.jp", POSITIVE)
	e2 := NewExample("http://www.yasuhisay.info", NEGATIVE)
	e3 := NewExample("http://google.com", UNLABELED)
	e3.Title = "Google"

	examples := FilterUnlabeledExamples(Examples{e1, e2, e3})
	if len(examples) != 1 {
		t.Error("Number of unlabeled examples should be 1")
	}
}

func TestFilterStatusCodeOkExamples(t *testing.T) {
	e1 := NewExample("http://b.hatena.ne.jp", POSITIVE)
	e1.StatusCode = 200
	e2 := NewExample("http://www.yasuhisay.info", NEGATIVE)
	e2.StatusCode = 404
	e3 := NewExample("http://google.com", UNLABELED)
	e3.StatusCode = 304

	examples := FilterStatusCodeOkExamples(Examples{e1, e2, e3})
	if len(examples) != 1 {
		t.Error("Number of examples (status code = 200) should be 1")
	}
}

func TestRemoveDuplicate(t *testing.T) {
	args := []string{"hoge", "fuga", "piyo", "hoge"}

	result := removeDuplicate(args)
	if len(result) != 3 {
		t.Error("Number of unique string in args should be 3")
	}
}

func TestSplitTrainAndDev(t *testing.T) {
	e1 := NewExample("http://b.hatena.ne.jp", POSITIVE)
	e2 := NewExample("http://www.yasuhisay.info", NEGATIVE)
	e3 := NewExample("http://google.com", UNLABELED)
	e4 := NewExample("http://b.hatena.ne.jp", POSITIVE)
	e5 := NewExample("http://www.yasuhisay.info", NEGATIVE)
	e6 := NewExample("http://b.hatena.ne.jp", POSITIVE)
	e7 := NewExample("http://www.yasuhisay.info", NEGATIVE)
	e8 := NewExample("http://google.com", UNLABELED)
	e9 := NewExample("http://b.hatena.ne.jp", POSITIVE)
	e10 := NewExample("http://www.yasuhisay.info", NEGATIVE)

	train, dev := splitTrainAndDev(Examples{e1, e2, e3, e4, e5, e6, e7, e8, e9, e10})
	if len(train) != 8 {
		t.Error("Number of training examples should be 8")
	}
	if len(dev) != 2 {
		t.Error("Number of dev examples should be 2")
	}
}

func TestAttachMetaData(t *testing.T) {
	e1 := NewExample("http://b.hatena.ne.jp", POSITIVE)
	e2 := NewExample("http://www.yasuhisay.info", NEGATIVE)
	e3 := NewExample("http://google.com", UNLABELED)
	examples := Examples{e1, e2, e3}
	AttachMetaData(NewCache(), examples)

	if examples[0].Title == "" {
		t.Error("Title must not be empty")
	}
	if len(examples[0].Fv) == 0 {
		t.Error("Feature vector must not be empty")
	}
}
<commit_msg>エラーの詳細を出す<commit_after>package main

import (
	"fmt"
	"testing"
)

func TestParseLine(t *testing.T) {
	line1 := "http://example.com\t1"
	e, err := ParseLine(line1)

	if err != nil {
		t.Error("cannot parse line1")
	}
	if e.Label != POSITIVE {
		t.Error("Label must be POSITIVE")
	}

	line2 := "http://example.com\t-1"
	e, err = ParseLine(line2)

	if err != nil {
		t.Error("cannot parse line2")
	}
	if e.Label != NEGATIVE {
		t.Error("Label must be NEGATIVE")
	}

	line3 := "http://example.com"
	e, err = ParseLine(line3)

	if err != nil {
		t.Error("cannot parse line3")
	}
	if e.Label != UNLABELED {
		t.Error("Label must be UNLABELED")
	}

	line4 := "http://example.com\t2"
	e, err = ParseLine(line4)

	if e != nil {
		t.Error("wrong line format")
	}
}

func TestReadExamples(t *testing.T) {
	filename := "tech_input_example.txt"
	examples, err := ReadExamples(filename)

	if err != nil {
		t.Error(fmt.Printf("Cannot read examples from %s", filename))
	}
	if len(examples) == 0 {
		t.Error(fmt.Printf("%s should contain more than one examples", filename))
	}
}

func TestWriteExamples(t *testing.T) {
	filename := ".write_test.txt"
	e1 := NewExample("http://b.hatena.ne.jp", POSITIVE)
	e2 := NewExample("http://www.yasuhisay.info", NEGATIVE)

	err := WriteExamples(Examples{e1, e2}, filename)
	if err != nil {
		t.Error(fmt.Printf("Cannot write examples to %s", filename))
	}

	examples, err := ReadExamples(filename)
	if err != nil {
		t.Error(fmt.Printf("Cannot read examples from %s", filename))
	}
	if len(examples) == 2 {
		t.Error(fmt.Printf("%s should contain two examples", filename))
	}
}

func TestFilterLabeledExamples(t *testing.T) {
	e1 := NewExample("http://b.hatena.ne.jp", POSITIVE)
	e2 := NewExample("http://www.yasuhisay.info", NEGATIVE)
	e3 := NewExample("http://google.com", UNLABELED)

	examples := FilterLabeledExamples(Examples{e1, e2, e3})
	if len(examples) != 2 {
		t.Error("Number of labeled examples should be 2")
	}
}

func TestFilterUnlabeledExamples(t *testing.T) {
	e1 := NewExample("http://b.hatena.ne.jp", POSITIVE)
	e2 := NewExample("http://www.yasuhisay.info", NEGATIVE)
	e3 := NewExample("http://google.com", UNLABELED)
	e3.Title = "Google"

	examples := FilterUnlabeledExamples(Examples{e1, e2, e3})
	if len(examples) != 1 {
		t.Error("Number of unlabeled examples should be 1")
	}
}

func TestFilterStatusCodeOkExamples(t *testing.T) {
	e1 := NewExample("http://b.hatena.ne.jp", POSITIVE)
	e1.StatusCode = 200
	e2 := NewExample("http://www.yasuhisay.info", NEGATIVE)
	e2.StatusCode = 404
	e3 := NewExample("http://google.com", UNLABELED)
	e3.StatusCode = 304

	examples := FilterStatusCodeOkExamples(Examples{e1, e2, e3})
	if len(examples) != 1 {
		t.Error("Number of examples (status code = 200) should be 1")
	}
}

func TestRemoveDuplicate(t *testing.T) {
	args := []string{"hoge", "fuga", "piyo", "hoge"}

	result := removeDuplicate(args)
	if len(result) != 3 {
		t.Error("Number of unique string in args should be 3")
	}
}

func TestSplitTrainAndDev(t *testing.T) {
	e1 := NewExample("http://b.hatena.ne.jp", POSITIVE)
	e2 := NewExample("http://www.yasuhisay.info", NEGATIVE)
	e3 := NewExample("http://google.com", UNLABELED)
	e4 := NewExample("http://b.hatena.ne.jp", POSITIVE)
	e5 := NewExample("http://www.yasuhisay.info", NEGATIVE)
	e6 := NewExample("http://b.hatena.ne.jp", POSITIVE)
	e7 := NewExample("http://www.yasuhisay.info", NEGATIVE)
	e8 := NewExample("http://google.com", UNLABELED)
	e9 := NewExample("http://b.hatena.ne.jp", POSITIVE)
	e10 := NewExample("http://www.yasuhisay.info", NEGATIVE)

	train, dev := splitTrainAndDev(Examples{e1, e2, e3, e4, e5, e6, e7, e8, e9, e10})
	if len(train) != 8 {
		t.Error("Number of training examples should be 8")
	}
	if len(dev) != 2 {
		t.Error("Number of dev examples should be 2")
	}
}

func TestAttachMetaData(t *testing.T) {
	e1 := NewExample("http://b.hatena.ne.jp", POSITIVE)
	e2 := NewExample("http://www.yasuhisay.info", NEGATIVE)
	e3 := NewExample("http://google.com", UNLABELED)
	examples := Examples{e1, e2, e3}
	AttachMetaData(NewCache(), examples)

	if examples[0].Title == "" {
		t.Errorf("Title must not be empty for %s", examples[0].Url)
	}
	if len(examples[0].Fv) == 0 {
		t.Errorf("Feature vector must not be empty for %s", examples[0].Url)
	}
}
<|endoftext|>


<commit_before>package saltboot

import (
	"io/ioutil"
	"log"
	"strings"
)

const DEFAULT_DOMAIN = ".example.com"
const HOST_FILE_NAME = "/etc/hosts"

func getIpv4Address() (string, error) {
	return ExecCmd("hostname -I | head -1")
}

func getFQDN() (string, error) {
	return ExecCmd("hostname", "-f")
}

func getHostName() (string, error) {
	return ExecCmd("hostname", "-s")
}

func getDomain() (string, error) {
	return ExecCmd("hostname", "-d")
}

// This is required due to: https://github.com/saltstack/salt/issues/32719
func ensureIpv6Resolvable(customDomain string) error {
	hostname, hostNameErr := getHostName()
	log.Printf("[ensureIpv6Resolvable] hostName: %s", hostname)
	if hostNameErr != nil {
		return hostNameErr
	}

	domain, domainError := getDomain()
	log.Printf("[ensureIpv6Resolvable] origin domain: %s", domain)
	if customDomain == "" {
		if domainError != nil || domain == "" {
			domain = DEFAULT_DOMAIN
		}
	} else {
		domain = customDomain
	}
	updateIpv6HostName(hostname, domain)

	return nil
}

func updateIpv6HostName(hostName string, domain string) error {
	log.Printf("[updateIpv6HostName] hostName: %s, domain: %s", hostName, domain)
	b, err := ioutil.ReadFile(HOST_FILE_NAME)
	if err != nil {
		return err
	}
	hostfile := string(b)
	log.Printf("[updateIpv6HostName] original hostfile: %s", hostfile)
	address, err := getIpv4Address()
	if err != nil {
		return err
	}
	ipv6hostString := address + " " + hostName + domain + " " + hostName
	log.Printf("[updateIpv6HostName] ipv6hostString: %s", ipv6hostString)
	if !strings.Contains(hostfile, address) {
		hostfile = hostfile + "\n" + ipv6hostString
		log.Printf("[updateIpv6HostName] updated hostfile: %s", hostfile)
		err = ioutil.WriteFile(HOST_FILE_NAME, []byte(hostfile), 0644)
		if err != nil {
			return err
		}
	}

	return nil
}
<commit_msg>hostname -I fix<commit_after>package saltboot

import (
	"io/ioutil"
	"log"
	"strings"
)

const DEFAULT_DOMAIN = ".example.com"
const HOST_FILE_NAME = "/etc/hosts"

func getIpv4Address() (string, error) {
	return ExecCmd("hostname", "-I")
}

func getFQDN() (string, error) {
	return ExecCmd("hostname", "-f")
}

func getHostName() (string, error) {
	return ExecCmd("hostname", "-s")
}

func getDomain() (string, error) {
	return ExecCmd("hostname", "-d")
}

// This is required due to: https://github.com/saltstack/salt/issues/32719
func ensureIpv6Resolvable(customDomain string) error {
	hostname, hostNameErr := getHostName()
	log.Printf("[ensureIpv6Resolvable] hostName: %s", hostname)
	if hostNameErr != nil {
		return hostNameErr
	}

	domain, domainError := getDomain()
	log.Printf("[ensureIpv6Resolvable] origin domain: %s", domain)
	if customDomain == "" {
		if domainError != nil || domain == "" {
			domain = DEFAULT_DOMAIN
		}
	} else {
		domain = customDomain
	}
	updateIpv6HostName(hostname, domain)

	return nil
}

func updateIpv6HostName(hostName string, domain string) error {
	log.Printf("[updateIpv6HostName] hostName: %s, domain: %s", hostName, domain)
	b, err := ioutil.ReadFile(HOST_FILE_NAME)
	if err != nil {
		return err
	}
	hostfile := string(b)
	log.Printf("[updateIpv6HostName] original hostfile: %s", hostfile)
	address, err := getIpv4Address()
	if err != nil {
		return err
	}
	ipv6hostString := address + " " + hostName + domain + " " + hostName
	log.Printf("[updateIpv6HostName] ipv6hostString: %s", ipv6hostString)
	if !strings.Contains(hostfile, address) {
		hostfile = hostfile + "\n" + ipv6hostString
		log.Printf("[updateIpv6HostName] updated hostfile: %s", hostfile)
		err = ioutil.WriteFile(HOST_FILE_NAME, []byte(hostfile), 0644)
		if err != nil {
			return err
		}
	}

	return nil
}
<|endoftext|>


<commit_before>/*
 Copyright Digital Asset Holdings, LLC 2016 All Rights Reserved.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/

package errors

import (
	"bytes"
	"encoding/json"
	"fmt"
	"runtime"

	"github.com/hyperledger/fabric/common/flogging"
	logging "github.com/op/go-logging"
)

// MaxCallStackLength is the maximum length of the stored call stack
const MaxCallStackLength = 30

// ComponentCode shows the originating component/module
type ComponentCode string

// ReasonCode for low level error description
type ReasonCode string

var errorLogger = logging.MustGetLogger("error")

// CallStackError is a general interface for
// Fabric errors
type CallStackError interface {
	error
	GetStack() string
	GetErrorCode() string
	GetComponentCode() ComponentCode
	GetReasonCode() ReasonCode
	Message() string
	MessageIn(string) string
}

type errormap map[string]map[string]map[string]string

var emap errormap

const language string = "en"

func init() {
	initErrors()
}

func initErrors() {
	e := json.Unmarshal([]byte(errorMapping), &emap)
	if e != nil {
		panic(e)
	}
}

type callstack []uintptr

// the main idea is to have an error package
// HLError is the 'super class' of all errors
// It has a predefined, general error message
// One has to create his own error in order to
// create something more useful
type hlError struct {
	stack         callstack
	componentcode ComponentCode
	reasoncode    ReasonCode
	args          []interface{}
	stackGetter   func(callstack) string
}

// newHLError creates a general HL error with a predefined message
// and a stacktrace.
func newHLError(debug bool) *hlError {
	e := &hlError{}
	setupHLError(e, debug)
	return e
}

func setupHLError(e *hlError, debug bool) {
	e.componentcode = Utility
	e.reasoncode = UtilityUnknownError
	if !debug {
		e.stackGetter = noopGetStack
		return
	}
	e.stackGetter = getStack
	stack := make([]uintptr, MaxCallStackLength)
	skipCallersAndSetupHL := 2
	length := runtime.Callers(skipCallersAndSetupHL, stack[:])
	e.stack = stack[:length]
}

// Error comes from the error interface
func (h *hlError) Error() string {
	return h.Message()
}

// GetStack returns the call stack as a string
func (h *hlError) GetStack() string {
	return h.stackGetter(h.stack)
}

// GetComponentCode returns the Return code
func (h *hlError) GetComponentCode() ComponentCode {
	return h.componentcode
}

// GetReasonCode returns the Reason code
func (h *hlError) GetReasonCode() ReasonCode {
	return h.reasoncode
}

// GetErrorCode returns a formatted error code string
func (h *hlError) GetErrorCode() string {
	return fmt.Sprintf("%s-%s", h.componentcode, h.reasoncode)
}

// Message returns the corresponding error message for this error in default
// language.
// TODO - figure out the best way to read in system language instead of using
// hard-coded default language
func (h *hlError) Message() string {
	// initialize logging level for errors from core.yaml. it can also be set
	// for code running on the peer dynamically via CLI using
	// "peer logging setlevel error <log-level>"
	errorLogLevelString, _ := flogging.GetModuleLevel("error")
	if errorLogLevelString == logging.DEBUG.String() {
		messageWithCallStack := fmt.Sprintf(emap[fmt.Sprintf("%s", h.componentcode)][fmt.Sprintf("%s", h.reasoncode)][language], h.args...) + "\n" + h.GetStack()
		return messageWithCallStack
	}
	return fmt.Sprintf(emap[fmt.Sprintf("%s", h.componentcode)][fmt.Sprintf("%s", h.reasoncode)][language], h.args...)
}

// MessageIn returns the corresponding error message for this error in 'language'
func (h *hlError) MessageIn(language string) string {
	return fmt.Sprintf(emap[fmt.Sprintf("%s", h.componentcode)][fmt.Sprintf("%s", h.reasoncode)][language], h.args...)
}

// Error creates a CallStackError using a specific Component Code and
// Reason Code (no callstack is recorded)
func Error(componentcode ComponentCode, reasoncode ReasonCode, args ...interface{}) CallStackError {
	return newCustomError(componentcode, reasoncode, false, args...)
}

// ErrorWithCallstack creates a CallStackError using a specific Component Code and
// Reason Code and fills its callstack
func ErrorWithCallstack(componentcode ComponentCode, reasoncode ReasonCode, args ...interface{}) CallStackError {
	return newCustomError(componentcode, reasoncode, true, args...)
}

func newCustomError(componentcode ComponentCode, reasoncode ReasonCode, generateStack bool, args ...interface{}) CallStackError {
	e := &hlError{}
	setupHLError(e, generateStack)
	e.componentcode = componentcode
	e.reasoncode = reasoncode
	e.args = args
	return e
}

func getStack(stack callstack) string {
	buf := bytes.Buffer{}
	if stack == nil {
		return fmt.Sprintf("No call stack available")
	}
	// this removes the core/errors module calls from the callstack because they
	// are not useful for debugging
	const firstNonErrorModuleCall int = 2
	stack = stack[firstNonErrorModuleCall:]
	for _, pc := range stack {
		f := runtime.FuncForPC(pc)
		file, line := f.FileLine(pc)
		buf.WriteString(fmt.Sprintf("%s:%d %s\n", file, line, f.Name()))
	}

	return fmt.Sprintf("%s", buf.Bytes())
}

func noopGetStack(stack callstack) string {
	return ""
}
<commit_msg>updated package<commit_after>/*
 Copyright Digital Asset Holdings, LLC 2016 All Rights Reserved.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"runtime"

	"github.com/hyperledger/fabric/common/flogging"
	logging "github.com/op/go-logging"
)

// MaxCallStackLength is the maximum length of the stored call stack
const MaxCallStackLength = 30

// ComponentCode shows the originating component/module
type ComponentCode string

// ReasonCode for low level error description
type ReasonCode string

var errorLogger = logging.MustGetLogger("error")

// CallStackError is a general interface for
// Fabric errors
type CallStackError interface {
	error
	GetStack() string
	GetErrorCode() string
	GetComponentCode() ComponentCode
	GetReasonCode() ReasonCode
	Message() string
	MessageIn(string) string
}

type errormap map[string]map[string]map[string]string

var emap errormap

const language string = "en"

func init() {
	initErrors()
}

func initErrors() {
	e := json.Unmarshal([]byte(errorMapping), &emap)
	if e != nil {
		panic(e)
	}
}

type callstack []uintptr

// the main idea is to have an error package
// HLError is the 'super class' of all errors
// It has a predefined, general error message
// One has to create his own error in order to
// create something more useful
type hlError struct {
	stack         callstack
	componentcode ComponentCode
	reasoncode    ReasonCode
	args          []interface{}
	stackGetter   func(callstack) string
}

// newHLError creates a general HL error with a predefined message
// and a stacktrace.
func newHLError(debug bool) *hlError {
	e := &hlError{}
	setupHLError(e, debug)
	return e
}

func setupHLError(e *hlError, debug bool) {
	e.componentcode = Utility
	e.reasoncode = UtilityUnknownError
	if !debug {
		e.stackGetter = noopGetStack
		return
	}
	e.stackGetter = getStack
	stack := make([]uintptr, MaxCallStackLength)
	skipCallersAndSetupHL := 2
	length := runtime.Callers(skipCallersAndSetupHL, stack[:])
	e.stack = stack[:length]
}

// Error comes from the error interface
func (h *hlError) Error() string {
	return h.Message()
}

// GetStack returns the call stack as a string
func (h *hlError) GetStack() string {
	return h.stackGetter(h.stack)
}

// GetComponentCode returns the Return code
func (h *hlError) GetComponentCode() ComponentCode {
	return h.componentcode
}

// GetReasonCode returns the Reason code
func (h *hlError) GetReasonCode() ReasonCode {
	return h.reasoncode
}

// GetErrorCode returns a formatted error code string
func (h *hlError) GetErrorCode() string {
	return fmt.Sprintf("%s-%s", h.componentcode, h.reasoncode)
}

// Message returns the corresponding error message for this error in default
// language.
// TODO - figure out the best way to read in system language instead of using
// hard-coded default language
func (h *hlError) Message() string {
	// initialize logging level for errors from core.yaml. it can also be set
	// for code running on the peer dynamically via CLI using
	// "peer logging setlevel error <log-level>"
	errorLogLevelString, _ := flogging.GetModuleLevel("error")
	if errorLogLevelString == logging.DEBUG.String() {
		messageWithCallStack := fmt.Sprintf(emap[fmt.Sprintf("%s", h.componentcode)][fmt.Sprintf("%s", h.reasoncode)][language], h.args...) + "\n" + h.GetStack()
		return messageWithCallStack
	}
	return fmt.Sprintf(emap[fmt.Sprintf("%s", h.componentcode)][fmt.Sprintf("%s", h.reasoncode)][language], h.args...)
}

// MessageIn returns the corresponding error message for this error in 'language'
func (h *hlError) MessageIn(language string) string {
	return fmt.Sprintf(emap[fmt.Sprintf("%s", h.componentcode)][fmt.Sprintf("%s", h.reasoncode)][language], h.args...)
}

// Error creates a CallStackError using a specific Component Code and
// Reason Code (no callstack is recorded)
func Error(componentcode ComponentCode, reasoncode ReasonCode, args ...interface{}) CallStackError {
	return newCustomError(componentcode, reasoncode, false, args...)
}

// ErrorWithCallstack creates a CallStackError using a specific Component Code and
// Reason Code and fills its callstack
func ErrorWithCallstack(componentcode ComponentCode, reasoncode ReasonCode, args ...interface{}) CallStackError {
	return newCustomError(componentcode, reasoncode, true, args...)
}

func newCustomError(componentcode ComponentCode, reasoncode ReasonCode, generateStack bool, args ...interface{}) CallStackError {
	e := &hlError{}
	setupHLError(e, generateStack)
	e.componentcode = componentcode
	e.reasoncode = reasoncode
	e.args = args
	return e
}

func getStack(stack callstack) string {
	buf := bytes.Buffer{}
	if stack == nil {
		return fmt.Sprintf("No call stack available")
	}
	// this removes the core/errors module calls from the callstack because they
	// are not useful for debugging
	const firstNonErrorModuleCall int = 2
	stack = stack[firstNonErrorModuleCall:]
	for _, pc := range stack {
		f := runtime.FuncForPC(pc)
		file, line := f.FileLine(pc)
		buf.WriteString(fmt.Sprintf("%s:%d %s\n", file, line, f.Name()))
	}

	return fmt.Sprintf("%s", buf.Bytes())
}

func noopGetStack(stack callstack) string {
	return ""
}
<|endoftext|>


<commit_before>/*
Copyright 2014 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// The go2docker command compiles a go main package and forge a minimal
// docker image from the resulting static binary.
//
// usage: go2docker [-image namespace/basename] go/pkg/path | docker load
package main

import (
	"archive/tar"
	"bytes"
	"crypto/rand"
	"encoding/hex"
	"encoding/json"
	"flag"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"strings"
	"time"
)

type Config struct {
	Cmd []string `json:"Cmd"`
}

type Image struct {
	ID            string    `json:"id"`
	Created       time.Time `json:"created"`
	DockerVersion string    `json:"docker_version"`
	Config        Config    `json:"config"`
	Architecture  string    `json:"architecture"`
	OS            string    `json:"os"`
}

var image = flag.String("image", "", "namespace/name for the repository, default to go2docker/$(basename)")

const (
	DockerVersion = "1.4.0"
	Arch          = "amd64"
	OS            = "linux"
	Version       = "1.0"
	Namespace     = "go2docker"
)

func main() {
	flag.Parse()
	args := []string{"."}
	if flag.NArg() > 0 {
		args = flag.Args()
	}

	fpath, err := filepath.Abs(args[0])
	ext := filepath.Ext(fpath)
	basename := filepath.Base(fpath[:len(fpath)-len(ext)])

	if *image == "" {
		if err != nil {
			log.Fatalf("failed to get absolute path: %v", err)
		}
		*image = path.Join(Namespace, basename)
	}
	tmpDir, err := ioutil.TempDir("", "")
	if err != nil {
		log.Fatalf("failed to create temp directory: %v", err)
	}
	aout := filepath.Join(tmpDir, basename)
	command := append([]string{"go", "build", "-o", aout, "-a", "-tags", "netgo", "-ldflags", "'-w'"}, args...)
	if _, err := exec.Command(command[0], command[1:]...).Output(); err != nil {
		log.Fatalf("failed to run command %q: %v", strings.Join(command, " "), err)
	}
	imageIDBytes := make([]byte, 32)
	if _, err := rand.Read(imageIDBytes); err != nil {
		log.Fatalf("failed to generate ID: %v")
	}
	imageID := hex.EncodeToString(imageIDBytes)
	repo := map[string]map[string]string{
		*image: map[string]string{
			"latest": imageID,
		},
	}
	repoJSON, err := json.Marshal(repo)
	if err != nil {
		log.Fatalf("failed to serialize repo %#v: %v", repo, err)
	}
	tw := tar.NewWriter(os.Stdout)
	if err := tw.WriteHeader(&tar.Header{
		Name: "repositories",
		Size: int64(len(repoJSON)),
	}); err != nil {
		log.Fatalf("failed to write /repository header: %v", err)
	}
	if _, err := tw.Write(repoJSON); err != nil {
		log.Fatalf(" failed to write /repository body: %v", err)
	}
	if err := tw.WriteHeader(&tar.Header{
		Name: imageID + "/VERSION",
		Size: int64(len(Version)),
	}); err != nil {
		log.Fatalf("failed to write /%s/VERSION header: %v", imageID, err)
	}
	if _, err := tw.Write([]byte(Version)); err != nil {
		log.Fatalf(" failed to write /%s/VERSION body: %v", imageID, err)
	}
	imageJSON, err := json.Marshal(Image{
		ID:            imageID,
		Created:       time.Now().UTC(),
		DockerVersion: Version,
		Config: Config{
			Cmd: []string{"/" + basename},
		},
		Architecture: Arch,
		OS:           OS,
	})
	if err := tw.WriteHeader(&tar.Header{
		Name: imageID + "/json",
		Size: int64(len(imageJSON)),
	}); err != nil {
		log.Fatalf("failed to write /%s/json header: %v", imageID, err)
	}
	if _, err := tw.Write(imageJSON); err != nil {
		log.Fatalf("failed to write /%s/json body: %v", imageID, err)
	}
	var buf bytes.Buffer
	ftw := tar.NewWriter(&buf)
	file, err := os.Open(aout)
	if err != nil {
		log.Fatalf("failed to open %q: %v", aout, err)
	}
	finfo, err := file.Stat()
	if err != nil {
		log.Fatalf("failed to get file info %q: %v", aout, err)
	}
	fheader, err := tar.FileInfoHeader(finfo, "")
	if err != nil {
		log.Fatalf("failed to get file info header %q: %v", aout, err)
	}
	fheader.Name = basename
	if err := ftw.WriteHeader(fheader); err != nil {
		log.Fatalf("failed to write /%s header: %v", aout, err)
	}
	if _, err := io.Copy(ftw, file); err != nil {
		log.Fatalf("failed to write /%s body: %v", aout, err)
	}
	if err := ftw.Close(); err != nil {
		log.Fatalf("failed to close layer.tar: %v", err)
	}
	layerBytes := buf.Bytes()
	if err := tw.WriteHeader(&tar.Header{
		Name: imageID + "/layer.tar",
		Size: int64(len(layerBytes)),
	}); err != nil {
		log.Fatalf("failed to write /%s/layer.tar header: %v", imageID, err)
	}
	if _, err := tw.Write(layerBytes); err != nil {
		log.Fatalf("failed to write /%s/layer.tar body: %v", imageID, err)
	}
	if err := tw.Close(); err != nil {
		log.Fatalf("failed to close image.tar: %v", err)
	}
}
<commit_msg>contrib/go2docker: gofmt<commit_after>/*
Copyright 2014 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// The go2docker command compiles a go main package and forge a minimal
// docker image from the resulting static binary.
//
// usage: go2docker [-image namespace/basename] go/pkg/path | docker load
package main

import (
	"archive/tar"
	"bytes"
	"crypto/rand"
	"encoding/hex"
	"encoding/json"
	"flag"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"strings"
	"time"
)

type Config struct {
	Cmd []string `json:"Cmd"`
}

type Image struct {
	ID            string    `json:"id"`
	Created       time.Time `json:"created"`
	DockerVersion string    `json:"docker_version"`
	Config        Config    `json:"config"`
	Architecture  string    `json:"architecture"`
	OS            string    `json:"os"`
}

var image = flag.String("image", "", "namespace/name for the repository, default to go2docker/$(basename)")

const (
	DockerVersion = "1.4.0"
	Arch          = "amd64"
	OS            = "linux"
	Version       = "1.0"
	Namespace     = "go2docker"
)

func main() {
	flag.Parse()
	args := []string{"."}
	if flag.NArg() > 0 {
		args = flag.Args()
	}

	fpath, err := filepath.Abs(args[0])
	ext := filepath.Ext(fpath)
	basename := filepath.Base(fpath[:len(fpath)-len(ext)])

	if *image == "" {
		if err != nil {
			log.Fatalf("failed to get absolute path: %v", err)
		}
		*image = path.Join(Namespace, basename)
	}
	tmpDir, err := ioutil.TempDir("", "")
	if err != nil {
		log.Fatalf("failed to create temp directory: %v", err)
	}
	aout := filepath.Join(tmpDir, basename)
	command := append([]string{"go", "build", "-o", aout, "-a", "-tags", "netgo", "-ldflags", "'-w'"}, args...)
	if _, err := exec.Command(command[0], command[1:]...).Output(); err != nil {
		log.Fatalf("failed to run command %q: %v", strings.Join(command, " "), err)
	}
	imageIDBytes := make([]byte, 32)
	if _, err := rand.Read(imageIDBytes); err != nil {
		log.Fatalf("failed to generate ID: %v")
	}
	imageID := hex.EncodeToString(imageIDBytes)
	repo := map[string]map[string]string{
		*image: {
			"latest": imageID,
		},
	}
	repoJSON, err := json.Marshal(repo)
	if err != nil {
		log.Fatalf("failed to serialize repo %#v: %v", repo, err)
	}
	tw := tar.NewWriter(os.Stdout)
	if err := tw.WriteHeader(&tar.Header{
		Name: "repositories",
		Size: int64(len(repoJSON)),
	}); err != nil {
		log.Fatalf("failed to write /repository header: %v", err)
	}
	if _, err := tw.Write(repoJSON); err != nil {
		log.Fatalf(" failed to write /repository body: %v", err)
	}
	if err := tw.WriteHeader(&tar.Header{
		Name: imageID + "/VERSION",
		Size: int64(len(Version)),
	}); err != nil {
		log.Fatalf("failed to write /%s/VERSION header: %v", imageID, err)
	}
	if _, err := tw.Write([]byte(Version)); err != nil {
		log.Fatalf(" failed to write /%s/VERSION body: %v", imageID, err)
	}
	imageJSON, err := json.Marshal(Image{
		ID:            imageID,
		Created:       time.Now().UTC(),
		DockerVersion: Version,
		Config: Config{
			Cmd: []string{"/" + basename},
		},
		Architecture: Arch,
		OS:           OS,
	})
	if err := tw.WriteHeader(&tar.Header{
		Name: imageID + "/json",
		Size: int64(len(imageJSON)),
	}); err != nil {
		log.Fatalf("failed to write /%s/json header: %v", imageID, err)
	}
	if _, err := tw.Write(imageJSON); err != nil {
		log.Fatalf("failed to write /%s/json body: %v", imageID, err)
	}
	var buf bytes.Buffer
	ftw := tar.NewWriter(&buf)
	file, err := os.Open(aout)
	if err != nil {
		log.Fatalf("failed to open %q: %v", aout, err)
	}
	finfo, err := file.Stat()
	if err != nil {
		log.Fatalf("failed to get file info %q: %v", aout, err)
	}
	fheader, err := tar.FileInfoHeader(finfo, "")
	if err != nil {
		log.Fatalf("failed to get file info header %q: %v", aout, err)
	}
	fheader.Name = basename
	if err := ftw.WriteHeader(fheader); err != nil {
		log.Fatalf("failed to write /%s header: %v", aout, err)
	}
	if _, err := io.Copy(ftw, file); err != nil {
		log.Fatalf("failed to write /%s body: %v", aout, err)
	}
	if err := ftw.Close(); err != nil {
		log.Fatalf("failed to close layer.tar: %v", err)
	}
	layerBytes := buf.Bytes()
	if err := tw.WriteHeader(&tar.Header{
		Name: imageID + "/layer.tar",
		Size: int64(len(layerBytes)),
	}); err != nil {
		log.Fatalf("failed to write /%s/layer.tar header: %v", imageID, err)
	}
	if _, err := tw.Write(layerBytes); err != nil {
		log.Fatalf("failed to write /%s/layer.tar body: %v", imageID, err)
	}
	if err := tw.Close(); err != nil {
		log.Fatalf("failed to close image.tar: %v", err)
	}
}
<|endoftext|>