<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"github.com/HewlettPackard/oneview-golang/i3s"
	"github.com/HewlettPackard/oneview-golang/ov"
	"github.com/HewlettPackard/oneview-golang/utils"
	"io/ioutil"
	"os"
)

func main() {
	var (
		clientOV             *ov.OVClient
		i3sClient            *i3s.I3SClient
		endpoint             = os.Getenv("ONEVIEW_OV_ENDPOINT")
		i3sc_endpoint        = os.Getenv("ONEVIEW_I3S_ENDPOINT")
		username             = os.Getenv("ONEVIEW_OV_USER")
		password             = os.Getenv("ONEVIEW_OV_PASSWORD")
		domain               = os.Getenv("ONEVIEW_OV_DOMAIN")
		api_version          = 1600
		deployment_plan_name = "DemoDeploymentPlan"
		new_name             = "RenamedDeploymentPlan"
	)
	ovc := clientOV.NewOVClient(
		username,
		password,
		domain,
		endpoint,
		false,
		api_version,
		"*")
	ovc.RefreshLogin()
	i3sc := i3sClient.NewI3SClient(i3sc_endpoint, false, api_version, ovc.APIKey)

	customAttributes := new([]i3s.CustomAttribute)
	var ca1, ca5, ca6, ca7, ca8, ca9  i3s.CustomAttribute

	ca1.Constraints = "{\"options\":[\"enabled\",\"disabled\"]}"
	ca1.Editable = true
	ca1.ID = "9303c168-3e23-4025-9e63-2bddd644b461"
	ca1.Name = "SSH"
	ca1.Type = "option"
	ca1.Value = "enabled"
	ca1.Visible = true
	*customAttributes = append(*customAttributes, ca1)

	ca5.Constraints = "{\"helpText\":\"\"}"
	ca5.Editable = true
	ca5.ID = "4c7c8229-1dc6-4656-857d-3392a26585ee"
	ca5.Name = "DomainName"
	ca5.Type = "string"
	ca5.Visible = true
	*customAttributes = append(*customAttributes, ca5)

	ca7.Constraints = "{\"helpText\":\"\"}"
	ca7.Editable = true
	ca7.ID = "3c7c8229-1dc6-4656-857d-3392a26585ee"
	ca7.Name = "Hostname"
	ca7.Type = "string"
	ca7.Visible = true
	*customAttributes = append(*customAttributes, ca7)

	ca8.Constraints = "{\"ipv4static\":true,\"ipv4dhcp\":true,\"ipv4disable\":false,\"parameters\":[\"dns1\",\"dns2\",\"gateway\",\"ipaddress\",\"mac\",\"netmask\",\"vlanid\"]}"
	ca8.Editable = true
	ca8.ID = "ec1d95d0-690a-482b-8efd-53bec6e9bfce"
	ca8.Name = "ManagementNIC"
	ca8.Type = "nic"
	ca8.Visible = true
	*customAttributes = append(*customAttributes, ca8)

	ca6.Constraints = "{\"ipv4static\":true,\"ipv4dhcp\":false,\"ipv4disable\":false,\"parameters\":[\"mac\",\"vlanid\"]}"
	ca6.Editable = true
	ca6.ID = "ec1d95d0-6h0a-482b-8efd-53bec6e9bfce"
	ca6.Name = "ManagementNIC2"
	ca6.Type = "nic"
	ca6.Visible = true
	*customAttributes = append(*customAttributes, ca6)

	ca9.Constraints = "{\"options\":[\"\"]}"
	ca9.Editable = true
	ca9.Description = "Administrator Password"
	ca9.ID = "a881b1af-9034-4c69-a890-5e8c83a13d25"
	ca9.Name = "Password"
	ca9.Type = "password"
	ca9.Visible = true
	*customAttributes = append(*customAttributes, ca9)

	var deploymentPlan i3s.DeploymentPlan
	deploymentPlan.Name = deployment_plan_name
	deploymentPlan.Type = "OEDeploymentPlanV5"
	deploymentPlan.OEBuildPlanURI = "/rest/build-plans/ff13e3d5-b4c3-47cd-bd99-b6e3dd2c4e66"
	deploymentPlan.CustomAttributes = *customAttributes
	deploymentPlan.HPProvided = false

	fmt.Println("HPProvided:", deploymentPlan.HPProvided)
	file, _ := json.MarshalIndent(deploymentPlan, "", " ")
	ioutil.WriteFile("inut.json", file, 0644)
	fmt.Println("***********Creating Deployment Plan****************")
	err := i3sc.CreateDeploymentPlan(deploymentPlan)
	if err != nil {
		fmt.Println("Deployment Plan Creation Failed: ", err)
	} else {
		fmt.Println("Deployment Plan created successfully...")
	}

	sort := "name:desc"
	count := "5"
	fmt.Println("**************Get Deployment Plans sorted by name in descending order****************")
	dps, err := i3sc.GetDeploymentPlans(count, "", "", sort, "")
	if err != nil {
		fmt.Println("Error while getting deployment plans:", err)
	} else {
		for i := range dps.Members {
			fmt.Println(dps.Members[i].Name)
		}
	}

	fmt.Println("***********Getting Deployment Plan By Name****************")
	deployment_plan, err := i3sc.GetDeploymentPlanByName(deployment_plan_name)
	if err != nil {
		fmt.Println("Error in getting deployment plan ", err)
	}
	fmt.Println(deployment_plan)

	fmt.Println("***********Updating Deployment Plan****************")
	deployment_plan.Name = new_name
	deployment_plan.GoldenImageUri = "/rest/golden-images/7e709af9-5446-426e-9ca1-df06c63df2cd"
	deployment_plan.Description = utils.NewNstring("Testing Deployment plan")
	err = i3sc.UpdateDeploymentPlan(deployment_plan)
	if err != nil {
		//panic(err)
		fmt.Println("Error whilw updating Deployment Plan:", err)
	} else {
		fmt.Println("Deployment Plan has been updated with name: " + deploymentPlan.Name)
	}

	fmt.Println("***********Deleting Deployment Plan****************")
	err = i3sc.DeleteDeploymentPlan(new_name)
	if err != nil {
		panic(err)
	} else {
		fmt.Println("Deleteed Deployment Plan successfully...")
	}
}
<commit_msg>DP file<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"github.com/HewlettPackard/oneview-golang/i3s"
	"github.com/HewlettPackard/oneview-golang/ov"
	"github.com/HewlettPackard/oneview-golang/utils"
	"io/ioutil"
	"os"
)

func main() {
	var (
		clientOV             *ov.OVClient
		i3sClient            *i3s.I3SClient
		endpoint             = os.Getenv("ONEVIEW_OV_ENDPOINT")
		i3sc_endpoint        = os.Getenv("ONEVIEW_I3S_ENDPOINT")
		username             = os.Getenv("ONEVIEW_OV_USER")
		password             = os.Getenv("ONEVIEW_OV_PASSWORD")
		domain               = os.Getenv("ONEVIEW_OV_DOMAIN")
		api_version          = 1600
		deployment_plan_name = "DemoDeploymentPlan"
		new_name             = "RenamedDeploymentPlan"
	)
	ovc := clientOV.NewOVClient(
		username,
		password,
		domain,
		endpoint,
		false,
		api_version,
		"*")
	ovc.RefreshLogin()
	i3sc := i3sClient.NewI3SClient(i3sc_endpoint, false, api_version, ovc.APIKey)

	customAttributes := new([]i3s.CustomAttribute)
	var ca1, ca2, ca3, ca4, ca5, ca6, ca7, ca8, ca9, ca10, ca11 i3s.CustomAttribute
	ca1.Constraints = "{\"options\":[\"English (United States)\",\"French (France)\",\"German (Germany)\",\"Japanese (Japan)\",\"Arabic " +
		"(Saudi Arabia)\",\"Chinese (PRC)\",\"Korean (Korea)\",\"Portuguese (Brazil)\",\"Russian (Russia)\"]}"
	ca1.Editable = true
	ca1.ID = "4509965b-fcdb-4ab2-9e20-1b80294ce94f"
	ca1.Name = "DisplayLanguage"
	ca1.Type = "option"
	ca1.Value = "English (United States)"
	ca1.Visible = true
	*customAttributes = append(*customAttributes, ca1)

	ca2.Constraints = "{\"options\":[\"English (United States)\",\"Arabic (101)\",\"Chinese (Traditional) - US Keyboard\",\"Japanese\",\"Korean\",\"United" +
		" Kingdom Extended\",\"United States - Dvorak\"]}"
	ca2.Editable = true
	ca2.ID = "c6ef28cc-0562-4c1e-8454-8e295f4df00d"
	ca2.Name = "KeyboardLayout"
	ca2.Type = "option"
	ca2.Value = "English (United States)"
	ca2.Visible = true
	*customAttributes = append(*customAttributes, ca2)

	ca3.Constraints = "{}"
	ca3.Editable = true
	ca3.ID = "e084491d-e476-4660-b231-b45a6cf2d42d"
	ca3.Name = "User1Password"
	ca3.Type = "string"
	ca3.Visible = true
	*customAttributes = append(*customAttributes, ca3)

	ca4.Constraints = "{}"
	ca4.Editable = true
	ca4.ID = "056c6f33-6509-4b1c-bb93-17685e631f4d"
	ca4.Name = "User1DisplayName"
	ca4.Type = "string"
	ca4.Visible = true
	*customAttributes = append(*customAttributes, ca4)

	ca5.Constraints = "{\"ipv4static\":true,\"ipv4dhcp\":true,\"ipv4disable\":false,\"parameters\":[\"mac\"]}"
	ca5.Editable = true
	ca5.ID = "8303c168-3e23-4025-9e63-2bddd644b461"
	ca5.Name = "ManagementNIC2"
	ca5.Type = "nic"
	ca5.Visible = true
	*customAttributes = append(*customAttributes, ca5)

	ca6.Constraints = "{\"options\":[\"Disallow\",\"Allow (Network Level Authentication)\",\"Allow\"]}"
	ca6.Editable = true
	ca6.ID = "ab0aa2b0-6b4f-433c-a6a6-abcb949ac286"
	ca6.Name = "RemoteDesktop"
	ca6.Type = "option"
	ca6.Value = "Disallow"
	ca6.Visible = true
	*customAttributes = append(*customAttributes, ca6)

	ca7.Constraints = "{}"
	ca7.Editable = true
	ca7.ID = "3c7c8229-1dc6-4656-857d-3392a26585ee"
	ca7.Name = "Hostname"
	ca7.Type = "string"
	ca7.Visible = true
	*customAttributes = append(*customAttributes, ca7)

	ca8.Constraints = "{\"ipv4static\":true,\"ipv4dhcp\":true,\"ipv4disable\":false,\"parameters\":[\"dhcp\",\"dns1\",\"dns2\",\"gateway\",\"ipaddress\",\"mac\",\"netmask\"]}"
	ca8.Editable = true
	ca8.ID = "ec1d95d0-690a-482b-8efd-53bec6e9bfce"
	ca8.Name = "ManagementNIC1"
	ca8.Type = "nic"
	ca8.Visible = true
	*customAttributes = append(*customAttributes, ca8)

	ca9.Constraints = "{\"maxlen\":\"20\"}"
	ca9.Editable = true
	ca9.Description = "Administrator Password"
	ca9.ID = "a881b1af-9034-4c69-a890-5e8c83a13d25"
	ca9.Name = "Password"
	ca9.Type = "password"
	ca9.Visible = true
	*customAttributes = append(*customAttributes, ca9)

	ca10.Constraints = "{\"options\":[\"GMT Standard Time\",\"Arabian Standard Time\",\"AUS Eastern Standard Time\",\"Central Standard Time\",\"China " +
		"Standard Time\",\"Eastern Standard Time\",\"India Standard Time\",\"Mountain Standard Time\",\"Singapore Standard " +
		"Time\",\"Tokyo Standard Time\"]}"
	ca10.Editable = true
	ca10.ID = "0d629c3e-23d0-49e1-950c-ecfcb9d5610d"
	ca10.Name = "TimeZone"
	ca10.Type = "option"
	ca10.Value = "GMT Standard Time"
	ca10.Visible = true
	*customAttributes = append(*customAttributes, ca10)

	ca11.Constraints = "{}"
	ca11.Editable = true
	ca11.ID = "1075adb8-5399-41fe-b6b3-71bea8836615"
	ca11.Name = "User1Name"
	ca11.Type = "string"
	ca11.Visible = true
	*customAttributes = append(*customAttributes, ca11)

	var deploymentPlan i3s.DeploymentPlan
	deploymentPlan.Name = deployment_plan_name
	deploymentPlan.Type = "OEDeploymentPlanV5"
	deploymentPlan.OEBuildPlanURI = "/rest/build-plans/1cfc2cc7-85c7-4db8-8213-854c0bfa3ff7"
	deploymentPlan.CustomAttributes = *customAttributes
	deploymentPlan.HPProvided = false

	fmt.Println("HPProvided:", deploymentPlan.HPProvided)
	file, _ := json.MarshalIndent(deploymentPlan, "", " ")
	ioutil.WriteFile("inut.json", file, 0644)
	fmt.Println("***********Creating Deployment Plan****************")
	err := i3sc.CreateDeploymentPlan(deploymentPlan)
	if err != nil {
		fmt.Println("Deployment Plan Creation Failed: ", err)
	} else {
		fmt.Println("Deployment Plan created successfully...")
	}

	sort := "name:desc"
	count := "5"
	fmt.Println("**************Get Deployment Plans sorted by name in descending order****************")
	dps, err := i3sc.GetDeploymentPlans(count, "", "", sort, "")
	if err != nil {
		fmt.Println("Error while getting deployment plans:", err)
	} else {
		for i := range dps.Members {
			fmt.Println(dps.Members[i].Name)
		}
	}

	fmt.Println("***********Getting Deployment Plan By Name****************")
	deployment_plan, err := i3sc.GetDeploymentPlanByName(deployment_plan_name)
	if err != nil {
		fmt.Println("Error in getting deployment plan ", err)
	}
	fmt.Println(deployment_plan)

	fmt.Println("***********Updating Deployment Plan****************")
	deployment_plan.Name = new_name
	deployment_plan.GoldenImageUri = "/rest/golden-images/7e709af9-5446-426e-9ca1-df06c63df2cd"
	deployment_plan.Description = utils.NewNstring("Testing Deployment plan")
	err = i3sc.UpdateDeploymentPlan(deployment_plan)
	if err != nil {
		//panic(err)
		fmt.Println("Error whilw updating Deployment Plan:", err)
	} else {
		fmt.Println("Deployment Plan has been updated with name: " + deploymentPlan.Name)
	}

	fmt.Println("***********Deleting Deployment Plan****************")
	err = i3sc.DeleteDeploymentPlan(new_name)
	if err != nil {
		panic(err)
	} else {
		fmt.Println("Deleteed Deployment Plan successfully...")
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/anthonynsimon/bild/imgio"
	"github.com/anthonynsimon/bild/transform"
	"github.com/songtianyi/go-mxnet-predictor/mxnet"
	"github.com/songtianyi/go-mxnet-predictor/utils"
	"io/ioutil"
	"sort"
)

func main() {

	// load mean image from file
	nd, err := mxnet.CreateNDListFromFile("/data/mean.bin")
	if err != nil {
		panic(err)
	}
	// free ndarray list operator before exit
	defer nd.Free()

	// get mean image data from C memory
	item, err := nd.Get(0)
	if err != nil {
		panic(err)
	}
	fmt.Println(item.Key, item.Data[0:10], item.Shape, item.Size)

	// load model
	symbol, err := ioutil.ReadFile("/data/102flowers-symbol.json")
	if err != nil {
		panic(err)
	}
	params, err := ioutil.ReadFile("/data/102flowers-0260.params")
	if err != nil {
		panic(err)
	}

	// create predictor
	p, err := mxnet.CreatePredictor(symbol, params, mxnet.Device{mxnet.CPU_DEVICE, 0}, []mxnet.InputNode{{Key: "data", Shape: []uint32{1, 3, 299, 299}}})
	if err != nil {
		panic(err)
	}
	defer p.Free()

	// load test image for predction
	img, err := imgio.Open("/data/flowertest.jpg")
	if err != nil {
		panic(err)
	}
	// preprocess
	resized := transform.Resize(img, 299, 299, transform.Linear)
	res, err := utils.CvtImageTo1DArray(resized, item.Data)
	if err != nil {
		panic(err)
	}

	// set input
	if err := p.SetInput("data", res); err != nil {
		panic(err)
	}
	// do predict
	if err := p.Forward(); err != nil {
		panic(err)
	}
	// get predict result
	data, err := p.GetOutput(0)
	if err != nil {
		panic(err)
	}
	idxs := make([]int, len(data))
	for i := range data {
		idxs[i] = i
	}
	as := utils.ArgSort{Args: data, Idxs: idxs}
	sort.Sort(as)
	fmt.Println("result:")
	fmt.Println(as.Args)
	fmt.Println(as.Idxs)
}
<commit_msg>add line break<commit_after>package main

import (
	"fmt"
	"github.com/anthonynsimon/bild/imgio"
	"github.com/anthonynsimon/bild/transform"
	"github.com/songtianyi/go-mxnet-predictor/mxnet"
	"github.com/songtianyi/go-mxnet-predictor/utils"
	"io/ioutil"
	"sort"
)

func main() {

	// load mean image from file
	nd, err := mxnet.CreateNDListFromFile("/data/mean.bin")
	if err != nil {
		panic(err)
	}
	// free ndarray list operator before exit
	defer nd.Free()

	// get mean image data from C memory
	item, err := nd.Get(0)
	if err != nil {
		panic(err)
	}
	fmt.Println(item.Key, item.Data[0:10], item.Shape, item.Size)

	// load model
	symbol, err := ioutil.ReadFile("/data/102flowers-symbol.json")
	if err != nil {
		panic(err)
	}
	params, err := ioutil.ReadFile("/data/102flowers-0260.params")
	if err != nil {
		panic(err)
	}

	// create predictor
	p, err := mxnet.CreatePredictor(symbol,
			params,
			mxnet.Device{mxnet.CPU_DEVICE, 0},
			[]mxnet.InputNode{{Key: "data", Shape: []uint32{1, 3, 299, 299}}},
	)
	if err != nil {
		panic(err)
	}
	defer p.Free()

	// load test image for predction
	img, err := imgio.Open("/data/flowertest.jpg")
	if err != nil {
		panic(err)
	}
	// preprocess
	resized := transform.Resize(img, 299, 299, transform.Linear)
	res, err := utils.CvtImageTo1DArray(resized, item.Data)
	if err != nil {
		panic(err)
	}

	// set input
	if err := p.SetInput("data", res); err != nil {
		panic(err)
	}
	// do predict
	if err := p.Forward(); err != nil {
		panic(err)
	}
	// get predict result
	data, err := p.GetOutput(0)
	if err != nil {
		panic(err)
	}
	idxs := make([]int, len(data))
	for i := range data {
		idxs[i] = i
	}
	as := utils.ArgSort{Args: data, Idxs: idxs}
	sort.Sort(as)
	fmt.Println("result:")
	fmt.Println(as.Args)
	fmt.Println(as.Idxs)
}
<|endoftext|>


<commit_before>// +build windows
package main

import (
	"context"
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"strings"
	"time"
	"unsafe"

	"github.com/go-ole/go-ole"
	"github.com/moutend/go-wave"
	"github.com/moutend/go-wca"
)

var version = "latest"
var revision = "latest"

type FilenameFlag struct {
	Value string
}

func (f *FilenameFlag) Set(value string) (err error) {
	if !strings.HasSuffix(value, ".wav") {
		err = fmt.Errorf("specify WAVE audio file (*.wav)")
		return
	}
	f.Value = value
	return
}

func (f *FilenameFlag) String() string {
	return f.Value
}

func main() {
	var err error
	if err = run(os.Args); err != nil {
		log.Fatal(err)
	}
}

func run(args []string) (err error) {
	var filenameFlag FilenameFlag
	var versionFlag bool
	var audio *wave.WAVE

	f := flag.NewFlagSet(args[0], flag.ExitOnError)
	f.Var(&filenameFlag, "input", "Specify WAVE format audio (e.g. music.wav)")
	f.Var(&filenameFlag, "i", "Alias of --input")
	f.BoolVar(&versionFlag, "version", false, "Show version")
	f.Parse(args[1:])

	if versionFlag {
		fmt.Printf("%s-%s\n", version, revision)
		return
	}
	if filenameFlag.Value == "" {
		return
	}
	if audio, err = wave.OpenFile(filenameFlag.Value); err != nil {
		return
	}

	signalChan := make(chan os.Signal, 1)
	signal.Notify(signalChan, os.Interrupt)
	ctx, cancel := context.WithCancel(context.Background())

	go func() {
		select {
		case <-signalChan:
			fmt.Println("Interrupted by SIGINT")
			cancel()
		}
	}()

	if err = renderSharedEventDriven(ctx, audio); err != nil {
		return
	}
	fmt.Println("Successfully done")
	return
}

func renderSharedEventDriven(ctx context.Context, audio *wave.WAVE) (err error) {
	if err = ole.CoInitializeEx(0, ole.COINIT_APARTMENTTHREADED); err != nil {
		return
	}
	defer ole.CoUninitialize()

	var mmde *wca.IMMDeviceEnumerator
	if err = wca.CoCreateInstance(wca.CLSID_MMDeviceEnumerator, 0, wca.CLSCTX_ALL, wca.IID_IMMDeviceEnumerator, &mmde); err != nil {
		return
	}
	defer mmde.Release()

	var mmd *wca.IMMDevice
	if err = mmde.GetDefaultAudioEndpoint(wca.ERender, wca.EConsole, &mmd); err != nil {
		return
	}
	defer mmd.Release()

	var ps *wca.IPropertyStore
	if err = mmd.OpenPropertyStore(wca.STGM_READ, &ps); err != nil {
		return
	}
	defer ps.Release()

	var pv wca.PROPVARIANT
	if err = ps.GetValue(&wca.PKEY_Device_FriendlyName, &pv); err != nil {
		return
	}
	fmt.Printf("Rendering audio to: %s\n", pv.String())

	var ac *wca.IAudioClient
	if err = mmd.Activate(wca.IID_IAudioClient, wca.CLSCTX_ALL, nil, &ac); err != nil {
		return
	}
	defer ac.Release()

	var wfx *wca.WAVEFORMATEX
	if err = ac.GetMixFormat(&wfx); err != nil {
		return
	}
	defer ole.CoTaskMemFree(uintptr(unsafe.Pointer(wfx)))
	if wfx.WFormatTag != wca.WAVE_FORMAT_PCM {
		wfx.WFormatTag = 1
		wfx.NSamplesPerSec = audio.SamplesPerSec
		wfx.WBitsPerSample = audio.BitsPerSample
		wfx.NChannels = audio.Channels
		wfx.NBlockAlign = audio.BlockAlign
		wfx.NAvgBytesPerSec = audio.AvgBytesPerSec
		wfx.CbSize = 0
	}

	fmt.Println("--------")
	fmt.Printf("Format: PCM %d bit signed integer\n", wfx.WBitsPerSample)
	fmt.Printf("Rate: %d Hz\n", wfx.NSamplesPerSec)
	fmt.Printf("Channels: %d\n", wfx.NChannels)
	fmt.Println("--------")

	var defaultPeriod int64
	var minimumPeriod int64
	var renderingPeriod time.Duration
	if err = ac.GetDevicePeriod(&defaultPeriod, &minimumPeriod); err != nil {
		return
	}
	renderingPeriod = time.Duration(defaultPeriod * 100)
	fmt.Printf("Default rendering period: %d ms\n", renderingPeriod/time.Millisecond)

	if err = ac.Initialize(wca.AUDCLNT_SHAREMODE_SHARED, wca.AUDCLNT_STREAMFLAGS_EVENTCALLBACK, 200*10000, 0, wfx, nil); err != nil {
		return
	}
	audioReadyEvent := wca.CreateEventExA(0, 0, 0, wca.EVENT_MODIFY_STATE|wca.SYNCHRONIZE)
	defer wca.CloseHandle(audioReadyEvent)

	if err = ac.SetEventHandle(audioReadyEvent); err != nil {
		return
	}

	var bufferFrameSize uint32
	if err = ac.GetBufferSize(&bufferFrameSize); err != nil {
		return
	}
	fmt.Printf("Allocated buffer size: %d\n", bufferFrameSize)

	var arc *wca.IAudioRenderClient
	if err = ac.GetService(wca.IID_IAudioRenderClient, &arc); err != nil {
		return
	}
	defer arc.Release()

	if err = ac.Start(); err != nil {
		return
	}
	fmt.Println("Start rendering audio with shared-event-driven mode")
	fmt.Println("Press Ctrl-C to stop")
	var b *byte
	var data *byte
	var offset int
	var isPlaying bool = true
	var padding uint32
	var availableFrameSize uint32

	errorChan := make(chan error, 1)

	for {
		if !isPlaying {
			close(errorChan)
			break
		}
		go func() {
			errorChan <- watchEvent(ctx, audioReadyEvent)
		}()
		select {
		case <-ctx.Done():
			isPlaying = false
			<-errorChan
			break
		case err = <-errorChan:
			if err != nil {
				isPlaying = false
				break
			}
			if offset >= int(audio.DataSize) {
				isPlaying = false
				break
			}
			if err = ac.GetCurrentPadding(&padding); err != nil {
				return
			}
			if availableFrameSize = bufferFrameSize - padding; availableFrameSize == 0 {
				continue
			}
			if err = arc.GetBuffer(availableFrameSize, &data); err != nil {
				return
			}

			start := unsafe.Pointer(data)
			lim := int(availableFrameSize) * int(wfx.NBlockAlign)
			remaining := int(audio.DataSize) - offset

			if remaining < lim {
				lim = remaining
			}
			for n := 0; n < lim; n++ {
				b = (*byte)(unsafe.Pointer(uintptr(start) + uintptr(n)))
				*b = audio.RawData[offset+n]
			}

			offset += lim

			if err = arc.ReleaseBuffer(availableFrameSize, 0); err != nil {
				return
			}
		}
	}
	if err != nil {
		return
	}

	if err = ac.Stop(); err != nil {
		return
	}
	fmt.Println("Stop rendering")
	return
}

func watchEvent(ctx context.Context, event uintptr) (err error) {
	errorChan := make(chan error, 1)
	go func() {
		errorChan <- eventEmitter(event)
	}()
	select {
	case err = <-errorChan:
		close(errorChan)
		return
	case <-ctx.Done():
		err = ctx.Err()
		return
	}
	return
}

func eventEmitter(event uintptr) (err error) {
	//if err = ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED); err != nil {
	//	return
	//}
	dw := wca.WaitForSingleObject(event, wca.INFINITE)
	if dw != 0 {
		return fmt.Errorf("failed to watch event")
	}
	//ole.CoUninitialize()
	return
}
<commit_msg>Use go-wav<commit_after>// +build windows
package main

import (
	"context"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/signal"
	"strings"
	"time"
	"unsafe"

	"github.com/go-ole/go-ole"
	"github.com/moutend/go-wav"
	"github.com/moutend/go-wca"
)

var version = "latest"
var revision = "latest"

type FilenameFlag struct {
	Value string
}

func (f *FilenameFlag) Set(value string) (err error) {
	if !strings.HasSuffix(value, ".wav") {
		err = fmt.Errorf("specify WAVE audio file (*.wav)")
		return
	}
	f.Value = value
	return
}

func (f *FilenameFlag) String() string {
	return f.Value
}

func main() {
	var err error
	if err = run(os.Args); err != nil {
		log.Fatal(err)
	}
}

func run(args []string) (err error) {
	var filenameFlag FilenameFlag
	var versionFlag bool
	var audio = &wav.File{}
	var file []byte

	f := flag.NewFlagSet(args[0], flag.ExitOnError)
	f.Var(&filenameFlag, "input", "Specify WAVE format audio (e.g. music.wav)")
	f.Var(&filenameFlag, "i", "Alias of --input")
	f.BoolVar(&versionFlag, "version", false, "Show version")
	f.Parse(args[1:])

	if versionFlag {
		fmt.Printf("%s-%s\n", version, revision)
		return
	}
	if filenameFlag.Value == "" {
		return
	}
	if file, err = ioutil.ReadFile(filenameFlag.Value); err != nil {
		return
	}
	if err = wav.Unmarshal(file, audio); err != nil {
		return
	}

	signalChan := make(chan os.Signal, 1)
	signal.Notify(signalChan, os.Interrupt)
	ctx, cancel := context.WithCancel(context.Background())

	go func() {
		select {
		case <-signalChan:
			fmt.Println("Interrupted by SIGINT")
			cancel()
		}
	}()

	if err = renderSharedEventDriven(ctx, audio); err != nil {
		return
	}
	fmt.Println("Successfully done")
	return
}

func renderSharedEventDriven(ctx context.Context, audio *wav.File) (err error) {
	if err = ole.CoInitializeEx(0, ole.COINIT_APARTMENTTHREADED); err != nil {
		return
	}
	defer ole.CoUninitialize()

	var mmde *wca.IMMDeviceEnumerator
	if err = wca.CoCreateInstance(wca.CLSID_MMDeviceEnumerator, 0, wca.CLSCTX_ALL, wca.IID_IMMDeviceEnumerator, &mmde); err != nil {
		return
	}
	defer mmde.Release()

	var mmd *wca.IMMDevice
	if err = mmde.GetDefaultAudioEndpoint(wca.ERender, wca.EConsole, &mmd); err != nil {
		return
	}
	defer mmd.Release()

	var ps *wca.IPropertyStore
	if err = mmd.OpenPropertyStore(wca.STGM_READ, &ps); err != nil {
		return
	}
	defer ps.Release()

	var pv wca.PROPVARIANT
	if err = ps.GetValue(&wca.PKEY_Device_FriendlyName, &pv); err != nil {
		return
	}
	fmt.Printf("Rendering audio to: %s\n", pv.String())

	var ac *wca.IAudioClient
	if err = mmd.Activate(wca.IID_IAudioClient, wca.CLSCTX_ALL, nil, &ac); err != nil {
		return
	}
	defer ac.Release()

	var wfx *wca.WAVEFORMATEX
	if err = ac.GetMixFormat(&wfx); err != nil {
		return
	}
	defer ole.CoTaskMemFree(uintptr(unsafe.Pointer(wfx)))

	wfx.WFormatTag = 1
	wfx.NSamplesPerSec = uint32(audio.SamplesPerSec())
	wfx.WBitsPerSample = uint16(audio.BitsPerSample())
	wfx.NChannels = uint16(audio.Channels())
	wfx.NBlockAlign = uint16(audio.BlockAlign())
	wfx.NAvgBytesPerSec = uint32(audio.AvgBytesPerSec())
	wfx.CbSize = 0

	fmt.Println("--------")
	fmt.Printf("Format: PCM %d bit signed integer\n", wfx.WBitsPerSample)
	fmt.Printf("Rate: %d Hz\n", wfx.NSamplesPerSec)
	fmt.Printf("Channels: %d\n", wfx.NChannels)
	fmt.Println("--------")

	var defaultPeriod int64
	var minimumPeriod int64
	var renderingPeriod time.Duration
	if err = ac.GetDevicePeriod(&defaultPeriod, &minimumPeriod); err != nil {
		return
	}
	renderingPeriod = time.Duration(defaultPeriod * 100)
	fmt.Printf("Default rendering period: %d ms\n", renderingPeriod/time.Millisecond)

	var latency uint32 = 200 // millisecond
	if err = ac.Initialize(wca.AUDCLNT_SHAREMODE_SHARED, wca.AUDCLNT_STREAMFLAGS_EVENTCALLBACK, latency*10000, 0, wfx, nil); err != nil {
		return
	}
	audioReadyEvent := wca.CreateEventExA(0, 0, 0, wca.EVENT_MODIFY_STATE|wca.SYNCHRONIZE)
	defer wca.CloseHandle(audioReadyEvent)

	if err = ac.SetEventHandle(audioReadyEvent); err != nil {
		return
	}

	var bufferFrameSize uint32
	if err = ac.GetBufferSize(&bufferFrameSize); err != nil {
		return
	}
	fmt.Printf("Allocated buffer size: %d\n", bufferFrameSize)

	var arc *wca.IAudioRenderClient
	if err = ac.GetService(wca.IID_IAudioRenderClient, &arc); err != nil {
		return
	}
	defer arc.Release()

	if err = ac.Start(); err != nil {
		return
	}
	fmt.Println("Start rendering audio with shared-event-driven mode")
	fmt.Println("Press Ctrl-C to stop")

	var input = audio.Bytes()
	var b *byte
	var data *byte
	var offset int
	var isPlaying bool = true
	var padding uint32
	var availableFrameSize uint32

	errorChan := make(chan error, 1)

	for {
		if !isPlaying {
			close(errorChan)
			break
		}
		go func() {
			errorChan <- watchEvent(ctx, audioReadyEvent)
		}()
		select {
		case <-ctx.Done():
			isPlaying = false
			<-errorChan
			break
		case err = <-errorChan:
			if err != nil {
				isPlaying = false
				break
			}
			if offset >= audio.Length() {
				isPlaying = false
				break
			}
			if err = ac.GetCurrentPadding(&padding); err != nil {
				return
			}
			if availableFrameSize = bufferFrameSize - padding; availableFrameSize == 0 {
				continue
			}
			if err = arc.GetBuffer(availableFrameSize, &data); err != nil {
				return
			}

			start := unsafe.Pointer(data)
			lim := int(availableFrameSize) * int(wfx.NBlockAlign)
			remaining := audio.Length() - offset

			if remaining < lim {
				lim = remaining
			}
			for n := 0; n < lim; n++ {
				b = (*byte)(unsafe.Pointer(uintptr(start) + uintptr(n)))
				*b = input[offset+n]
			}

			offset += lim

			if err = arc.ReleaseBuffer(availableFrameSize, 0); err != nil {
				return
			}
		}
	}
	if err != nil {
		return
	}
	time.Sleep(time.Duration(latency) * time.Millisecond)
	return ac.Stop()
}

func watchEvent(ctx context.Context, event uintptr) (err error) {
	errorChan := make(chan error, 1)
	go func() {
		errorChan <- eventEmitter(event)
	}()
	select {
	case err = <-errorChan:
		close(errorChan)
		return
	case <-ctx.Done():
		err = ctx.Err()
		return
	}
	return
}

func eventEmitter(event uintptr) (err error) {
	//if err = ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED); err != nil {
	//	return
	//}
	dw := wca.WaitForSingleObject(event, wca.INFINITE)
	if dw != 0 {
		return fmt.Errorf("failed to watch event")
	}
	//ole.CoUninitialize()
	return
}
<|endoftext|>


<commit_before>package json

import "github.com/gopherjs/gopherjs/js"

func Marshal(v interface{}) ([]byte, error) {
	return MarshalIndent(v, "", "")
}

func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
	s, err := MarshalIndentString(v, prefix, indent)
	return []byte(s), err
}

func MarshalString(v interface{}) (string, error) {
	return MarshalIndentString(v, "", "")
}

func MarshalIndentString(v interface{}, prefix, indent string) (string, error) {
	str := js.Global.Get("JSON").Call("stringify", js.InternalObject(filterIt).Invoke(js.InternalObject(v), v), nil, indent)
	if len(prefix) > 0 {
		str = str.Call("replace", js.Global.Get("RegExp").New("\n", "g"), "\n"+prefix)
	}
	return str.String(), nil
}

const (
	arrayKind     = 17
	interfaceKind = 20
	mapKind       = 21
	ptrKind       = 22
	sliceKind     = 23
	structKind    = 25
)

func filterIt(v, value *js.Object) *js.Object {
	filter(v, v.Get("constructor"), value)
	return value
}

func filter(v, t, value *js.Object) {
	switch t.Get("kind").Int() {
	case arrayKind, sliceKind:
		len := value.Length()
		for i := 0; i < len; i++ {
			filter(v.Get("$array").Index(i), t.Get("elem"), value.Index(i))
		}
	case mapKind:
		keys := js.Global.Get("Object").Call("keys", value)
		len := keys.Length()
		for i := 0; i < len; i++ {
			name := keys.Index(i).String()
			filter(v.Get("$map").Get(name), t.Get("elem"), value.Get(name))
		}
	case ptrKind:
		filter(v, t.Get("elem"), value)
	case structKind:
		nf := t.Get("fields").Length()
		for i := 0; i < nf; i++ {
			field := t.Get("fields").Index(i)
			tag, tagOptions := parseTag(getJSONTag(field.Get("tag")))
			if tag == "-" {
				value.Delete(field.Get("name").String())
				continue
			}
			name := field.Get("name").String()
			if tagOptions.Contains("omitempty") {
				if isEmpty(v.Get(name)) {
					value.Delete(name)
					continue
				}
			}
			if tagOptions.Contains("string") {

			} else {
				filter(v.Get(name), field.Get("typ"), value.Get(name))
			}
			if len(tag) != 0 && tag != name {
				value.Set(tag, value.Get(name))
				value.Delete(name)
			}
		}
	case interfaceKind:
		filter(v.Get("$val"), v.Get("constructor"), value)
	}
}

func isEmpty(v *js.Object) bool {
	return false
}
<commit_msg>disabled string tag options code path<commit_after>package json

import "github.com/gopherjs/gopherjs/js"

func Marshal(v interface{}) ([]byte, error) {
	return MarshalIndent(v, "", "")
}

func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
	s, err := MarshalIndentString(v, prefix, indent)
	return []byte(s), err
}

func MarshalString(v interface{}) (string, error) {
	return MarshalIndentString(v, "", "")
}

func MarshalIndentString(v interface{}, prefix, indent string) (string, error) {
	str := js.Global.Get("JSON").Call("stringify", js.InternalObject(filterIt).Invoke(js.InternalObject(v), v), nil, indent)
	if len(prefix) > 0 {
		str = str.Call("replace", js.Global.Get("RegExp").New("\n", "g"), "\n"+prefix)
	}
	return str.String(), nil
}

const (
	arrayKind     = 17
	interfaceKind = 20
	mapKind       = 21
	ptrKind       = 22
	sliceKind     = 23
	structKind    = 25
)

func filterIt(v, value *js.Object) *js.Object {
	filter(v, v.Get("constructor"), value)
	return value
}

func filter(v, t, value *js.Object) {
	switch t.Get("kind").Int() {
	case arrayKind, sliceKind:
		len := value.Length()
		for i := 0; i < len; i++ {
			filter(v.Get("$array").Index(i), t.Get("elem"), value.Index(i))
		}
	case mapKind:
		keys := js.Global.Get("Object").Call("keys", value)
		len := keys.Length()
		for i := 0; i < len; i++ {
			name := keys.Index(i).String()
			filter(v.Get("$map").Get(name), t.Get("elem"), value.Get(name))
		}
	case ptrKind:
		filter(v, t.Get("elem"), value)
	case structKind:
		nf := t.Get("fields").Length()
		for i := 0; i < nf; i++ {
			field := t.Get("fields").Index(i)
			tag, tagOptions := parseTag(getJSONTag(field.Get("tag")))
			if tag == "-" {
				value.Delete(field.Get("name").String())
				continue
			}
			name := field.Get("name").String()
			if tagOptions.Contains("omitempty") {
				if isEmpty(v.Get(name)) {
					value.Delete(name)
					continue
				}
			}
			//if tagOptions.Contains("string") {

			//} else {
			filter(v.Get(name), field.Get("typ"), value.Get(name))
			//}
			if len(tag) != 0 && tag != name {
				value.Set(tag, value.Get(name))
				value.Delete(name)
			}
		}
	case interfaceKind:
		filter(v.Get("$val"), v.Get("constructor"), value)
	}
}

func isEmpty(v *js.Object) bool {
	return false
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/scipipe/scipipe"
)

const dna = "AAACCCGGGTTT"

func main() {
	// Initialize workflow
	wf := scipipe.NewWorkflow("DNA Base Complement Workflow", 4)

	// Initialize processes based on shell commands
	makeDNA := wf.NewProc("Make DNA", "echo "+dna+" > {o:dna}")
	complmt := wf.NewProc("Base Complement", `cat {i:in} | tr ATCG TAGC > {o:compl}`)
	reverse := wf.NewProc("Reverse", "cat {i:in} | rev > {o:rev}")

	// Connect dependencies
	complmt.In("in").From(makeDNA.Out("dna"))
	reverse.In("in").From(complmt.Out("compl"))

	// Run the workflow
	wf.Run()
}
<commit_msg>Improve reverse complement example<commit_after>package main

import (
	"github.com/scipipe/scipipe"
)

const dna = "AAAGCCCGTGGGGGACCTGTTC"

func main() {
	// Initialize workflow, using max 4 CPU cores
	wf := scipipe.NewWorkflow("DNA Base Complement Workflow", 4)

	// Initialize processes based on shell commands:
	// makeDNA writes a DNA string to a file
	makeDNA := wf.NewProc("Make DNA", "echo "+dna+" > {o:dna}")
	makeDNA.SetOut("dna", "dna.txt")
	// complmt computes the base complement of a DNA string
	complmt := wf.NewProc("Base Complement", "cat {i:in} | tr ATCG TAGC > {o:compl}")
	complmt.SetOut("compl", "{i:in}.compl.txt")
	// reverse reverses the input DNA string
	reverse := wf.NewProc("Reverse", "cat {i:in} | rev > {o:rev}")
	reverse.SetOut("rev", "{i:in}.rev.txt")

	// Connect data dependencies between out- and in-ports
	complmt.In("in").From(makeDNA.Out("dna"))
	reverse.In("in").From(complmt.Out("compl"))

	// Run the workflow
	wf.Run()
}
<|endoftext|>


<commit_before>package dsl

import (
	"fmt"
	"strings"

	"github.com/bketelsen/gorma"
	"github.com/raphael/goa/design/dsl"
)

// RelationalField is a DSL definition for a field in a Relational Model
// Examples and more docs here later
//func Field(name string, fieldType gorma.FieldType, dsl func()) {
func Field(name string, args ...interface{}) {
	// We can't rely on this being run first, any of the top level DSL could run
	// in any order. The top level DSLs are API, Version, Resource, MediaType and Type.
	// The first one to be called executes InitDesign.

	checkInit()
	// standardize field name definitions
	name = strings.Title(name)
	fieldType, dsl := parsemModelArgs(args...)
	if s, ok := relationalModelDefinition(true); ok {
		if s.RelationalFields == nil {
			s.RelationalFields = make(map[string]*gorma.RelationalFieldDefinition)
		}
		field, ok := s.RelationalFields[name]
		if !ok {
			field = &gorma.RelationalFieldDefinition{
				Name:          name,
				DefinitionDSL: dsl,
				Parent:        s,
				Datatype:      fieldType,
			}
		} else {
			// the field was auto-added by the model parser
			// so we need to update whatever we can from this new definition
			fmt.Println("AutoAdded field", name)
			field.DefinitionDSL = dsl

		}

		if fieldType == gorma.PKUUID || fieldType == gorma.PKInteger || fieldType == gorma.PKBigInteger {
			field.PrimaryKey = true
			field.Description = "primary key"
			s.PrimaryKeys = append(s.PrimaryKeys, field)
		}

		if fieldType == gorma.Timestamp {
			field.Timestamp = true
			field.Description = "timestamp"
		}
		if fieldType == gorma.NullableTimestamp {
			field.Timestamp = true
			field.Nullable = true
			field.Description = "nullable timestamp (soft delete)"
		}

		s.RelationalFields[name] = field
	}

}

func parsemModelArgs(args ...interface{}) (gorma.FieldType, func()) {

	var (
		fieldType gorma.FieldType
		dslp      func()
		ok        bool
	)

	parseFieldType := func(expected string, index int) {
		if fieldType, ok = args[index].(gorma.FieldType); !ok {
			invalidArgError(expected, args[index])
		}
	}
	parseDSL := func(index int, success, failure func()) {
		if dslp, ok = args[index].(func()); ok {
			success()
		} else {
			failure()
		}
	}

	success := func() {}

	switch len(args) {
	case 0:
		fieldType = gorma.NotFound
	case 1:
		parseDSL(0, success, func() { parseFieldType("DataType or func()", 0) })
	case 2:
		parseFieldType("FieldType", 0)
		parseDSL(1, success, func() { invalidArgError("DSL", args[1]) })

	default:
		dsl.ReportError("too many arguments in call to Attribute")
	}

	return fieldType, dslp

}

// DatabaseFieldName creates sql tag necessary to name the
// database column
func DatabaseFieldName(d string) {
	if r, ok := relationalFieldDefinition(false); ok {
		r.DatabaseFieldName = d
	}
}
<commit_msg>document variadic field definitoin<commit_after>package dsl

import (
	"fmt"
	"strings"

	"github.com/bketelsen/gorma"
	"github.com/raphael/goa/design/dsl"
)

// RelationalField is a DSL definition for a field in a Relational Model
// Examples and more docs here later
// Parameter Options:
// Field("Title")
// Field("Title", gorma.String)
// Field("Title", func(){... other field level dsl ...})
// Field("Title", gorma.String, func(){... other field level dsl ...})
func Field(name string, args ...interface{}) {
	// We can't rely on this being run first, any of the top level DSL could run
	// in any order. The top level DSLs are API, Version, Resource, MediaType and Type.
	// The first one to be called executes InitDesign.

	checkInit()
	// standardize field name definitions
	name = strings.Title(name)
	fieldType, dsl := parsemModelArgs(args...)
	if s, ok := relationalModelDefinition(true); ok {
		if s.RelationalFields == nil {
			s.RelationalFields = make(map[string]*gorma.RelationalFieldDefinition)
		}
		field, ok := s.RelationalFields[name]
		if !ok {
			field = &gorma.RelationalFieldDefinition{
				Name:          name,
				DefinitionDSL: dsl,
				Parent:        s,
				Datatype:      fieldType,
			}
		} else {
			// the field was auto-added by the model parser
			// so we need to update whatever we can from this new definition
			fmt.Println("AutoAdded field", name)
			field.DefinitionDSL = dsl

		}

		if fieldType == gorma.PKUUID || fieldType == gorma.PKInteger || fieldType == gorma.PKBigInteger {
			field.PrimaryKey = true
			field.Description = "primary key"
			s.PrimaryKeys = append(s.PrimaryKeys, field)
		}

		if fieldType == gorma.Timestamp {
			field.Timestamp = true
			field.Description = "timestamp"
		}
		if fieldType == gorma.NullableTimestamp {
			field.Timestamp = true
			field.Nullable = true
			field.Description = "nullable timestamp (soft delete)"
		}

		s.RelationalFields[name] = field
	}

}

func parsemModelArgs(args ...interface{}) (gorma.FieldType, func()) {

	var (
		fieldType gorma.FieldType
		dslp      func()
		ok        bool
	)

	parseFieldType := func(expected string, index int) {
		if fieldType, ok = args[index].(gorma.FieldType); !ok {
			invalidArgError(expected, args[index])
		}
	}
	parseDSL := func(index int, success, failure func()) {
		if dslp, ok = args[index].(func()); ok {
			success()
		} else {
			failure()
		}
	}

	success := func() {}

	switch len(args) {
	case 0:
		fieldType = gorma.NotFound
	case 1:
		parseDSL(0, success, func() { parseFieldType("DataType or func()", 0) })
	case 2:
		parseFieldType("FieldType", 0)
		parseDSL(1, success, func() { invalidArgError("DSL", args[1]) })

	default:
		dsl.ReportError("too many arguments in call to Attribute")
	}

	return fieldType, dslp

}

// DatabaseFieldName creates sql tag necessary to name the
// database column
func DatabaseFieldName(d string) {
	if r, ok := relationalFieldDefinition(false); ok {
		r.DatabaseFieldName = d
	}
}
<|endoftext|>


<commit_before>package jws

import (
	"encoding/json"
	"errors"
	"net/url"

	"github.com/lestrrat/go-jwx/buffer"
	"github.com/lestrrat/go-jwx/internal/emap"
	"github.com/lestrrat/go-jwx/jwa"
)

func NewHeader() *Header {
	return &Header{
		EssentialHeader: &EssentialHeader{},
		PrivateParams:   map[string]interface{}{},
	}
}

func (h *Header) Set(key string, value interface{}) error {
	switch key {
	case "alg":
		var v jwa.SignatureAlgorithm
		s, ok := value.(string)
		if ok {
			v = jwa.SignatureAlgorithm(s)
		} else {
			v, ok = value.(jwa.SignatureAlgorithm)
			if !ok {
				return ErrInvalidHeaderValue
			}
		}
		h.Algorithm = v
	case "cty":
		v, ok := value.(string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		h.ContentType = v
	case "kid":
		v, ok := value.(string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		h.KeyID = v
	case "typ":
		v, ok := value.(string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		h.Type = v
	case "x5t":
		v, ok := value.(string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		h.X509CertThumbprint = v
	case "x5t#256":
		v, ok := value.(string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		h.X509CertThumbprintS256 = v
	case "x5c":
		v, ok := value.([]string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		h.X509CertChain = v
	case "crit":
		v, ok := value.([]string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		h.Critical = v
	case "jku":
		v, ok := value.(string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		u, err := url.Parse(v)
		if err != nil {
			return ErrInvalidHeaderValue
		}
		h.JwkSetURL = u
	case "x5u":
		v, ok := value.(string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		u, err := url.Parse(v)
		if err != nil {
			return ErrInvalidHeaderValue
		}
		h.X509Url = u
	default:
		h.PrivateParams[key] = value
	}
	return nil
}

func (h1 *Header) Merge(h2 *Header) (*Header, error) {
	if h2 == nil {
		return nil, errors.New("merge target is nil")
	}

	h3 := NewHeader()
	if err := h3.Copy(h1); err != nil {
		return nil, err
	}

	h3.EssentialHeader.Merge(h2.EssentialHeader)

	for k, v := range h2.PrivateParams {
		h3.PrivateParams[k] = v
	}

	return h3, nil
}

func (h1 *EssentialHeader) Merge(h2 *EssentialHeader) {
	if h2.Algorithm != "" {
		h1.Algorithm = h2.Algorithm
	}

	if h2.ContentType != "" {
		h1.ContentType = h2.ContentType
	}

	if h2.JwkSetURL != nil {
		h1.JwkSetURL = h2.JwkSetURL
	}

	if h2.KeyID != "" {
		h1.KeyID = h2.KeyID
	}

	if h2.Type != "" {
		h1.Type = h2.Type
	}

	if h2.X509Url != nil {
		h1.X509Url = h2.X509Url
	}

	if h2.X509CertChain != nil {
		h1.X509CertChain = h2.X509CertChain
	}

	if h2.X509CertThumbprint != "" {
		h1.X509CertThumbprint = h2.X509CertThumbprint
	}

	if h2.X509CertThumbprintS256 != "" {
		h1.X509CertThumbprintS256 = h2.X509CertThumbprintS256
	}
}

func (h1 *Header) Copy(h2 *Header) error {
	if h1 == nil {
		return errors.New("copy destination is nil")
	}
	if h2 == nil {
		return errors.New("copy target is nil")
	}

	h1.EssentialHeader.Copy(h2.EssentialHeader)

	for k, v := range h2.PrivateParams {
		h1.PrivateParams[k] = v
	}

	return nil
}

func (h1 *EssentialHeader) Copy(h2 *EssentialHeader) {
	h1.Algorithm = h2.Algorithm
	h1.ContentType = h2.ContentType
	h1.JwkSetURL = h2.JwkSetURL
	h1.KeyID = h2.KeyID
	h1.Type = h2.Type
	h1.X509Url = h2.X509Url
	h1.X509CertChain = h2.X509CertChain
	h1.X509CertThumbprint = h2.X509CertThumbprint
	h1.X509CertThumbprintS256 = h2.X509CertThumbprintS256
}

func (h Header) MarshalJSON() ([]byte, error) {
	return emap.MergeMarshal(h.EssentialHeader, h.PrivateParams)
}

func (h *Header) UnmarshalJSON(data []byte) error {
	if h.EssentialHeader == nil {
		h.EssentialHeader = &EssentialHeader{}
	}
	if h.PrivateParams == nil {
		h.PrivateParams = map[string]interface{}{}
	}
	return emap.MergeUnmarshal(data, h.EssentialHeader, &h.PrivateParams)
}

func (h *EssentialHeader) Construct(m map[string]interface{}) error {
	r := emap.Hmap(m)
	if alg, err := r.GetString("alg"); err == nil {
		h.Algorithm = jwa.SignatureAlgorithm(alg)
	}
	if h.Algorithm == "" {
		h.Algorithm = jwa.NoSignature
	}
	h.ContentType, _ = r.GetString("cty")
	h.KeyID, _ = r.GetString("kid")
	h.Type, _ = r.GetString("typ")
	h.X509CertThumbprint, _ = r.GetString("x5t")
	h.X509CertThumbprintS256, _ = r.GetString("x5t#256")
	if v, err := r.GetStringSlice("crit"); err != nil {
		h.Critical = v
	}
	if v, err := r.GetStringSlice("x5c"); err != nil {
		h.X509CertChain = v
	}
	if v, err := r.GetString("jku"); err == nil {
		u, err := url.Parse(v)
		if err == nil {
			h.JwkSetURL = u
		}
	}

	if v, err := r.GetString("x5u"); err == nil {
		u, err := url.Parse(v)
		if err == nil {
			h.X509Url = u
		}
	}

	return nil
}

func (h Header) Base64Encode() ([]byte, error) {
	b, err := json.Marshal(h)
	if err != nil {
		return nil, err
	}

	return buffer.Buffer(b).Base64Encode()
}

func (e EncodedHeader) MarshalJSON() ([]byte, error) {
	buf, err := json.Marshal(e.Header)
	if err != nil {
		return nil, err
	}

	buf, err = buffer.Buffer(buf).Base64Encode()
	if err != nil {
		return nil, err
	}

	return json.Marshal(string(buf))
}

func (e *EncodedHeader) UnmarshalJSON(buf []byte) error {
	b := buffer.Buffer{}
	// base646 json string -> json object representation of header
	if err := json.Unmarshal(buf, &b); err != nil {
		return err
	}

	if err := json.Unmarshal(b.Bytes(), &e.Header); err != nil {
		return err
	}

	e.Source = b

	return nil
}

func NewSignature() *Signature {
	h1 := NewHeader()
	h2 := NewHeader()
	return &Signature{
		PublicHeader:    h1,
		ProtectedHeader: &EncodedHeader{Header: h2},
	}
}

func (s Signature) MergedHeaders() MergedHeader {
	return MergedHeader{
		ProtectedHeader: s.ProtectedHeader,
		PublicHeader:    s.PublicHeader,
	}
}

func (h MergedHeader) KeyID() string {
	if hp := h.ProtectedHeader; hp != nil {
		if hp.KeyID != "" {
			return hp.KeyID
		}
	}

	if hp := h.PublicHeader; hp != nil {
		if hp.KeyID != "" {
			return hp.KeyID
		}
	}

	return ""
}

func (h MergedHeader) Algorithm() jwa.SignatureAlgorithm {
	if hp := h.ProtectedHeader; hp != nil {
		return hp.Algorithm
	}
	return jwa.NoSignature
}

// LookupSignature looks up a particular signature entry using
// the `kid` value
func (m Message) LookupSignature(kid string) []Signature {
	sigs := []Signature{}
	for _, sig := range m.Signatures {
		if sig.MergedHeaders().KeyID() != kid {
			continue
		}

		sigs = append(sigs, sig)
	}
	return sigs
}
<commit_msg>jws: Add jwk header field in JWS header<commit_after>package jws

import (
	"encoding/json"
	"errors"
	"net/url"

	"github.com/lestrrat/go-jwx/buffer"
	"github.com/lestrrat/go-jwx/internal/emap"
	"github.com/lestrrat/go-jwx/jwa"
	"github.com/lestrrat/go-jwx/jwk"
)

func NewHeader() *Header {
	return &Header{
		EssentialHeader: &EssentialHeader{},
		PrivateParams:   map[string]interface{}{},
	}
}

func (h *Header) Set(key string, value interface{}) error {
	switch key {
	case "alg":
		var v jwa.SignatureAlgorithm
		s, ok := value.(string)
		if ok {
			v = jwa.SignatureAlgorithm(s)
		} else {
			v, ok = value.(jwa.SignatureAlgorithm)
			if !ok {
				return ErrInvalidHeaderValue
			}
		}
		h.Algorithm = v
	case "cty":
		v, ok := value.(string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		h.ContentType = v
	case "kid":
		v, ok := value.(string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		h.KeyID = v
	case "typ":
		v, ok := value.(string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		h.Type = v
	case "x5t":
		v, ok := value.(string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		h.X509CertThumbprint = v
	case "x5t#256":
		v, ok := value.(string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		h.X509CertThumbprintS256 = v
	case "x5c":
		v, ok := value.([]string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		h.X509CertChain = v
	case "crit":
		v, ok := value.([]string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		h.Critical = v
	case "jwk":
		v, ok := value.(jwk.Key)
		if !ok {
			return ErrInvalidHeaderValue
		}
		h.Jwk = v
	case "jku":
		v, ok := value.(string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		u, err := url.Parse(v)
		if err != nil {
			return ErrInvalidHeaderValue
		}
		h.JwkSetURL = u
	case "x5u":
		v, ok := value.(string)
		if !ok {
			return ErrInvalidHeaderValue
		}
		u, err := url.Parse(v)
		if err != nil {
			return ErrInvalidHeaderValue
		}
		h.X509Url = u
	default:
		h.PrivateParams[key] = value
	}
	return nil
}

func (h1 *Header) Merge(h2 *Header) (*Header, error) {
	if h2 == nil {
		return nil, errors.New("merge target is nil")
	}

	h3 := NewHeader()
	if err := h3.Copy(h1); err != nil {
		return nil, err
	}

	h3.EssentialHeader.Merge(h2.EssentialHeader)

	for k, v := range h2.PrivateParams {
		h3.PrivateParams[k] = v
	}

	return h3, nil
}

func (h1 *EssentialHeader) Merge(h2 *EssentialHeader) {
	if h2.Algorithm != "" {
		h1.Algorithm = h2.Algorithm
	}

	if h2.ContentType != "" {
		h1.ContentType = h2.ContentType
	}

	if h2.Jwk != nil {
		h1.Jwk = h2.Jwk
	}

	if h2.JwkSetURL != nil {
		h1.JwkSetURL = h2.JwkSetURL
	}

	if h2.KeyID != "" {
		h1.KeyID = h2.KeyID
	}

	if h2.Type != "" {
		h1.Type = h2.Type
	}

	if h2.X509Url != nil {
		h1.X509Url = h2.X509Url
	}

	if h2.X509CertChain != nil {
		h1.X509CertChain = h2.X509CertChain
	}

	if h2.X509CertThumbprint != "" {
		h1.X509CertThumbprint = h2.X509CertThumbprint
	}

	if h2.X509CertThumbprintS256 != "" {
		h1.X509CertThumbprintS256 = h2.X509CertThumbprintS256
	}
}

func (h1 *Header) Copy(h2 *Header) error {
	if h1 == nil {
		return errors.New("copy destination is nil")
	}
	if h2 == nil {
		return errors.New("copy target is nil")
	}

	h1.EssentialHeader.Copy(h2.EssentialHeader)

	for k, v := range h2.PrivateParams {
		h1.PrivateParams[k] = v
	}

	return nil
}

func (h1 *EssentialHeader) Copy(h2 *EssentialHeader) {
	h1.Algorithm = h2.Algorithm
	h1.ContentType = h2.ContentType
	h1.Jwk = h2.Jwk
	h1.JwkSetURL = h2.JwkSetURL
	h1.KeyID = h2.KeyID
	h1.Type = h2.Type
	h1.X509Url = h2.X509Url
	h1.X509CertChain = h2.X509CertChain
	h1.X509CertThumbprint = h2.X509CertThumbprint
	h1.X509CertThumbprintS256 = h2.X509CertThumbprintS256
}

func (h Header) MarshalJSON() ([]byte, error) {
	return emap.MergeMarshal(h.EssentialHeader, h.PrivateParams)
}

func (h *Header) UnmarshalJSON(data []byte) error {
	if h.EssentialHeader == nil {
		h.EssentialHeader = &EssentialHeader{}
	}
	if h.PrivateParams == nil {
		h.PrivateParams = map[string]interface{}{}
	}
	return emap.MergeUnmarshal(data, h.EssentialHeader, &h.PrivateParams)
}

func (h *EssentialHeader) Construct(m map[string]interface{}) error {
	r := emap.Hmap(m)
	if alg, err := r.GetString("alg"); err == nil {
		h.Algorithm = jwa.SignatureAlgorithm(alg)
	}
	if h.Algorithm == "" {
		h.Algorithm = jwa.NoSignature
	}
	h.ContentType, _ = r.GetString("cty")
	h.KeyID, _ = r.GetString("kid")
	h.Type, _ = r.GetString("typ")
	h.X509CertThumbprint, _ = r.GetString("x5t")
	h.X509CertThumbprintS256, _ = r.GetString("x5t#256")
	if v, err := r.GetStringSlice("crit"); err != nil {
		h.Critical = v
	}
	if v, err := r.GetStringSlice("x5c"); err != nil {
		h.X509CertChain = v
	}
	if v, err := r.GetByteSlice("jwk"); err == nil {
		if jwks, err := jwk.Parse(v); err == nil {
			// we have at least 1 JWK
			h.Jwk = jwks.Keys[0]
		}
	}
	if v, err := r.GetString("jku"); err == nil {
		u, err := url.Parse(v)
		if err == nil {
			h.JwkSetURL = u
		}
	}

	if v, err := r.GetString("x5u"); err == nil {
		u, err := url.Parse(v)
		if err == nil {
			h.X509Url = u
		}
	}

	return nil
}

func (h Header) Base64Encode() ([]byte, error) {
	b, err := json.Marshal(h)
	if err != nil {
		return nil, err
	}

	return buffer.Buffer(b).Base64Encode()
}

func (e EncodedHeader) MarshalJSON() ([]byte, error) {
	buf, err := json.Marshal(e.Header)
	if err != nil {
		return nil, err
	}

	buf, err = buffer.Buffer(buf).Base64Encode()
	if err != nil {
		return nil, err
	}

	return json.Marshal(string(buf))
}

func (e *EncodedHeader) UnmarshalJSON(buf []byte) error {
	b := buffer.Buffer{}
	// base646 json string -> json object representation of header
	if err := json.Unmarshal(buf, &b); err != nil {
		return err
	}

	if err := json.Unmarshal(b.Bytes(), &e.Header); err != nil {
		return err
	}

	e.Source = b

	return nil
}

func NewSignature() *Signature {
	h1 := NewHeader()
	h2 := NewHeader()
	return &Signature{
		PublicHeader:    h1,
		ProtectedHeader: &EncodedHeader{Header: h2},
	}
}

func (s Signature) MergedHeaders() MergedHeader {
	return MergedHeader{
		ProtectedHeader: s.ProtectedHeader,
		PublicHeader:    s.PublicHeader,
	}
}

func (h MergedHeader) KeyID() string {
	if hp := h.ProtectedHeader; hp != nil {
		if hp.KeyID != "" {
			return hp.KeyID
		}
	}

	if hp := h.PublicHeader; hp != nil {
		if hp.KeyID != "" {
			return hp.KeyID
		}
	}

	return ""
}

func (h MergedHeader) Algorithm() jwa.SignatureAlgorithm {
	if hp := h.ProtectedHeader; hp != nil {
		return hp.Algorithm
	}
	return jwa.NoSignature
}

// LookupSignature looks up a particular signature entry using
// the `kid` value
func (m Message) LookupSignature(kid string) []Signature {
	sigs := []Signature{}
	for _, sig := range m.Signatures {
		if sig.MergedHeaders().KeyID() != kid {
			continue
		}

		sigs = append(sigs, sig)
	}
	return sigs
}
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes 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 generators has the generators for the import-boss utility.
package generators

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"sort"
	"strings"

	"k8s.io/gengo/args"
	"k8s.io/gengo/generator"
	"k8s.io/gengo/namer"
	"k8s.io/gengo/types"

	"github.com/golang/glog"
)

const (
	importBossFileType = "import-boss"
)

// NameSystems returns the name system used by the generators in this package.
func NameSystems() namer.NameSystems {
	return namer.NameSystems{
		"raw": namer.NewRawNamer("", nil),
	}
}

// DefaultNameSystem returns the default name system for ordering the types to be
// processed by the generators in this package.
func DefaultNameSystem() string {
	return "raw"
}

// Packages makes the import-boss package definition.
func Packages(c *generator.Context, arguments *args.GeneratorArgs) generator.Packages {
	pkgs := generator.Packages{}
	c.FileTypes = map[string]generator.FileType{
		importBossFileType: importRuleFile{},
	}

	for _, p := range c.Universe {
		if !arguments.InputIncludes(p) {
			// Don't run on e.g. third party dependencies.
			continue
		}
		savedPackage := p
		pkgs = append(pkgs, &generator.DefaultPackage{
			PackageName: p.Name,
			PackagePath: p.Path,
			// GeneratorFunc returns a list of generators. Each generator makes a
			// single file.
			GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) {
				return []generator.Generator{&importRules{
					myPackage: savedPackage,
				}}
			},
			FilterFunc: func(c *generator.Context, t *types.Type) bool {
				return false
			},
		})
	}

	return pkgs
}

// A single import restriction rule.
type Rule struct {
	// All import paths that match this regexp...
	SelectorRegexp string
	// ... must have one of these prefixes ...
	AllowedPrefixes []string
	// ... and must not have one of these prefixes.
	ForbiddenPrefixes []string
}

type fileFormat struct {
	CurrentImports []string

	Rules []Rule
}

func readFile(path string) (*fileFormat, error) {
	currentBytes, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, fmt.Errorf("couldn't read %v: %v", path, err)
	}

	var current fileFormat
	err = json.Unmarshal(currentBytes, &current)
	if err != nil {
		return nil, fmt.Errorf("couldn't unmarshal %v: %v", path, err)
	}
	return &current, nil
}

func writeFile(path string, ff *fileFormat) error {
	raw, err := json.MarshalIndent(ff, "", "\t")
	if err != nil {
		return fmt.Errorf("couldn't format data for file %v.\n%#v", path, ff)
	}
	f, err := os.Create(path)
	if err != nil {
		return fmt.Errorf("couldn't open %v for writing: %v", path, err)
	}
	defer f.Close()
	_, err = f.Write(raw)
	return err
}

// This does the actual checking, since it knows the literal destination file.
type importRuleFile struct{}

func (importRuleFile) AssembleFile(f *generator.File, path string) error {
	return nil
}

// TODO: make a flag to enable this, or expose this information in some other way.
func (importRuleFile) listEntireImportTree(f *generator.File, path string) error {
	// If the file exists, populate its current imports. This is mostly to help
	// humans figure out what they need to fix.
	if _, err := os.Stat(path); err != nil {
		// Ignore packages which haven't opted in by adding an .import-restrictions file.
		return nil
	}

	current, err := readFile(path)
	if err != nil {
		return err
	}

	current.CurrentImports = []string{}
	for v := range f.Imports {
		current.CurrentImports = append(current.CurrentImports, v)
	}
	sort.Strings(current.CurrentImports)

	return writeFile(path, current)
}

// removeLastDir removes the last directory, but leaves the file name
// unchanged. It returns the new path and the removed directory. So:
// "a/b/c/file" -> ("a/b/file", "c")
func removeLastDir(path string) (newPath, removedDir string) {
	dir, file := filepath.Split(path)
	dir = strings.TrimSuffix(dir, string(filepath.Separator))
	return filepath.Join(filepath.Dir(dir), file), filepath.Base(dir)
}

// Keep going up a directory until we find an .import-restrictions file.
func recursiveRead(path string) (*fileFormat, string, error) {
	for {
		if _, err := os.Stat(path); err == nil {
			ff, err := readFile(path)
			return ff, path, err
		}

		nextPath, removedDir := removeLastDir(path)
		if nextPath == path || removedDir == "src" {
			break
		}
		path = nextPath
	}
	return nil, "", nil
}

func (importRuleFile) VerifyFile(f *generator.File, path string) error {
	rules, actualPath, err := recursiveRead(path)
	if err != nil {
		return fmt.Errorf("error finding rules file: %v", err)
	}

	if rules == nil {
		// No restrictions on this directory.
		return nil
	}

	for _, r := range rules.Rules {
		re, err := regexp.Compile(r.SelectorRegexp)
		if err != nil {
			return fmt.Errorf("regexp `%s` in file %q doesn't compile: %v", r.SelectorRegexp, actualPath, err)
		}
		for v := range f.Imports {
			glog.V(4).Infof("Checking %v matches %v: %v\n", r.SelectorRegexp, v, re.MatchString(v))
			if !re.MatchString(v) {
				continue
			}
			for _, forbidden := range r.ForbiddenPrefixes {
				glog.V(4).Infof("Checking %v against %v\n", v, forbidden)
				if strings.HasPrefix(v, forbidden) {
					return fmt.Errorf("import %v has forbidden prefix %v", v, forbidden)
				}
			}
			found := false
			for _, allowed := range r.AllowedPrefixes {
				glog.V(4).Infof("Checking %v against %v\n", v, allowed)
				if strings.HasPrefix(v, allowed) {
					found = true
					break
				}
			}
			if !found {
				return fmt.Errorf("import %v did not match any allowed prefix", v)
			}
		}
	}
	if len(rules.Rules) > 0 {
		glog.V(2).Infof("%v passes rules found in %v\n", path, actualPath)
	}

	return nil
}

// importRules produces a file with a set for a single type.
type importRules struct {
	myPackage *types.Package
	imports   namer.ImportTracker
}

var (
	_ = generator.Generator(&importRules{})
	_ = generator.FileType(importRuleFile{})
)

func (r *importRules) Name() string                                                  { return "import rules" }
func (r *importRules) Filter(*generator.Context, *types.Type) bool                   { return false }
func (r *importRules) Namers(*generator.Context) namer.NameSystems                   { return nil }
func (r *importRules) PackageVars(*generator.Context) []string                       { return []string{} }
func (r *importRules) PackageConsts(*generator.Context) []string                     { return []string{} }
func (r *importRules) GenerateType(*generator.Context, *types.Type, io.Writer) error { return nil }
func (r *importRules) Filename() string                                              { return ".import-restrictions" }
func (r *importRules) FileType() string                                              { return importBossFileType }
func (r *importRules) Init(c *generator.Context, w io.Writer) error                  { return nil }
func (r *importRules) Finalize(*generator.Context, io.Writer) error                  { return nil }

func dfsImports(dest *[]string, seen map[string]bool, p *types.Package) {
	for _, p2 := range p.Imports {
		if seen[p2.Path] {
			continue
		}
		seen[p2.Path] = true
		dfsImports(dest, seen, p2)
		*dest = append(*dest, p2.Path)
	}
}

func (r *importRules) Imports(*generator.Context) []string {
	all := []string{}
	dfsImports(&all, map[string]bool{}, r.myPackage)
	return all
}
<commit_msg>report all import errors one time instead of exiting while found one import error<commit_after>/*
Copyright 2016 The Kubernetes 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 generators has the generators for the import-boss utility.
package generators

import (
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"sort"
	"strings"

	"k8s.io/gengo/args"
	"k8s.io/gengo/generator"
	"k8s.io/gengo/namer"
	"k8s.io/gengo/types"

	"github.com/golang/glog"
)

const (
	importBossFileType = "import-boss"
)

// NameSystems returns the name system used by the generators in this package.
func NameSystems() namer.NameSystems {
	return namer.NameSystems{
		"raw": namer.NewRawNamer("", nil),
	}
}

// DefaultNameSystem returns the default name system for ordering the types to be
// processed by the generators in this package.
func DefaultNameSystem() string {
	return "raw"
}

// Packages makes the import-boss package definition.
func Packages(c *generator.Context, arguments *args.GeneratorArgs) generator.Packages {
	pkgs := generator.Packages{}
	c.FileTypes = map[string]generator.FileType{
		importBossFileType: importRuleFile{},
	}

	for _, p := range c.Universe {
		if !arguments.InputIncludes(p) {
			// Don't run on e.g. third party dependencies.
			continue
		}
		savedPackage := p
		pkgs = append(pkgs, &generator.DefaultPackage{
			PackageName: p.Name,
			PackagePath: p.Path,
			// GeneratorFunc returns a list of generators. Each generator makes a
			// single file.
			GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) {
				return []generator.Generator{&importRules{
					myPackage: savedPackage,
				}}
			},
			FilterFunc: func(c *generator.Context, t *types.Type) bool {
				return false
			},
		})
	}

	return pkgs
}

// A single import restriction rule.
type Rule struct {
	// All import paths that match this regexp...
	SelectorRegexp string
	// ... must have one of these prefixes ...
	AllowedPrefixes []string
	// ... and must not have one of these prefixes.
	ForbiddenPrefixes []string
}

type fileFormat struct {
	CurrentImports []string

	Rules []Rule
}

func readFile(path string) (*fileFormat, error) {
	currentBytes, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, fmt.Errorf("couldn't read %v: %v", path, err)
	}

	var current fileFormat
	err = json.Unmarshal(currentBytes, &current)
	if err != nil {
		return nil, fmt.Errorf("couldn't unmarshal %v: %v", path, err)
	}
	return &current, nil
}

func writeFile(path string, ff *fileFormat) error {
	raw, err := json.MarshalIndent(ff, "", "\t")
	if err != nil {
		return fmt.Errorf("couldn't format data for file %v.\n%#v", path, ff)
	}
	f, err := os.Create(path)
	if err != nil {
		return fmt.Errorf("couldn't open %v for writing: %v", path, err)
	}
	defer f.Close()
	_, err = f.Write(raw)
	return err
}

// This does the actual checking, since it knows the literal destination file.
type importRuleFile struct{}

func (importRuleFile) AssembleFile(f *generator.File, path string) error {
	return nil
}

// TODO: make a flag to enable this, or expose this information in some other way.
func (importRuleFile) listEntireImportTree(f *generator.File, path string) error {
	// If the file exists, populate its current imports. This is mostly to help
	// humans figure out what they need to fix.
	if _, err := os.Stat(path); err != nil {
		// Ignore packages which haven't opted in by adding an .import-restrictions file.
		return nil
	}

	current, err := readFile(path)
	if err != nil {
		return err
	}

	current.CurrentImports = []string{}
	for v := range f.Imports {
		current.CurrentImports = append(current.CurrentImports, v)
	}
	sort.Strings(current.CurrentImports)

	return writeFile(path, current)
}

// removeLastDir removes the last directory, but leaves the file name
// unchanged. It returns the new path and the removed directory. So:
// "a/b/c/file" -> ("a/b/file", "c")
func removeLastDir(path string) (newPath, removedDir string) {
	dir, file := filepath.Split(path)
	dir = strings.TrimSuffix(dir, string(filepath.Separator))
	return filepath.Join(filepath.Dir(dir), file), filepath.Base(dir)
}

// Keep going up a directory until we find an .import-restrictions file.
func recursiveRead(path string) (*fileFormat, string, error) {
	for {
		if _, err := os.Stat(path); err == nil {
			ff, err := readFile(path)
			return ff, path, err
		}

		nextPath, removedDir := removeLastDir(path)
		if nextPath == path || removedDir == "src" {
			break
		}
		path = nextPath
	}
	return nil, "", nil
}

func (importRuleFile) VerifyFile(f *generator.File, path string) error {
	rules, actualPath, err := recursiveRead(path)
	if err != nil {
		return fmt.Errorf("error finding rules file: %v", err)
	}

	if rules == nil {
		// No restrictions on this directory.
		return nil
	}

	forbiddenImports := map[string]string{}
	allowedMismatchedImports := []string{}
	for _, r := range rules.Rules {
		re, err := regexp.Compile(r.SelectorRegexp)
		if err != nil {
			return fmt.Errorf("regexp `%s` in file %q doesn't compile: %v", r.SelectorRegexp, actualPath, err)
		}
		for v := range f.Imports {
			glog.V(4).Infof("Checking %v matches %v: %v\n", r.SelectorRegexp, v, re.MatchString(v))
			if !re.MatchString(v) {
				continue
			}
			for _, forbidden := range r.ForbiddenPrefixes {
				glog.V(4).Infof("Checking %v against %v\n", v, forbidden)
				if strings.HasPrefix(v, forbidden) {
					forbiddenImports[v] = forbidden
				}
			}
			found := false
			for _, allowed := range r.AllowedPrefixes {
				glog.V(4).Infof("Checking %v against %v\n", v, allowed)
				if strings.HasPrefix(v, allowed) {
					found = true
					break
				}
			}
			if !found {
				allowedMismatchedImports = append(allowedMismatchedImports, v)
			}
		}
	}

	if len(forbiddenImports) > 0 || len(allowedMismatchedImports) > 0 {
		var errorBuilder strings.Builder
		for i, f := range forbiddenImports {
			fmt.Fprintf(&errorBuilder, "import %v has forbidden prefix %v\n", i, f)
		}
		if len(allowedMismatchedImports) > 0 {
			sort.Sort(sort.StringSlice(allowedMismatchedImports))
			fmt.Fprintf(&errorBuilder, "the following imports did not match any allowed prefix:\n")
			for _, i := range allowedMismatchedImports {
				fmt.Fprintf(&errorBuilder, "  %v\n", i)
			}
		}
		return errors.New(errorBuilder.String())
	}
	if len(rules.Rules) > 0 {
		glog.V(2).Infof("%v passes rules found in %v\n", path, actualPath)
	}

	return nil
}

// importRules produces a file with a set for a single type.
type importRules struct {
	myPackage *types.Package
	imports   namer.ImportTracker
}

var (
	_ = generator.Generator(&importRules{})
	_ = generator.FileType(importRuleFile{})
)

func (r *importRules) Name() string                                                  { return "import rules" }
func (r *importRules) Filter(*generator.Context, *types.Type) bool                   { return false }
func (r *importRules) Namers(*generator.Context) namer.NameSystems                   { return nil }
func (r *importRules) PackageVars(*generator.Context) []string                       { return []string{} }
func (r *importRules) PackageConsts(*generator.Context) []string                     { return []string{} }
func (r *importRules) GenerateType(*generator.Context, *types.Type, io.Writer) error { return nil }
func (r *importRules) Filename() string                                              { return ".import-restrictions" }
func (r *importRules) FileType() string                                              { return importBossFileType }
func (r *importRules) Init(c *generator.Context, w io.Writer) error                  { return nil }
func (r *importRules) Finalize(*generator.Context, io.Writer) error                  { return nil }

func dfsImports(dest *[]string, seen map[string]bool, p *types.Package) {
	for _, p2 := range p.Imports {
		if seen[p2.Path] {
			continue
		}
		seen[p2.Path] = true
		dfsImports(dest, seen, p2)
		*dest = append(*dest, p2.Path)
	}
}

func (r *importRules) Imports(*generator.Context) []string {
	all := []string{}
	dfsImports(&all, map[string]bool{}, r.myPackage)
	return all
}
<|endoftext|>


<commit_before>// A simple database migrator for PostgreSQL.

package gomigrate

import (
	"database/sql"
	"errors"
	"io/ioutil"
	"log"
	"path/filepath"
	"regexp"
	"sort"
)

const (
	migrationTableName = "gomigrate"
)

var (
	upMigrationFile       = regexp.MustCompile(`(\d+)_(\w+)_up.sql`)
	downMigrationFile     = regexp.MustCompile(`(\d+)_(\w+)_down.sql`)
	InvalidMigrationFile  = errors.New("Invalid migration file")
	InvalidMigrationPair  = errors.New("Invalid pair of migration files")
	InvalidMigrationsPath = errors.New("Invalid migrations path")
)

type Migrator struct {
	DB             *sql.DB
	MigrationsPath string
	migrations     map[uint64]*Migration
}

// Returns a new migrator.
func NewMigrator(db *sql.DB, migrationsPath string) (*Migrator, error) {
	// Normalize the migrations path.
	path := []byte(migrationsPath)
	pathLength := len(path)
	if path[pathLength-1] != '/' {
		path = append(path, '/')
	}

	log.Printf("Migrations path: %s", path)

	migrator := Migrator{
		db,
		string(path),
		make(map[uint64]*Migration),
	}

	if err := migrator.createMigrationsTable(); err != nil {
		return nil, err
	}

	// Get all metadata from the database.
	if err := migrator.fetchMigrations(); err != nil {
		return nil, err
	}
	if err := migrator.getMigrationStatuses(); err != nil {
		return nil, err
	}

	return &migrator, nil
}

const selectTablesSql = "SELECT tablename FROM pg_catalog.pg_tables"

// Returns true if the migration table already exists.
func (m *Migrator) migrationTableExists() (bool, error) {
	rows, err := m.DB.Query(selectTablesSql)
	if err != nil {
		log.Printf("Error checking for migration table: %v", err)
		return false, err
	}
	for rows.Next() {
		var tableName string
		err := rows.Scan(&tableName)
		if err != nil {
			return false, err
		}
		if tableName == migrationTableName {
			log.Printf("Found migrations table: %v", tableName)
			return true, nil
		}
	}

	log.Print("Migrations table not found")

	return false, nil
}

const createMigrationTableSql = `
CREATE TABLE gomigrate (
  id           SERIAL       PRIMARY KEY,
  migration_id INT          UNIQUE NOT NULL,
  name         VARCHAR(100) UNIQUE NOT NULL,
  status       INT          NOT NULL
)`

// Creates the migrations table if it doesn't exist.
func (m *Migrator) createMigrationsTable() error {
	status, err := m.migrationTableExists()
	if err != nil {
		return err
	}
	if status {
		return nil
	}

	log.Print("Creating migrations table")

	_, err = m.DB.Query(createMigrationTableSql)
	if err != nil {
		log.Fatalf("Error creating migrations table: %v", err)
	}

	log.Printf("Created migrations table: %s", migrationTableName)

	return nil
}

// Populates a migrator with a sorted list of migrations from the file system.
func (m *Migrator) fetchMigrations() error {
	pathGlob := append([]byte(m.MigrationsPath), []byte("*")...)

	log.Printf("Migrations path glob: %s", pathGlob)

	matches, err := filepath.Glob(string(pathGlob))
	if err != nil {
		log.Fatalf("Error while globbing migrations: %v", err)
	}

	for _, match := range matches {
		num, migrationType, name, err := parseMigrationPath(match)
		if err != nil {
			log.Printf("Invalid migration file found: %s", match)
			continue
		}

		log.Printf("Migration file found: %s", match)

		migration, ok := m.migrations[num]
		if !ok {
			migration = &Migration{Id: num, Name: name, Status: Inactive}
			m.migrations[num] = migration
		}
		if migrationType == "up" {
			migration.UpPath = match
		} else {
			migration.DownPath = match
		}
	}

	// Validate each migration.
	for _, migration := range m.migrations {
		if !migration.valid() {
			path := migration.UpPath
			if path == "" {
				path = migration.DownPath
			}
			log.Printf("Invalid migration pair for path: %s", path)
			return InvalidMigrationPair
		}
	}

	log.Printf("Migrations file pairs found: %v", len(m.migrations))

	return nil
}

const migrationStatusSql = "SELECT status FROM gomigrate WHERE name = $1"

// Queries the migration table to determine the status of each
// migration.
func (m *Migrator) getMigrationStatuses() error {
	for _, migration := range m.migrations {
		rows, err := m.DB.Query(migrationStatusSql, migration.Name)
		if err != nil {
			log.Printf(
				"Error getting migration status for %s: %v",
				migration.Name,
				err,
			)
			return err
		}
		for rows.Next() {
			var status int
			err := rows.Scan(&status)
			if err != nil {
				log.Printf("Error getting migration status: %v", err)
				return err
			}
			migration.Status = status
			log.Printf(
				"Migration %s found with status: %v",
				migration.Name,
				status,
			)
		}
	}
	return nil
}

// Returns a sorted list of migration ids for a given status.
func (m *Migrator) Migrations(status int) []*Migration {
	// Sort all migration ids.
	ids := make([]uint64, 0)
	for id, _ := range m.migrations {
		ids = append(ids, id)
	}
	sort.Sort(uint64slice(ids))

	// Find ids for the given status.
	migrations := make([]*Migration, 0)
	for _, id := range ids {
		migration := m.migrations[id]
		if migration.Status == status {
			migrations = append(migrations, migration)
		}
	}
	return migrations
}

const migrationLogInsertSql = `
INSERT INTO gomigrate (migration_id, name, status) values ($1, $2, $3)
`

// Applies all inactive migrations.
func (m *Migrator) Migrate() error {
	for _, migration := range m.Migrations(Inactive) {
		log.Printf("Applying migration: %s", migration.Name)

		sql, err := ioutil.ReadFile(migration.UpPath)
		if err != nil {
			log.Printf("Error reading up migration: %s", migration.Name)
			return err
		}
		transaction, err := m.DB.Begin()
		if err != nil {
			log.Printf("Error opening transaction: %v", err)
			return err
		}
		// Perform the migration.
		if _, err = transaction.Exec(string(sql)); err != nil {
			log.Printf("Error executing migration: %v", err)
			if rollbackErr := transaction.Rollback(); rollbackErr != nil {
				log.Printf("Error rolling back transaction: %v", rollbackErr)
				return rollbackErr
			}
			return err
		}
		// Log the exception in the migrations table.
		_, err = transaction.Exec(
			migrationLogInsertSql,
			migration.Id,
			migration.Name,
			Active,
		)
		if err != nil {
			log.Printf("Error logging migration: %v", err)
			if rollbackErr := transaction.Rollback(); rollbackErr != nil {
				log.Printf("Error rolling back transaction: %v", rollbackErr)
				return rollbackErr
			}
			return err
		}
		if err := transaction.Commit(); err != nil {
			log.Printf("Error commiting transaction: %v", err)
			return err
		}

		// Do this as the last step to ensure that the database has
		// been updated.
		migration.Status = Active
	}
	return nil
}

var (
	NoActiveMigrations = errors.New("No active migrations to rollback")
)

const (
	migrationLogUpdateSql = "UPDATE gomigrate SET status = $1 WHERE migration_id = $2"
)

// Rolls back the last migration
func (m *Migrator) Rollback() error {
	migrations := m.Migrations(Active)

	if len(migrations) == 0 {
		return NoActiveMigrations
	}

	lastMigration := migrations[len(migrations)-1]

	log.Printf("Rolling back migration: %v", lastMigration.Name)

	sql, err := ioutil.ReadFile(lastMigration.DownPath)
	if err != nil {
		log.Printf("Error reading migration: %s", lastMigration.DownPath)
		return err
	}
	transaction, err := m.DB.Begin()
	if err != nil {
		log.Printf("Error creating transaction: %v", err)
		return err
	}
	_, err = transaction.Exec(string(sql))
	if err != nil {
		transaction.Rollback()
		log.Printf("Error rolling back transaction: %v", err)
		return err
	}

	// Change the status in the migrations table.
	_, err = transaction.Exec(
		migrationLogUpdateSql,
		Inactive,
		lastMigration.Id,
	)
	if err != nil {
		log.Printf("Error logging rollback: %v", err)
		if rollbackErr := transaction.Rollback(); rollbackErr != nil {
			log.Printf("Error rolling back transaction: %v", rollbackErr)
			return rollbackErr
		}
		return err
	}

	err = transaction.Commit()
	if err != nil {
		log.Printf("Error commiting transaction: %v", err)
		return err
	}
	lastMigration.Status = Inactive
	return nil
}
<commit_msg>Check for existence of table in initializer<commit_after>// A simple database migrator for PostgreSQL.

package gomigrate

import (
	"database/sql"
	"errors"
	"io/ioutil"
	"log"
	"path/filepath"
	"regexp"
	"sort"
)

const (
	migrationTableName = "gomigrate"
)

var (
	upMigrationFile       = regexp.MustCompile(`(\d+)_(\w+)_up.sql`)
	downMigrationFile     = regexp.MustCompile(`(\d+)_(\w+)_down.sql`)
	InvalidMigrationFile  = errors.New("Invalid migration file")
	InvalidMigrationPair  = errors.New("Invalid pair of migration files")
	InvalidMigrationsPath = errors.New("Invalid migrations path")
)

type Migrator struct {
	DB             *sql.DB
	MigrationsPath string
	migrations     map[uint64]*Migration
}

// Returns a new migrator.
func NewMigrator(db *sql.DB, migrationsPath string) (*Migrator, error) {
	// Normalize the migrations path.
	path := []byte(migrationsPath)
	pathLength := len(path)
	if path[pathLength-1] != '/' {
		path = append(path, '/')
	}

	log.Printf("Migrations path: %s", path)

	migrator := Migrator{
		db,
		string(path),
		make(map[uint64]*Migration),
	}

	// Create the migrations table if it doesn't exist.
	tableExists, err := migrator.migrationTableExists()
	if err != nil {
		return nil, err
	}
	if !tableExists {
		if err := migrator.createMigrationsTable(); err != nil {
			return nil, err
		}
	}

	// Get all metadata from the database.
	if err := migrator.fetchMigrations(); err != nil {
		return nil, err
	}
	if err := migrator.getMigrationStatuses(); err != nil {
		return nil, err
	}

	return &migrator, nil
}

const selectTablesSql = "SELECT tablename FROM pg_catalog.pg_tables"

// Returns true if the migration table already exists.
func (m *Migrator) migrationTableExists() (bool, error) {
	rows, err := m.DB.Query(selectTablesSql)
	if err != nil {
		log.Printf("Error checking for migration table: %v", err)
		return false, err
	}
	for rows.Next() {
		var tableName string
		err := rows.Scan(&tableName)
		if err != nil {
			return false, err
		}
		if tableName == migrationTableName {
			log.Printf("Found migrations table: %v", tableName)
			return true, nil
		}
	}

	log.Print("Migrations table not found")

	return false, nil
}

const createMigrationTableSql = `
CREATE TABLE gomigrate (
  id           SERIAL       PRIMARY KEY,
  migration_id INT          UNIQUE NOT NULL,
  name         VARCHAR(100) UNIQUE NOT NULL,
  status       INT          NOT NULL
)`

// Creates the migrations table if it doesn't exist.
func (m *Migrator) createMigrationsTable() error {
	log.Print("Creating migrations table")

	_, err := m.DB.Query(createMigrationTableSql)
	if err != nil {
		log.Fatalf("Error creating migrations table: %v", err)
	}

	log.Printf("Created migrations table: %s", migrationTableName)

	return nil
}

// Populates a migrator with a sorted list of migrations from the file system.
func (m *Migrator) fetchMigrations() error {
	pathGlob := append([]byte(m.MigrationsPath), []byte("*")...)

	log.Printf("Migrations path glob: %s", pathGlob)

	matches, err := filepath.Glob(string(pathGlob))
	if err != nil {
		log.Fatalf("Error while globbing migrations: %v", err)
	}

	for _, match := range matches {
		num, migrationType, name, err := parseMigrationPath(match)
		if err != nil {
			log.Printf("Invalid migration file found: %s", match)
			continue
		}

		log.Printf("Migration file found: %s", match)

		migration, ok := m.migrations[num]
		if !ok {
			migration = &Migration{Id: num, Name: name, Status: Inactive}
			m.migrations[num] = migration
		}
		if migrationType == "up" {
			migration.UpPath = match
		} else {
			migration.DownPath = match
		}
	}

	// Validate each migration.
	for _, migration := range m.migrations {
		if !migration.valid() {
			path := migration.UpPath
			if path == "" {
				path = migration.DownPath
			}
			log.Printf("Invalid migration pair for path: %s", path)
			return InvalidMigrationPair
		}
	}

	log.Printf("Migrations file pairs found: %v", len(m.migrations))

	return nil
}

const migrationStatusSql = "SELECT status FROM gomigrate WHERE name = $1"

// Queries the migration table to determine the status of each
// migration.
func (m *Migrator) getMigrationStatuses() error {
	for _, migration := range m.migrations {
		rows, err := m.DB.Query(migrationStatusSql, migration.Name)
		if err != nil {
			log.Printf(
				"Error getting migration status for %s: %v",
				migration.Name,
				err,
			)
			return err
		}
		for rows.Next() {
			var status int
			err := rows.Scan(&status)
			if err != nil {
				log.Printf("Error getting migration status: %v", err)
				return err
			}
			migration.Status = status
			log.Printf(
				"Migration %s found with status: %v",
				migration.Name,
				status,
			)
		}
	}
	return nil
}

// Returns a sorted list of migration ids for a given status.
func (m *Migrator) Migrations(status int) []*Migration {
	// Sort all migration ids.
	ids := make([]uint64, 0)
	for id, _ := range m.migrations {
		ids = append(ids, id)
	}
	sort.Sort(uint64slice(ids))

	// Find ids for the given status.
	migrations := make([]*Migration, 0)
	for _, id := range ids {
		migration := m.migrations[id]
		if migration.Status == status {
			migrations = append(migrations, migration)
		}
	}
	return migrations
}

const migrationLogInsertSql = `
INSERT INTO gomigrate (migration_id, name, status) values ($1, $2, $3)
`

// Applies all inactive migrations.
func (m *Migrator) Migrate() error {
	for _, migration := range m.Migrations(Inactive) {
		log.Printf("Applying migration: %s", migration.Name)

		sql, err := ioutil.ReadFile(migration.UpPath)
		if err != nil {
			log.Printf("Error reading up migration: %s", migration.Name)
			return err
		}
		transaction, err := m.DB.Begin()
		if err != nil {
			log.Printf("Error opening transaction: %v", err)
			return err
		}
		// Perform the migration.
		if _, err = transaction.Exec(string(sql)); err != nil {
			log.Printf("Error executing migration: %v", err)
			if rollbackErr := transaction.Rollback(); rollbackErr != nil {
				log.Printf("Error rolling back transaction: %v", rollbackErr)
				return rollbackErr
			}
			return err
		}
		// Log the exception in the migrations table.
		_, err = transaction.Exec(
			migrationLogInsertSql,
			migration.Id,
			migration.Name,
			Active,
		)
		if err != nil {
			log.Printf("Error logging migration: %v", err)
			if rollbackErr := transaction.Rollback(); rollbackErr != nil {
				log.Printf("Error rolling back transaction: %v", rollbackErr)
				return rollbackErr
			}
			return err
		}
		if err := transaction.Commit(); err != nil {
			log.Printf("Error commiting transaction: %v", err)
			return err
		}

		// Do this as the last step to ensure that the database has
		// been updated.
		migration.Status = Active
	}
	return nil
}

var (
	NoActiveMigrations = errors.New("No active migrations to rollback")
)

const (
	migrationLogUpdateSql = "UPDATE gomigrate SET status = $1 WHERE migration_id = $2"
)

// Rolls back the last migration
func (m *Migrator) Rollback() error {
	migrations := m.Migrations(Active)

	if len(migrations) == 0 {
		return NoActiveMigrations
	}

	lastMigration := migrations[len(migrations)-1]

	log.Printf("Rolling back migration: %v", lastMigration.Name)

	sql, err := ioutil.ReadFile(lastMigration.DownPath)
	if err != nil {
		log.Printf("Error reading migration: %s", lastMigration.DownPath)
		return err
	}
	transaction, err := m.DB.Begin()
	if err != nil {
		log.Printf("Error creating transaction: %v", err)
		return err
	}
	_, err = transaction.Exec(string(sql))
	if err != nil {
		transaction.Rollback()
		log.Printf("Error rolling back transaction: %v", err)
		return err
	}

	// Change the status in the migrations table.
	_, err = transaction.Exec(
		migrationLogUpdateSql,
		Inactive,
		lastMigration.Id,
	)
	if err != nil {
		log.Printf("Error logging rollback: %v", err)
		if rollbackErr := transaction.Rollback(); rollbackErr != nil {
			log.Printf("Error rolling back transaction: %v", rollbackErr)
			return rollbackErr
		}
		return err
	}

	err = transaction.Commit()
	if err != nil {
		log.Printf("Error commiting transaction: %v", err)
		return err
	}
	lastMigration.Status = Inactive
	return nil
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2014 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package wire

import (
	"bytes"
	"fmt"
	fct "github.com/FactomProject/factoid"
	"io"
)

var _ = fmt.Printf

type IMsgFactoidTX interface {
	// Set the Transaction to be carried by this message.
	SetTransaction(fct.ITransaction)
	// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
	// This is part of the Message interface implementation.
	BtcEncode(w io.Writer, pver uint32) error
	// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
	// This is part of the Message interface implementation.
	BtcDecode(r io.Reader, pver uint32) error
	// Command returns the protocol command string for the message.  This is part
	// of the Message interface implementation.
	Command() string
	// MaxPayloadLength returns the maximum length the payload can be for the
	// receiver.  This is part of the Message interface implementation.
	MaxPayloadLength(pver uint32) uint32
	// NewMsgCommitEntry returns a new bitcoin Commit Entry message that conforms to
	// the Message interface.
	NewMsgFactoidTX() IMsgFactoidTX
	// Check whether the msg can pass the message level validations
	// such as timestamp, signiture and etc
	IsValid() bool
	// Create a sha hash from the message binary (output of BtcEncode)
	Sha() (ShaHash, error)
}

// MsgCommitEntry implements the Message interface and represents a factom
// Commit-Entry message.  It is used by client to commit the entry before
// revealing it.
type MsgFactoidTX struct {
	IMsgFactoidTX
	Transaction fct.ITransaction
}

// Accessor to set the Transaction for a message.
func (msg *MsgFactoidTX) SetTransaction(transaction fct.ITransaction) {
	msg.Transaction = transaction
}

// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgFactoidTX) BtcEncode(w io.Writer, pver uint32) error {

	data, err := msg.Transaction.MarshalBinary()
	if err != nil {
		return err
	}

	err = writeVarBytes(w, pver, data)
	if err != nil {
		return err
	}

	return nil
}

// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgFactoidTX) BtcDecode(r io.Reader, pver uint32) error {

	data, err := readVarBytes(r, pver, uint32(MaxAppMsgPayload), CmdEBlock)
	if err != nil {
		return err
	}

	msg.Transaction = new(fct.Transaction)
	err = msg.Transaction.UnmarshalBinary(data)
	if err != nil {
		return err
	}

	return nil
}

// Command returns the protocol command string for the message.  This is part
// of the Message interface implementation.
func (msg *MsgFactoidTX) Command() string {
	return CmdFactoidTX
}

// MaxPayloadLength returns the maximum length the payload can be for the
// receiver.  This is part of the Message interface implementation.
func (msg *MsgFactoidTX) MaxPayloadLength(pver uint32) uint32 {
	return MaxAppMsgPayload
}

// NewMsgCommitEntry returns a new bitcoin Commit Entry message that conforms to
// the Message interface.
func NewMsgFactoidTX() IMsgFactoidTX {
	return &MsgFactoidTX{}
}

// Check whether the msg can pass the message level validations
// such as timestamp, signiture and etc
func (msg *MsgFactoidTX) IsValid() bool {
	err := msg.Transaction.Validate()
	if err != nil {
		return false
	}
	err = msg.Transaction.ValidateSignatures()
	if err != nil {
		return false
	}
	return true
}

// Create a sha hash from the message binary (output of BtcEncode)
func (msg *MsgFactoidTX) Sha() (ShaHash, error) {

	buf := bytes.NewBuffer(nil)
	msg.BtcEncode(buf, ProtocolVersion)
	var sha ShaHash
	_ = sha.SetBytes(Sha256(buf.Bytes()))

	return sha, nil
}
<commit_msg>Fix for api change<commit_after>// Copyright (c) 2013-2014 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package wire

import (
	"bytes"
	"fmt"
	fct "github.com/FactomProject/factoid"
	"io"
)

var _ = fmt.Printf

type IMsgFactoidTX interface {
	// Set the Transaction to be carried by this message.
	SetTransaction(fct.ITransaction)
	// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
	// This is part of the Message interface implementation.
	BtcEncode(w io.Writer, pver uint32) error
	// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
	// This is part of the Message interface implementation.
	BtcDecode(r io.Reader, pver uint32) error
	// Command returns the protocol command string for the message.  This is part
	// of the Message interface implementation.
	Command() string
	// MaxPayloadLength returns the maximum length the payload can be for the
	// receiver.  This is part of the Message interface implementation.
	MaxPayloadLength(pver uint32) uint32
	// NewMsgCommitEntry returns a new bitcoin Commit Entry message that conforms to
	// the Message interface.
	NewMsgFactoidTX() IMsgFactoidTX
	// Check whether the msg can pass the message level validations
	// such as timestamp, signiture and etc
	IsValid() bool
	// Create a sha hash from the message binary (output of BtcEncode)
	Sha() (ShaHash, error)
}

// MsgCommitEntry implements the Message interface and represents a factom
// Commit-Entry message.  It is used by client to commit the entry before
// revealing it.
type MsgFactoidTX struct {
	IMsgFactoidTX
	Transaction fct.ITransaction
}

// Accessor to set the Transaction for a message.
func (msg *MsgFactoidTX) SetTransaction(transaction fct.ITransaction) {
	msg.Transaction = transaction
}

// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgFactoidTX) BtcEncode(w io.Writer, pver uint32) error {

	data, err := msg.Transaction.MarshalBinary()
	if err != nil {
		return err
	}

	err = writeVarBytes(w, pver, data)
	if err != nil {
		return err
	}

	return nil
}

// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgFactoidTX) BtcDecode(r io.Reader, pver uint32) error {

	data, err := readVarBytes(r, pver, uint32(MaxAppMsgPayload), CmdEBlock)
	if err != nil {
		return err
	}

	msg.Transaction = new(fct.Transaction)
	err = msg.Transaction.UnmarshalBinary(data)
	if err != nil {
		return err
	}

	return nil
}

// Command returns the protocol command string for the message.  This is part
// of the Message interface implementation.
func (msg *MsgFactoidTX) Command() string {
	return CmdFactoidTX
}

// MaxPayloadLength returns the maximum length the payload can be for the
// receiver.  This is part of the Message interface implementation.
func (msg *MsgFactoidTX) MaxPayloadLength(pver uint32) uint32 {
	return MaxAppMsgPayload
}

// NewMsgCommitEntry returns a new bitcoin Commit Entry message that conforms to
// the Message interface.
func NewMsgFactoidTX() IMsgFactoidTX {
	return &MsgFactoidTX{}
}

// Check whether the msg can pass the message level validations
// such as timestamp, signiture and etc
func (msg *MsgFactoidTX) IsValid() bool {
	err := msg.Transaction.Validate(1)
	if err != nil {
		return false
	}
	err = msg.Transaction.ValidateSignatures()
	if err != nil {
		return false
	}
	return true
}

// Create a sha hash from the message binary (output of BtcEncode)
func (msg *MsgFactoidTX) Sha() (ShaHash, error) {

	buf := bytes.NewBuffer(nil)
	msg.BtcEncode(buf, ProtocolVersion)
	var sha ShaHash
	_ = sha.SetBytes(Sha256(buf.Bytes()))

	return sha, nil
}
<|endoftext|>


<commit_before>package cluster

import (
	"fmt"
	"strings"

	"github.com/appcelerator/amp/cli"
	"github.com/appcelerator/amp/cmd/amplifier/server/configuration"
	"github.com/spf13/cobra"
	flag "github.com/spf13/pflag"
)

type docker struct {
	Volumes []string
}

type clusterOpts struct {
	docker
	managers      int
	workers       int
	provider      string
	name          string
	tag           string
	registration  string
	notifications bool
	// TODO: not clear yet if we'll need this
	options map[string]string
}

var (
	opts = &clusterOpts{
		docker: docker{
			Volumes: []string{},
		},
		managers:      3,
		workers:       2,
		provider:      "local",
		name:          "",
		tag:           "latest",
		registration:  configuration.RegistrationDefault,
		notifications: true,
		// TODO: not clear yet if we'll need this
		options: map[string]string{},
	}
)

// NewClusterCommand returns a new instance of the cluster command.
func NewClusterCommand(c cli.Interface) *cobra.Command {
	cmd := &cobra.Command{
		Use:     "cluster",
		Short:   "Cluster management operations",
		PreRunE: cli.NoArgs,
		RunE:    c.ShowHelp,
	}

	cmd.PersistentFlags().StringSliceVarP(&opts.Volumes, "volume", "v", []string{}, "Bind mount a volume")

	cmd.AddCommand(NewCreateCommand(c))
	cmd.AddCommand(NewListCommand(c))
	cmd.AddCommand(NewRemoveCommand(c))
	cmd.AddCommand(NewStatusCommand(c))
	cmd.AddCommand(NewUpdateCommand(c))
	cmd.AddCommand(NewNodeCommand(c))
	return cmd
}

// Strip provider prefix from CLI options to provider-specific options that will be supplied to the plugin.
// For example, `--aws-region us-west-2` becomes `--region us-west-2` (as expected by the aws plugin)
func stripPrefixes(cmd *cobra.Command, args []string) []string {
	cmd.Flags().Visit(func(f *flag.Flag) {
		if strings.HasPrefix(f.Name, opts.provider) {
			name := strings.TrimPrefix(f.Name, opts.provider+"-")

			if strings.HasSuffix(f.Value.Type(), "Slice") {
				// error shouldn't happen here since we're asking for the slice it says it has
				slice, _ := cmd.Flags().GetStringSlice(f.Name)
				for _, val := range slice {
					opt := fmt.Sprintf("--%s", name)
					args = append(args, opt, val)
				}

			} else {
				opt := fmt.Sprintf("--%s", name)
				args = append(args, opt, f.Value.String())
			}

		}
	})
	return args
}

func runPluginCommand(c cli.Interface, cmd *cobra.Command, command string) error {
	// args and env will be supplied to the cluster plugin container
	var args []string
	var env map[string]string
	//	env = map[string]string{"TAG": opts.tag, "REGISTRATION": opts.registration, "NOTIFICATIONS": strconv.FormatBool(opts.notifications)}

	args = append(args, command)
	args = stripPrefixes(cmd, args)

	config := PluginConfig{
		Provider:   opts.provider,
		DockerOpts: opts.docker,
		// TODO: not clear yet if we'll need this
		Options: opts.options,
	}

	p, err := NewPlugin(config)
	if err != nil {
		return err
	}

	return p.Run(c, args, env)
}
<commit_msg>add environment from options before running plugin<commit_after>package cluster

import (
	"fmt"
	"strconv"
	"strings"

	"github.com/appcelerator/amp/cli"
	"github.com/appcelerator/amp/cmd/amplifier/server/configuration"
	"github.com/spf13/cobra"
	flag "github.com/spf13/pflag"
)

type docker struct {
	Volumes []string
}

type clusterOpts struct {
	docker
	managers      int
	workers       int
	provider      string
	name          string
	tag           string
	registration  string
	notifications bool
	// TODO: not clear yet if we'll need this
	options map[string]string
}

var (
	opts = &clusterOpts{
		docker: docker{
			Volumes: []string{},
		},
		managers:      3,
		workers:       2,
		provider:      "local",
		name:          "",
		tag:           "latest",
		registration:  configuration.RegistrationDefault,
		notifications: true,
		// TODO: not clear yet if we'll need this
		options: map[string]string{},
	}
)

// NewClusterCommand returns a new instance of the cluster command.
func NewClusterCommand(c cli.Interface) *cobra.Command {
	cmd := &cobra.Command{
		Use:     "cluster",
		Short:   "Cluster management operations",
		PreRunE: cli.NoArgs,
		RunE:    c.ShowHelp,
	}

	cmd.PersistentFlags().StringSliceVarP(&opts.Volumes, "volume", "v", []string{}, "Bind mount a volume")

	cmd.AddCommand(NewCreateCommand(c))
	cmd.AddCommand(NewListCommand(c))
	cmd.AddCommand(NewRemoveCommand(c))
	cmd.AddCommand(NewStatusCommand(c))
	cmd.AddCommand(NewUpdateCommand(c))
	cmd.AddCommand(NewNodeCommand(c))
	return cmd
}

// Strip provider prefix from CLI options to provider-specific options that will be supplied to the plugin.
// For example, `--aws-region us-west-2` becomes `--region us-west-2` (as expected by the aws plugin)
func stripPrefixes(cmd *cobra.Command, args []string) []string {
	cmd.Flags().Visit(func(f *flag.Flag) {
		if strings.HasPrefix(f.Name, opts.provider) {
			name := strings.TrimPrefix(f.Name, opts.provider+"-")

			if strings.HasSuffix(f.Value.Type(), "Slice") {
				// error shouldn't happen here since we're asking for the slice it says it has
				slice, _ := cmd.Flags().GetStringSlice(f.Name)
				for _, val := range slice {
					opt := fmt.Sprintf("--%s", name)
					args = append(args, opt, val)
				}

			} else {
				opt := fmt.Sprintf("--%s", name)
				args = append(args, opt, f.Value.String())
			}

		}
	})
	return args
}

func runPluginCommand(c cli.Interface, cmd *cobra.Command, command string) error {
	// args and env will be supplied to the cluster plugin container
	var args []string
	env := map[string]string{}
	if opts.tag != "" {
		env["TAG"] = opts.tag
	}
	if opts.registration != "" {
		env["REGISTRATION"] = opts.registration
	}
	if opts.notifications {
		env["NOTIFICATIONS"] = strconv.FormatBool(opts.notifications)
	}

	args = append(args, command)
	args = stripPrefixes(cmd, args)

	config := PluginConfig{
		Provider:   opts.provider,
		DockerOpts: opts.docker,
		// TODO: not clear yet if we'll need this
		Options: opts.options,
	}

	p, err := NewPlugin(config)
	if err != nil {
		return err
	}

	return p.Run(c, args, env)
}
<|endoftext|>