<commit_before>/*
 * This file is part of the KubeVirt project
 *
 * 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.
 *
 * Copyright 2018 Red Hat, Inc.
 *
 */

package tests_test

import (
	. "github.com/onsi/ginkgo"
	"github.com/onsi/ginkgo/extensions/table"
	. "github.com/onsi/gomega"
	k8sv1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

	v1 "kubevirt.io/client-go/api/v1"
	"kubevirt.io/client-go/kubecli"
	"kubevirt.io/kubevirt/pkg/virt-launcher/virtwrap/api"
	"kubevirt.io/kubevirt/tests"
)

var _ = Describe("[Serial]VMIDefaults", func() {
	var err error
	var virtClient kubecli.KubevirtClient

	var vmi *v1.VirtualMachineInstance

	BeforeEach(func() {
		virtClient, err = kubecli.GetKubevirtClient()
		tests.PanicOnError(err)
	})

	Context("Disk defaults", func() {
		BeforeEach(func() {
			tests.BeforeTestCleanup()
			// create VMI with missing disk target
			vmi = tests.NewRandomVMI()
			vmi.Spec = v1.VirtualMachineInstanceSpec{
				Domain: v1.DomainSpec{
					Devices: v1.Devices{
						Disks: []v1.Disk{
							{Name: "testdisk"},
						},
					},
					Resources: v1.ResourceRequirements{
						Requests: k8sv1.ResourceList{
							k8sv1.ResourceMemory: resource.MustParse("8192Ki"),
						},
					},
				},
				Volumes: []v1.Volume{
					{
						Name: "testdisk",
						VolumeSource: v1.VolumeSource{
							ContainerDisk: &v1.ContainerDiskSource{
								Image: "dummy",
							},
						},
					},
				},
			}
		})

		It("[test_id:4115]Should be applied to VMIs", func() {
			// create the VMI first
			_, err = virtClient.VirtualMachineInstance(tests.NamespaceTestDefault).Create(vmi)
			Expect(err).ToNot(HaveOccurred())

			newVMI, err := virtClient.VirtualMachineInstance(tests.NamespaceTestDefault).Get(vmi.Name, &metav1.GetOptions{})
			Expect(err).ToNot(HaveOccurred())

			// check defaults
			disk := newVMI.Spec.Domain.Devices.Disks[0]
			Expect(disk.Disk).ToNot(BeNil(), "DiskTarget should not be nil")
			Expect(disk.Disk.Bus).ToNot(BeEmpty(), "DiskTarget's bus should not be empty")
		})

	})

	Context("MemBalloon defaults", func() {
		var kvConfiguration v1.KubeVirtConfiguration

		BeforeEach(func() {
			tests.BeforeTestCleanup()
			// create VMI with missing disk target
			vmi = tests.NewRandomVMI()

			kv := tests.GetCurrentKv(virtClient)
			kvConfiguration = kv.Spec.Configuration
		})

		AfterEach(func() {
			tests.UpdateKubeVirtConfigValueAndWait(kvConfiguration)
		})

		It("[test_id:4556]Should be present in domain", func() {
			By("Creating a virtual machine")
			vmi, err = virtClient.VirtualMachineInstance(tests.NamespaceTestDefault).Create(vmi)
			Expect(err).ToNot(HaveOccurred())

			By("Waiting for successful start")
			tests.WaitForSuccessfulVMIStart(vmi)

			By("Getting domain of vmi")
			domain, err := tests.GetRunningVMIDomainSpec(vmi)
			Expect(err).ToNot(HaveOccurred())

			expected := api.MemBalloon{
				Model: "virtio",
				Stats: &api.Stats{
					Period: 10,
				},
				Address: &api.Address{
					Type:     "pci",
					Domain:   "0x0000",
					Bus:      "0x03",
					Slot:     "0x00",
					Function: "0x0",
				},
			}
			Expect(domain.Devices.Ballooning).ToNot(BeNil(), "There should be default memballoon device")
			Expect(*domain.Devices.Ballooning).To(Equal(expected), "Default to virtio model and 10 seconds pooling")
		})

		table.DescribeTable("Should override period in domain if present in virt-config ", func(period uint32, expected api.MemBalloon) {
			By("Adding period to virt-config")
			kvConfigurationCopy := kvConfiguration.DeepCopy()
			kvConfigurationCopy.MemBalloonStatsPeriod = &period
			tests.UpdateKubeVirtConfigValueAndWait(*kvConfigurationCopy)

			By("Creating a virtual machine")
			vmi, err = virtClient.VirtualMachineInstance(tests.NamespaceTestDefault).Create(vmi)
			Expect(err).ToNot(HaveOccurred())

			By("Waiting for successful start")
			tests.WaitForSuccessfulVMIStart(vmi)

			By("Getting domain of vmi")
			domain, err := tests.GetRunningVMIDomainSpec(vmi)

			Expect(err).ToNot(HaveOccurred())
			Expect(domain.Devices.Ballooning).ToNot(BeNil(), "There should be memballoon device")
			Expect(*domain.Devices.Ballooning).To(Equal(expected))
		},
			table.Entry("[test_id:4557]with period 12", uint32(12), api.MemBalloon{
				Model: "virtio",
				Stats: &api.Stats{
					Period: 12,
				},
				Address: &api.Address{
					Type:     "pci",
					Domain:   "0x0000",
					Bus:      "0x03",
					Slot:     "0x00",
					Function: "0x0",
				},
			}),
			table.Entry("[test_id:4558]with period 0", uint32(0), api.MemBalloon{
				Model: "virtio",
				Address: &api.Address{
					Type:     "pci",
					Domain:   "0x0000",
					Bus:      "0x03",
					Slot:     "0x00",
					Function: "0x0",
				},
			}),
		)

		It("[test_id:4559]Should not be present in domain ", func() {
			By("Creating a virtual machine with autoAttachmemballoon set to false")
			f := false
			vmi.Spec.Domain.Devices.AutoattachMemBalloon = &f
			vmi, err = virtClient.VirtualMachineInstance(tests.NamespaceTestDefault).Create(vmi)
			Expect(err).ToNot(HaveOccurred())

			By("Waiting for successful start")
			tests.WaitForSuccessfulVMIStart(vmi)

			By("Getting domain of vmi")
			domain, err := tests.GetRunningVMIDomainSpec(vmi)
			Expect(err).ToNot(HaveOccurred())

			expected := api.MemBalloon{
				Model: "none",
			}
			Expect(domain.Devices.Ballooning).ToNot(BeNil(), "There should be memballoon device")
			Expect(*domain.Devices.Ballooning).To(Equal(expected))
		})

	})

})
<commit_msg>adjust pci address tests to consider the new virtio-iscsi controller<commit_after>/*
 * This file is part of the KubeVirt project
 *
 * 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.
 *
 * Copyright 2018 Red Hat, Inc.
 *
 */

package tests_test

import (
	. "github.com/onsi/ginkgo"
	"github.com/onsi/ginkgo/extensions/table"
	. "github.com/onsi/gomega"
	k8sv1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

	v1 "kubevirt.io/client-go/api/v1"
	"kubevirt.io/client-go/kubecli"
	"kubevirt.io/kubevirt/pkg/virt-launcher/virtwrap/api"
	"kubevirt.io/kubevirt/tests"
)

var _ = Describe("[Serial]VMIDefaults", func() {
	var err error
	var virtClient kubecli.KubevirtClient

	var vmi *v1.VirtualMachineInstance

	BeforeEach(func() {
		virtClient, err = kubecli.GetKubevirtClient()
		tests.PanicOnError(err)
	})

	Context("Disk defaults", func() {
		BeforeEach(func() {
			tests.BeforeTestCleanup()
			// create VMI with missing disk target
			vmi = tests.NewRandomVMI()
			vmi.Spec = v1.VirtualMachineInstanceSpec{
				Domain: v1.DomainSpec{
					Devices: v1.Devices{
						Disks: []v1.Disk{
							{Name: "testdisk"},
						},
					},
					Resources: v1.ResourceRequirements{
						Requests: k8sv1.ResourceList{
							k8sv1.ResourceMemory: resource.MustParse("8192Ki"),
						},
					},
				},
				Volumes: []v1.Volume{
					{
						Name: "testdisk",
						VolumeSource: v1.VolumeSource{
							ContainerDisk: &v1.ContainerDiskSource{
								Image: "dummy",
							},
						},
					},
				},
			}
		})

		It("[test_id:4115]Should be applied to VMIs", func() {
			// create the VMI first
			_, err = virtClient.VirtualMachineInstance(tests.NamespaceTestDefault).Create(vmi)
			Expect(err).ToNot(HaveOccurred())

			newVMI, err := virtClient.VirtualMachineInstance(tests.NamespaceTestDefault).Get(vmi.Name, &metav1.GetOptions{})
			Expect(err).ToNot(HaveOccurred())

			// check defaults
			disk := newVMI.Spec.Domain.Devices.Disks[0]
			Expect(disk.Disk).ToNot(BeNil(), "DiskTarget should not be nil")
			Expect(disk.Disk.Bus).ToNot(BeEmpty(), "DiskTarget's bus should not be empty")
		})

	})

	Context("MemBalloon defaults", func() {
		var kvConfiguration v1.KubeVirtConfiguration

		BeforeEach(func() {
			tests.BeforeTestCleanup()
			// create VMI with missing disk target
			vmi = tests.NewRandomVMI()

			kv := tests.GetCurrentKv(virtClient)
			kvConfiguration = kv.Spec.Configuration
		})

		AfterEach(func() {
			tests.UpdateKubeVirtConfigValueAndWait(kvConfiguration)
		})

		It("[test_id:4556]Should be present in domain", func() {
			By("Creating a virtual machine")
			vmi, err = virtClient.VirtualMachineInstance(tests.NamespaceTestDefault).Create(vmi)
			Expect(err).ToNot(HaveOccurred())

			By("Waiting for successful start")
			tests.WaitForSuccessfulVMIStart(vmi)

			By("Getting domain of vmi")
			domain, err := tests.GetRunningVMIDomainSpec(vmi)
			Expect(err).ToNot(HaveOccurred())

			expected := api.MemBalloon{
				Model: "virtio",
				Stats: &api.Stats{
					Period: 10,
				},
				Address: &api.Address{
					Type:     "pci",
					Domain:   "0x0000",
					Bus:      "0x04",
					Slot:     "0x00",
					Function: "0x0",
				},
			}
			Expect(domain.Devices.Ballooning).ToNot(BeNil(), "There should be default memballoon device")
			Expect(*domain.Devices.Ballooning).To(Equal(expected), "Default to virtio model and 10 seconds pooling")
		})

		table.DescribeTable("Should override period in domain if present in virt-config ", func(period uint32, expected api.MemBalloon) {
			By("Adding period to virt-config")
			kvConfigurationCopy := kvConfiguration.DeepCopy()
			kvConfigurationCopy.MemBalloonStatsPeriod = &period
			tests.UpdateKubeVirtConfigValueAndWait(*kvConfigurationCopy)

			By("Creating a virtual machine")
			vmi, err = virtClient.VirtualMachineInstance(tests.NamespaceTestDefault).Create(vmi)
			Expect(err).ToNot(HaveOccurred())

			By("Waiting for successful start")
			tests.WaitForSuccessfulVMIStart(vmi)

			By("Getting domain of vmi")
			domain, err := tests.GetRunningVMIDomainSpec(vmi)

			Expect(err).ToNot(HaveOccurred())
			Expect(domain.Devices.Ballooning).ToNot(BeNil(), "There should be memballoon device")
			Expect(*domain.Devices.Ballooning).To(Equal(expected))
		},
			table.Entry("[test_id:4557]with period 12", uint32(12), api.MemBalloon{
				Model: "virtio",
				Stats: &api.Stats{
					Period: 12,
				},
				Address: &api.Address{
					Type:     "pci",
					Domain:   "0x0000",
					Bus:      "0x04",
					Slot:     "0x00",
					Function: "0x0",
				},
			}),
			table.Entry("[test_id:4558]with period 0", uint32(0), api.MemBalloon{
				Model: "virtio",
				Address: &api.Address{
					Type:     "pci",
					Domain:   "0x0000",
					Bus:      "0x04",
					Slot:     "0x00",
					Function: "0x0",
				},
			}),
		)

		It("[test_id:4559]Should not be present in domain ", func() {
			By("Creating a virtual machine with autoAttachmemballoon set to false")
			f := false
			vmi.Spec.Domain.Devices.AutoattachMemBalloon = &f
			vmi, err = virtClient.VirtualMachineInstance(tests.NamespaceTestDefault).Create(vmi)
			Expect(err).ToNot(HaveOccurred())

			By("Waiting for successful start")
			tests.WaitForSuccessfulVMIStart(vmi)

			By("Getting domain of vmi")
			domain, err := tests.GetRunningVMIDomainSpec(vmi)
			Expect(err).ToNot(HaveOccurred())

			expected := api.MemBalloon{
				Model: "none",
			}
			Expect(domain.Devices.Ballooning).ToNot(BeNil(), "There should be memballoon device")
			Expect(*domain.Devices.Ballooning).To(Equal(expected))
		})

	})

})
<|endoftext|>


<commit_before>package dependencies

import (
	"fmt"

	"github.com/hashicorp/go-version"
	"github.com/parkr/auto-reply/ctx"
)

type RubyDependency struct {
	name       string
	constraint version.Constraints
	latest     *version.Version
	isOutdated *bool
}

func (d *RubyDependency) String() string {
	return fmt.Sprintf(
		"name:%+v constraint:%+v latest %+v isOutdated:%v",
		d.name, d.constraint, d.latest, *d.isOutdated,
	)
}

func (d *RubyDependency) GetName() string {
	return d.name
}

func (d *RubyDependency) GetConstraint() version.Constraints {
	return d.constraint
}

func (d *RubyDependency) GetLatestVersion(context *ctx.Context) *version.Version {
	if d.latest != nil {
		return d.latest
	}

	versionStr, err := context.RubyGems.GetLatestVersion(d.name)
	if err != nil {
		context.Log("dependencies: could not fetch latest version on rubygems for %s: %v", d.name, err)
		return nil
	}

	ver, err := version.NewVersion(versionStr)
	if err != nil {
		context.Log("dependencies: could not parse version %+v for %s: %v", versionStr, d.name, err)
		return nil
	}

	d.latest = ver
	return d.latest
}

func (d *RubyDependency) IsOutdated(context *ctx.Context) bool {
	if d.isOutdated != nil {
		return *d.isOutdated
	}

	isOutdated := !d.GetConstraint().Check(d.GetLatestVersion(context))
	d.isOutdated = &isOutdated
	return *d.isOutdated
}
<commit_msg>dependencies: fix a nil pointer exception in RubyDependency.IsOutdate()<commit_after>package dependencies

import (
	"fmt"

	"github.com/hashicorp/go-version"
	"github.com/parkr/auto-reply/ctx"
)

type RubyDependency struct {
	name       string
	constraint version.Constraints
	latest     *version.Version
	isOutdated *bool
}

func (d *RubyDependency) String() string {
	return fmt.Sprintf(
		"name:%+v constraint:%+v latest %+v isOutdated:%v",
		d.name, d.constraint, d.latest, *d.isOutdated,
	)
}

func (d *RubyDependency) GetName() string {
	return d.name
}

func (d *RubyDependency) GetConstraint() version.Constraints {
	return d.constraint
}

func (d *RubyDependency) GetLatestVersion(context *ctx.Context) *version.Version {
	if d.latest != nil {
		return d.latest
	}

	versionStr, err := context.RubyGems.GetLatestVersion(d.name)
	if err != nil {
		context.Log("dependencies: could not fetch latest version on rubygems for %s: %v", d.name, err)
		return nil
	}

	ver, err := version.NewVersion(versionStr)
	if err != nil {
		context.Log("dependencies: could not parse version %+v for %s: %v", versionStr, d.name, err)
		return nil
	}

	d.latest = ver
	return d.latest
}

func (d *RubyDependency) IsOutdated(context *ctx.Context) bool {
	if d.isOutdated != nil {
		return *d.isOutdated
	}

	latestVersion := d.GetLatestVersion(context)
	if latestVersion == nil {
		return false
	}

	isOutdated := !d.GetConstraint().Check(latestVersion)
	d.isOutdated = &isOutdated
	return *d.isOutdated
}
<|endoftext|>


<commit_before>// Copyright © 2016 Pennock Tech, LLC.
// All rights reserved, except as granted under license.
// Licensed per file LICENSE.txt

package length_test // import "go.pennock.tech/tabular/length"

import (
	"testing"

	"github.com/liquidgecka/testlib"

	"go.pennock.tech/tabular/length"
)

func TestStringLengths(t *testing.T) {
	T := testlib.NewT(t)
	defer T.Finish()

	for i, tuple := range []struct {
		s string
		b int // bytes length
		r int // runes length
		c int // cells length
	}{
		{"", 0, 0, 0},
		{"a", 1, 1, 1},
		{" b", 2, 2, 2},
		{"£", 2, 1, 1},              // %C2%A3
		{"⌘€", 6, 2, 2},             // %E2%8C%98 %E2%82%AC
		{"á", 2, 1, 1},              // %C3%A1
		{"\xCC\x81a", 3, 2, 1},      // %CC%81 = COMBINING ACUTE ACCENT
		{"ａ", 3, 1, 2},              // %EF%BD%81 = FULLWIDTH LATIN SMALL LETTER A
		{"\xE2\x80\xAA", 3, 1, 0},   //  %E2%80%AA = 202a = LEFT-TO-RIGHT EMBEDDING (a control, zero-width)
		{"a\xC2\xA0b", 4, 3, 3},     // %C2%A0 = a0 = NO-BREAK SPACE
		{"a\xE2\x80\x82b", 5, 3, 3}, // \xE2\x80\x82 = 2002 = EN SPACE
		{"a\xE2\x80\x83b", 5, 3, 3}, // \xE2\x80\x83 = 2003 = EM SPACE
		{"a\xE2\x80\x8bb", 5, 3, 2}, // \xE2\x80\x8B = 200b = ZERO WIDTH SPACE
		{"a\xE3\x80\x80b", 5, 3, 4}, // \xE3\x80\x80 = 3000 = IDEOGRAPHIC SPACE (2 wide)
		// Broken FIXME items (presence here is not API guarantee):
		{"💪", 4, 1, 1 /* want: 2 */}, // %F0%9F%92%AA = FLEXED BICEPS, followed by a space

	} {
		T.Equalf(length.StringBytes(tuple.s), tuple.b, "bytes length test [%d] string %q", i, tuple.s)
		T.Equalf(length.StringRunes(tuple.s), tuple.r, "runes length test [%d] string %q", i, tuple.s)
		T.Equalf(length.StringCells(tuple.s), tuple.c, "cells length test [%d] string %q", i, tuple.s)
	}

}

func TestMultiLineStringLengths(t *testing.T) {
	T := testlib.NewT(t)
	defer T.Finish()

	for i, tuple := range []struct {
		s string
		l int // lines count
		b int // bytes length
		r int // runes length
		c int // cells length
	}{
		{"", 0, 0, 0, 0},
		{"\n", 1, 0, 0, 0}, // "" on first line, drop second line
		{"\n\n", 2, 0, 0, 0},
		{"a", 1, 1, 1, 1},
		{"a\n", 1, 1, 1, 1},
		{"a\n\n", 2, 1, 1, 1},
		{"\nbbb", 2, 3, 3, 3},
		{"\nb\n", 2, 1, 1, 1},
		{"a\nbb\nc", 3, 2, 2, 2},
		{"a\nbb", 2, 2, 2, 2},
		{"aa\nb", 2, 2, 2, 2},
		{"\xCC\x81a\nbb", 2, 3, 2, 2}, // 1st line: 3 bytes, 2 runes, 1 cell
		{"\xCC\x81a\nb", 2, 3, 2, 1},
		{"\xCC\x81a\n\n", 2, 3, 2, 1},
		{"\xCC\x81a\nｂ", 2, 3, 2, 2}, // 2nd line FULLWIDTH LATIN SMALL LETTER B
		{"💪\nbb", 2, 4, 2, 2},        // 1st line: 4 bytes, 1 rune, currently 1 cell but should be 2
		{"💪\nb", 2, 4, 1, 1 /* want: 2 */},
		{"💪\n\n", 2, 4, 1, 1 /* want: 2 */},
		{"💪\nｂ", 2, 4, 1, 2}, // 2nd line is fullwidth, 2 cells (1st line theoretically 2, but currently 1)
	} {
		T.Equalf(len(length.Lines(tuple.s)), tuple.l, "lines count test [%d] string %q", i, tuple.s)
		T.Equalf(length.LongestLineBytes(tuple.s), tuple.b, "bytes line length test [%d] string %q", i, tuple.s)
		T.Equalf(length.LongestLineRunes(tuple.s), tuple.r, "runes line length test [%d] string %q", i, tuple.s)
		T.Equalf(length.LongestLineCells(tuple.s), tuple.c, "cells line length test [%d] string %q", i, tuple.s)
	}
}
<commit_msg>Fix fixme tests which were flagged as bad-value<commit_after>// Copyright © 2016 Pennock Tech, LLC.
// All rights reserved, except as granted under license.
// Licensed per file LICENSE.txt

package length_test // import "go.pennock.tech/tabular/length"

import (
	"testing"

	"github.com/liquidgecka/testlib"

	"go.pennock.tech/tabular/length"
)

func TestStringLengths(t *testing.T) {
	T := testlib.NewT(t)
	defer T.Finish()

	for i, tuple := range []struct {
		s string
		b int // bytes length
		r int // runes length
		c int // cells length
	}{
		{"", 0, 0, 0},
		{"a", 1, 1, 1},
		{" b", 2, 2, 2},
		{"£", 2, 1, 1},              // %C2%A3
		{"⌘€", 6, 2, 2},             // %E2%8C%98 %E2%82%AC
		{"á", 2, 1, 1},              // %C3%A1
		{"\xCC\x81a", 3, 2, 1},      // %CC%81 = COMBINING ACUTE ACCENT
		{"ａ", 3, 1, 2},              // %EF%BD%81 = FULLWIDTH LATIN SMALL LETTER A
		{"\xE2\x80\xAA", 3, 1, 0},   //  %E2%80%AA = 202a = LEFT-TO-RIGHT EMBEDDING (a control, zero-width)
		{"a\xC2\xA0b", 4, 3, 3},     // %C2%A0 = a0 = NO-BREAK SPACE
		{"a\xE2\x80\x82b", 5, 3, 3}, // \xE2\x80\x82 = 2002 = EN SPACE
		{"a\xE2\x80\x83b", 5, 3, 3}, // \xE2\x80\x83 = 2003 = EM SPACE
		{"a\xE2\x80\x8bb", 5, 3, 2}, // \xE2\x80\x8B = 200b = ZERO WIDTH SPACE
		{"a\xE3\x80\x80b", 5, 3, 4}, // \xE3\x80\x80 = 3000 = IDEOGRAPHIC SPACE (2 wide)
		{"💪", 4, 1, 2},              // %F0%9F%92%AA = FLEXED BICEPS, followed by a space

	} {
		T.Equalf(length.StringBytes(tuple.s), tuple.b, "bytes length test [%d] string %q", i, tuple.s)
		T.Equalf(length.StringRunes(tuple.s), tuple.r, "runes length test [%d] string %q", i, tuple.s)
		T.Equalf(length.StringCells(tuple.s), tuple.c, "cells length test [%d] string %q", i, tuple.s)
	}

}

func TestMultiLineStringLengths(t *testing.T) {
	T := testlib.NewT(t)
	defer T.Finish()

	for i, tuple := range []struct {
		s string
		l int // lines count
		b int // bytes length
		r int // runes length
		c int // cells length
	}{
		{"", 0, 0, 0, 0},
		{"\n", 1, 0, 0, 0}, // "" on first line, drop second line
		{"\n\n", 2, 0, 0, 0},
		{"a", 1, 1, 1, 1},
		{"a\n", 1, 1, 1, 1},
		{"a\n\n", 2, 1, 1, 1},
		{"\nbbb", 2, 3, 3, 3},
		{"\nb\n", 2, 1, 1, 1},
		{"a\nbb\nc", 3, 2, 2, 2},
		{"a\nbb", 2, 2, 2, 2},
		{"aa\nb", 2, 2, 2, 2},
		{"\xCC\x81a\nbb", 2, 3, 2, 2}, // 1st line: 3 bytes, 2 runes, 1 cell
		{"\xCC\x81a\nb", 2, 3, 2, 1},
		{"\xCC\x81a\n\n", 2, 3, 2, 1},
		{"\xCC\x81a\nｂ", 2, 3, 2, 2}, // 2nd line FULLWIDTH LATIN SMALL LETTER B
		{"💪\nbb", 2, 4, 2, 2},        // 1st line: 4 bytes, 1 rune, currently 1 cell but should be 2
		{"💪\nb", 2, 4, 1, 2},
		{"💪\n\n", 2, 4, 1, 2},
		{"💪\nｂ", 2, 4, 1, 2}, // 2nd line is fullwidth, 2 cells (1st line theoretically 2, but currently 1)
	} {
		T.Equalf(len(length.Lines(tuple.s)), tuple.l, "lines count test [%d] string %q", i, tuple.s)
		T.Equalf(length.LongestLineBytes(tuple.s), tuple.b, "bytes line length test [%d] string %q", i, tuple.s)
		T.Equalf(length.LongestLineRunes(tuple.s), tuple.r, "runes line length test [%d] string %q", i, tuple.s)
		T.Equalf(length.LongestLineCells(tuple.s), tuple.c, "cells line length test [%d] string %q", i, tuple.s)
	}
}
<|endoftext|>


<commit_before>package models

type ChannelContainer struct {
	Channel             Channel                  `json:"channel"`
	IsParticipant       bool                     `json:"isParticipant"`
	ParticipantCount    int                      `json:"participantCount"`
	ParticipantsPreview []string                 `json:"participantsPreview"`
	LastMessage         *ChannelMessageContainer `json:"lastMessage"`
}

func NewChannelContainer() *ChannelContainer {
	return &ChannelContainer{}
}

func PopulateChannelContainers(channelList []Channel, accountId int64) ([]*ChannelContainer, error) {
	channelContainers := make([]*ChannelContainer, len(channelList))

	var err error
	for i, channel := range channelList {
		channelContainers[i], err = PopulateChannelContainer(channel, accountId)
		if err != nil {
			return nil, err
		}
	}

	return channelContainers, nil
}

func PopulateChannelContainer(channel Channel, accountId int64) (*ChannelContainer, error) {
	cp := NewChannelParticipant()
	cp.ChannelId = channel.Id

	// add participantCount
	participantCount, err := cp.FetchParticipantCount()
	if err != nil {
		return nil, err
	}

	// add participant preview
	cpList, err := cp.ListAccountIds(5)
	if err != nil {
		return nil, err
	}

	// add participation status
	isParticipant, err := cp.IsParticipant(accountId)
	if err != nil {
		return nil, err
	}

	cc := NewChannelContainer()
	cc.Channel = channel
	cc.IsParticipant = isParticipant
	cc.ParticipantCount = participantCount
	participantOldIds, err := AccountOldsIdByIds(cpList)
	if err != nil {
		return nil, err
	}

	cc.ParticipantsPreview = participantOldIds

	// add last message of the channel
	cm, err := channel.FetchLastMessage()
	if err != nil {
		return nil, err
	}

	if cm != nil {
		cmc, err := cm.BuildEmptyMessageContainer()
		if err != nil {
			return nil, err
		}
		cc.LastMessage = cmc
	}

	return cc, nil
}
<commit_msg>Social: add  a new function for populating channels with unread count<commit_after>package models

import "socialapi/workers/helper"

type ChannelContainer struct {
	Channel             Channel                  `json:"channel"`
	IsParticipant       bool                     `json:"isParticipant"`
	ParticipantCount    int                      `json:"participantCount"`
	ParticipantsPreview []string                 `json:"participantsPreview"`
	LastMessage         *ChannelMessageContainer `json:"lastMessage"`
	UnreadCount         int                      `json:"unreadCount"`
}

func NewChannelContainer() *ChannelContainer {
	return &ChannelContainer{}
}

func PopulateChannelContainers(channelList []Channel, accountId int64) ([]*ChannelContainer, error) {
	channelContainers := make([]*ChannelContainer, len(channelList))

	var err error
	for i, channel := range channelList {
		channelContainers[i], err = PopulateChannelContainer(channel, accountId)
		if err != nil {
			return nil, err
		}
	}

	return channelContainers, nil
}

func PopulateChannelContainersWithUnreadCount(channelList []Channel, accountId int64) ([]*ChannelContainer, error) {
	channelContainers, err := PopulateChannelContainers(channelList, accountId)
	if err != nil {
		return nil, err
	}

	cml := NewChannelMessageList()
	for i, container := range channelContainers {
		if !container.IsParticipant {
			continue
		}

		cp := NewChannelParticipant()
		cp.ChannelId = container.Channel.Id
		cp.AccountId = accountId
		if err := cp.FetchParticipant(); err != nil {
			helper.MustGetLogger().Error(err.Error())
			continue
		}

		count, _ := cml.UnreadCount(cp)
		if err != nil {
			helper.MustGetLogger().Error(err.Error())
			continue
		}
		channelContainers[i].UnreadCount = count
	}

	return channelContainers, nil
}

func PopulateChannelContainer(channel Channel, accountId int64) (*ChannelContainer, error) {
	cp := NewChannelParticipant()
	cp.ChannelId = channel.Id

	// add participantCount
	participantCount, err := cp.FetchParticipantCount()
	if err != nil {
		return nil, err
	}

	// add participant preview
	cpList, err := cp.ListAccountIds(5)
	if err != nil {
		return nil, err
	}

	// add participation status
	isParticipant, err := cp.IsParticipant(accountId)
	if err != nil {
		return nil, err
	}

	cc := NewChannelContainer()
	cc.Channel = channel
	cc.IsParticipant = isParticipant
	cc.ParticipantCount = participantCount
	participantOldIds, err := AccountOldsIdByIds(cpList)
	if err != nil {
		return nil, err
	}

	cc.ParticipantsPreview = participantOldIds

	// add last message of the channel
	cm, err := channel.FetchLastMessage()
	if err != nil {
		return nil, err
	}

	if cm != nil {
		cmc, err := cm.BuildEmptyMessageContainer()
		if err != nil {
			return nil, err
		}
		cc.LastMessage = cmc
	}

	return cc, nil
}
<|endoftext|>


<commit_before>package utils

import (
	"errors"
	"fmt"
	"net/url"
	"reflect"
	"strconv"
	"strings"
)

// Fill fills the structure with data from a form post.
// obj - the object to be filled.
// m - post form.
// required - the field which should be in post form, in
// if they are not, the structure is not filled
// and return the error "Required fields not found.".
func Fill(obj interface{}, m url.Values, required ...string) error {
	defer func() {
		if e := recover(); e != nil {
			panic(e)
		}
	}()

	for _, reqField := range required {
		fields := strings.Split(reqField, "|")

		if len(fields) == 0 {
			continue
		}

		flagExist := false
		for _, field := range fields {
			_, exist := m[field]

			flagExist = flagExist || exist
		}
		if !flagExist {
			return errors.New("Required fields not found.")
		}
	}

	val := reflect.ValueOf(obj)
	if val.Kind() == reflect.Ptr {
		val = val.Elem()
	}

	for k, v := range m {
		var f reflect.Value

		if f = val.FieldByName(strings.Title(k)); !f.IsValid() {
			continue
		}

		if !f.CanSet() {
			fmt.Printf("Key '%s' cannot be set\n", k)
			continue
		}

		switch f.Type().Kind() {
		case reflect.Int:
			if i, e := strconv.ParseInt(v[0], 0, 0); e == nil {
				f.SetInt(i)
			} else {
				fmt.Printf("Could not set int value of %s: %s\n", k, e)
			}
		case reflect.Float64:
			if fl, e := strconv.ParseFloat(v[0], 0); e == nil {
				f.SetFloat(fl)
			} else {
				fmt.Printf("Could not set float64 value of %s: %s\n", k, e)
			}
		case reflect.String:
			f.SetString(v[0])

		default:
			fmt.Printf("Unsupported format %v for field %s\n", f.Type().Kind(), k)
		}
	}

	return nil
}
<commit_msg>Rename variable.<commit_after>package utils

import (
	"errors"
	"fmt"
	"net/url"
	"reflect"
	"strconv"
	"strings"
)

// Fill fills the structure with data from a form post.
// obj - the object to be filled.
// m - post form.
// required - the field which should be in post form, in
// if they are not, the structure is not filled
// and return the error "Required fields not found.".
func Fill(obj interface{}, m url.Values, required ...string) error {
	defer func() {
		if e := recover(); e != nil {
			panic(e)
		}
	}()

	for _, reqField := range required {
		fields := strings.Split(reqField, "|")

		if len(fields) == 0 {
			continue
		}

		flagExist := false
		for _, field := range fields {
			_, isExist := m[field]

			flagExist = flagExist || isExist
		}
		if !flagExist {
			return errors.New("Required fields not found.")
		}
	}

	val := reflect.ValueOf(obj)
	if val.Kind() == reflect.Ptr {
		val = val.Elem()
	}

	for k, v := range m {
		var f reflect.Value

		if f = val.FieldByName(strings.Title(k)); !f.IsValid() {
			continue
		}

		if !f.CanSet() {
			fmt.Printf("Key '%s' cannot be set\n", k)
			continue
		}

		switch f.Type().Kind() {
		case reflect.Int:
			if i, e := strconv.ParseInt(v[0], 0, 0); e == nil {
				f.SetInt(i)
			} else {
				fmt.Printf("Could not set int value of %s: %s\n", k, e)
			}
		case reflect.Float64:
			if fl, e := strconv.ParseFloat(v[0], 0); e == nil {
				f.SetFloat(fl)
			} else {
				fmt.Printf("Could not set float64 value of %s: %s\n", k, e)
			}
		case reflect.String:
			f.SetString(v[0])

		default:
			fmt.Printf("Unsupported format %v for field %s\n", f.Type().Kind(), k)
		}
	}

	return nil
}
<|endoftext|>


<commit_before>package netutil

import (
	"encoding/binary"
	"fmt"
	"net"
)

type Ipv4Address struct {
	v4address uint32
	mask      uint32
	prefix    uint
	network   uint32
	host      uint32
}

func ParseCIDR(cidr string) (*Ipv4Address, error) {
	ip, ipNet, err := net.ParseCIDR(cidr)
	if err != nil {
		return nil, err
	}
	ip = ip.To4()
	result := &Ipv4Address{}
	result.v4address = (uint32(ip[0])<<24 | (uint32(ip[1]) << 16) | (uint32(ip[2]) << 8) | uint32(ip[3]))
	prefix, _ := ipNet.Mask.Size()
	result.prefix = uint(prefix)
	result.mask = (uint32(ipNet.Mask[0])<<24 | (uint32(ipNet.Mask[1]) << 16) | (uint32(ipNet.Mask[2]) << 8) | uint32(ipNet.Mask[3]))
	result.network = (result.v4address & result.mask) >> uint32(32-prefix)
	result.host = (result.v4address & ^result.mask)
	return result, nil
}

func clone(source *Ipv4Address) *Ipv4Address {
	result := &Ipv4Address{
		v4address: source.v4address,
		mask:      source.mask,
		prefix:    source.prefix,
		network:   source.network,
		host:      source.host,
	}
	return result
}

func IncreaseHostAddress(source *Ipv4Address) *Ipv4Address {
	result := clone(source)
	if (result.host & ^result.mask) == (0xFFFFFFFF & ^result.mask) {
		result.host = 0
	} else {
		result.host += 1
	}
	return result
}

func DecreaseHostAddress(source *Ipv4Address) *Ipv4Address {
	result := clone(source)
	if result.host == 0x00000000 {
		result.host = 0xFFFFFFFF & ^result.mask
	} else {
		result.host -= 1
	}
	return result
}

func IncreaseNetworkAddress(source *Ipv4Address) *Ipv4Address {
	result := clone(source)
	result.network += 1
	return result
}

func DecreaseNetworkAddress(source *Ipv4Address) *Ipv4Address {
	result := clone(source)
	result.network -= 1
	return result
}

func IncreaseIpAddress(source *Ipv4Address) *Ipv4Address {
	result := clone(source)
	if (result.host & ^result.mask) == (0xFFFFFFFF & ^result.mask) {
		result.host = 0
		result.network += 1
	} else {
		result.host += 1
	}
	return result
}

func DecreaseIpAddress(source *Ipv4Address) *Ipv4Address {
	result := clone(source)
	if result.host == 0x00000000 {
		result.host = 0xFFFFFFFF & ^result.mask
		result.network -= 1
	} else {
		result.host -= 1
	}
	return result
}

func LimitedBroadcast(source *Ipv4Address) *Ipv4Address {
	result := clone(source)
	result.host = 0xFFFFFFFF & ^result.mask
	return result
}

func Network(source *Ipv4Address) *Ipv4Address {
	result := clone(source)
	result.host = 0
	return result
}

func MaxHost(source *Ipv4Address) *Ipv4Address {
	result := clone(source)
	result.host = (0xFFFFFFFF & ^result.mask) - 1
	return result
}

func MinimumHost(source *Ipv4Address) *Ipv4Address {
	result := clone(source)
	result.host = 1
	return result
}

func IsBroadcastAddress(source *Ipv4Address) bool {
	return ((source.host & ^source.mask) == (0xFFFFFFFF & ^source.mask))
}

func IsNetworkAddress(source *Ipv4Address) bool {
	return (source.host == 0x00000000)
}

func String(source *Ipv4Address) string {
	ip := (source.network << uint32(32-source.prefix)) | source.host
	ipBytes := make([]byte, 4)
	binary.BigEndian.PutUint32(ipBytes, ip)
	return fmt.Sprintf("%d.%d.%d.%d", ipBytes[0], ipBytes[1], ipBytes[2], ipBytes[3])
}

func StringWithPrefix(source *Ipv4Address) string {
	return fmt.Sprintf("%s/%d", String(source), source.prefix)
}
<commit_msg>Remove directly-unrelated utilitiy from Caly<commit_after><|endoftext|>


<commit_before>package main

import (
	// Import the entire framework (including bundled verilog)
	_ "sdaccel"

	aximemory "axi/memory"
	axiprotocol "axi/protocol"

	"github.com/ReconfigureIO/fixed"
)

// A small kernel to test our fixed library
func Top(
	a int32,
	b int32,
	addr uintptr,

	// The second set of arguments will be the ports for interacting with memory
	memReadAddr chan<- axiprotocol.Addr,
	memReadData <-chan axiprotocol.ReadData,

	memWriteAddr chan<- axiprotocol.Addr,
	memWriteData chan<- axiprotocol.WriteData,
	memWriteResp <-chan axiprotocol.WriteResp) {

	// Since we're not reading anything from memory, disable those reads
	go axiprotocol.ReadDisable(memReadAddr, memReadData)

	// Calculate the value
	pre_val := fixed.Int26_6(a)
	val := pre_val.Mul(fixed.Int26_6(b))

	// Write it back to the pointer the host requests
	aximemory.WriteUInt32(
		memWriteAddr, memWriteData, memWriteResp, false, addr, uint32(val))
}
<commit_msg>More comments.<commit_after>package main

import (
	// Import the entire framework (including bundled verilog)
	_ "sdaccel"

	aximemory "axi/memory"
	axiprotocol "axi/protocol"

	"github.com/ReconfigureIO/fixed"
)

// A small kernel to test our fixed library
func Top(
	a int32,
	b int32,
	addr uintptr,

	// The second set of arguments will be the ports for interacting with memory
	memReadAddr chan<- axiprotocol.Addr,
	memReadData <-chan axiprotocol.ReadData,

	memWriteAddr chan<- axiprotocol.Addr,
	memWriteData chan<- axiprotocol.WriteData,
	memWriteResp <-chan axiprotocol.WriteResp) {

	// Since we're not reading anything from memory, disable those reads
	go axiprotocol.ReadDisable(memReadAddr, memReadData)

	// convert to fixed point
	a_fixed := fixed.I26(a)

	// Calculate the value
	val := a_fixed.Mul(fixed.I26(b))

	// Write it back to the pointer the host requests
	aximemory.WriteUInt32(
		memWriteAddr, memWriteData, memWriteResp, false, addr, uint32(val))
}
<|endoftext|>


<commit_before>// Copyright 2012-2016 Apcera Inc. All rights reserved.
// +build ignore

package main

import (
	"flag"
	"log"
	"os"
	"runtime"

	"github.com/nats-io/nats"
)

// NOTE: Use tls scheme for TLS, e.g. nats-qsub -s tls://demo.nats.io:4443 foo
func usage() {
	log.Fatalf("Usage: nats-sub [-s server] [-t] <subject> <queue-group>\n")
}

func printMsg(m *nats.Msg, i int) {
	log.Printf("[#%d] Received on [%s] Queue[%s] Pid[%d]: '%s'\n", i, m.Subject, m.Sub.Queue, os.Getpid(), string(m.Data))
}

func main() {
	var urls = flag.String("s", nats.DefaultURL, "The nats server URLs (separated by comma)")
	var showTime = flag.Bool("t", false, "Display timestamps")

	log.SetFlags(0)
	flag.Usage = usage
	flag.Parse()

	args := flag.Args()
	if len(args) < 2 {
		usage()
	}

	nc, err := nats.Connect(*urls)
	if err != nil {
		log.Fatalf("Can't connect: %v\n", err)
	}

	subj, queue, i := args[0], args[1], 0

	nc.QueueSubscribe(subj, queue, func(msg *nats.Msg) {
		i++
		printMsg(msg, i)
	})
	nc.Flush()

	if err := nc.LastError(); err != nil {
		log.Fatal(err)
	}

	log.Printf("Listening on [%s]\n", subj)
	if *showTime {
		log.SetFlags(log.LstdFlags)
	}

	runtime.Goexit()
}
<commit_msg>Fixed usage statement with correct executable name<commit_after>// Copyright 2012-2016 Apcera Inc. All rights reserved.
// +build ignore

package main

import (
	"flag"
	"log"
	"os"
	"runtime"

	"github.com/nats-io/nats"
)

// NOTE: Use tls scheme for TLS, e.g. nats-qsub -s tls://demo.nats.io:4443 foo
func usage() {
	log.Fatalf("Usage: nats-qsub [-s server] [-t] <subject> <queue-group>\n")
}

func printMsg(m *nats.Msg, i int) {
	log.Printf("[#%d] Received on [%s] Queue[%s] Pid[%d]: '%s'\n", i, m.Subject, m.Sub.Queue, os.Getpid(), string(m.Data))
}

func main() {
	var urls = flag.String("s", nats.DefaultURL, "The nats server URLs (separated by comma)")
	var showTime = flag.Bool("t", false, "Display timestamps")

	log.SetFlags(0)
	flag.Usage = usage
	flag.Parse()

	args := flag.Args()
	if len(args) < 2 {
		usage()
	}

	nc, err := nats.Connect(*urls)
	if err != nil {
		log.Fatalf("Can't connect: %v\n", err)
	}

	subj, queue, i := args[0], args[1], 0

	nc.QueueSubscribe(subj, queue, func(msg *nats.Msg) {
		i++
		printMsg(msg, i)
	})
	nc.Flush()

	if err := nc.LastError(); err != nil {
		log.Fatal(err)
	}

	log.Printf("Listening on [%s]\n", subj)
	if *showTime {
		log.SetFlags(log.LstdFlags)
	}

	runtime.Goexit()
}
<|endoftext|>


<commit_before>package factory

import (
	"errors"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"

	"github.com/Sirupsen/logrus"
)

type RKT struct {
	name string
}

func (this *RKT) SetRT(runtime string) {
	this.name = "rkt"
}

func (this *RKT) GetRT() string {
	return "rkt"
}

func (this *RKT) Convert(bundleName string, workingDir string) (string, error) {
	var cmd *exec.Cmd
	aciName := bundleName + ".aci"
	cmd = exec.Command("../plugins/oci2aci", "--debug", bundleName, aciName)
	cmd.Dir = workingDir
	// cmd.stdin = os.Stdin
	stderr, err := cmd.StderrPipe()
	if err != nil {
		log.Fatal("stderr err %v", err)
	}

	stdout, err := cmd.StdoutPipe()
	if err != nil {
		log.Fatalf("stdout err %v", err)
	}

	var retStr string
	err = cmd.Start()
	if err != nil {
		retb, _ := ioutil.ReadAll(stderr)
		retStr = string(retb)
	} else {
		retb, _ := ioutil.ReadAll(stdout)
		retStr = string(retb)
	}

	return retStr, err
}

func (this *RKT) StartRT(specDir string) (string, error) {
	logrus.Debugf("Launcing runtime")
	/*rkt run 3.aci --interactive --insecure-skip-verify --mds-register=false --volume proc,kind=host,source=/bin --volume dev,kind=host,source=/bin --volume devpts,kind=host,source=/bin --volume shm,kind=host,source=/bin --volume mqueue,kind=host,source=/bin --volume sysfs,kind=host,source=/bin --volume cgroup,kind=host,source=/bin*/
	aciName := filepath.Base(specDir) + ".aci"
	aciPath := filepath.Dir(specDir)

	if retStr, err := this.Convert(aciName, aciPath); err != nil {
		return retStr, err
	}

	cmd := exec.Command("rkt", "run", aciName, "--interactive", "--insecure-skip-verify", "--mds-register=false",
		"--volume", "proc,kind=host,source=/bin", "--volume", "dev,kind=host,source=/bin", "--volume", "devpts,kind=host,source=/bin",
		"--volume", "shm,kind=host,source=/bin", "--volume", "mqueue,kind=host,source=/bin",
		"--volume", "sysfs,kind=host,source=/bin", "--volume", "cgroup,kind=host,source=/bin")
	cmd.Dir = aciPath
	cmd.Stdin = os.Stdin
	out, err := cmd.CombinedOutput()
	logrus.Debugf("Command done")

	if err != nil {
		return string(out), errors.New(string(out) + err.Error())
	}
	return string(out), nil
	/*if string(out) != "" {
		logrus.Infof("container output=%s\n", out)
	} else {
		logrus.Debugf("container output= nil\n")
	}
	if err != nil {
		return err
	}
	return nil*/
}

func (this *RKT) StopRT() error {
	return nil
}
<commit_msg>resolve conflict<commit_after>package factory

import (
	"errors"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"strings"

	"github.com/Sirupsen/logrus"
)

type RKT struct {
	name string
}

func (this *RKT) SetRT(runtime string) {
	this.name = "rkt"
}

func (this *RKT) GetRT() string {
	return "rkt"
}

func (this *RKT) Convert(appName string, workingDir string) (string, error) {
	var cmd *exec.Cmd
	aciName := appName + ".aci"
	//set appName to rkt appname, set rkt aciName to image name
	cmd = exec.Command("../plugins/oci2aci", "--debug", "-name", appName, appName, aciName)
	cmd.Dir = workingDir
	// cmd.stdin = os.Stdin
	stderr, err := cmd.StderrPipe()
	if err != nil {
		log.Fatal("stderr err %v", err)
	}

	stdout, err := cmd.StdoutPipe()
	if err != nil {
		log.Fatalf("stdout err %v", err)
	}

	var retStr string
	err = cmd.Start()
	if err != nil {
		retb, _ := ioutil.ReadAll(stderr)
		retStr = string(retb)
	} else {
		retb, _ := ioutil.ReadAll(stdout)
		retStr = string(retb)
	}

	return retStr, err
}

func (this *RKT) StartRT(specDir string) (string, error) {

	logrus.Debugf("Launcing runtime")
	/*rkt run 3.aci --interactive --insecure-skip-verify --mds-register=false --volume proc,kind=host,source=/bin --volume dev,kind=host,source=/bin --volume devpts,kind=host,source=/bin --volume shm,kind=host,source=/bin --volume mqueue,kind=host,source=/bin --volume sysfs,kind=host,source=/bin --volume cgroup,kind=host,source=/bin*/
	appName := filepath.Base(specDir)
	aciName := appName + ".aci"
	aciPath := filepath.Dir(specDir)

        if retStr, err := this.Convert(appName, aciPath); err != nil {
                return retStr, err
        }

	cmd := exec.Command("rkt", "run", aciName, "--interactive", "--insecure-skip-verify", "--mds-register=false",
		"--volume", "proc,kind=host,source=/bin", "--volume", "dev,kind=host,source=/bin", "--volume", "devpts,kind=host,source=/bin",
		"--volume", "shm,kind=host,source=/bin", "--volume", "mqueue,kind=host,source=/bin",
		"--volume", "sysfs,kind=host,source=/bin", "--volume", "cgroup,kind=host,source=/bin", "--net=host")
	cmd.Dir = aciPath
	cmd.Stdin = os.Stdin
	out, err := cmd.CombinedOutput()
	if err != nil {
		return string(out), err
	}
	logrus.Debugf("Command done")

	bv, ev := checkResult(appName)
	if ev != nil {
		return "", ev
	} else if !bv {
		return string(out), errors.New(string(out))
	}
	return string(out), nil
}

func checkResult(appName string) (bool, error) {

	//use rkt list to get uuid of rkt contianer
	cmd := exec.Command("rkt", "list")
	cmd.Stdin = os.Stdin
	listOut, err := cmd.CombinedOutput()
	if err != nil {
		logrus.Fatalf("rkt list err %v\n", err)
	}
	uuid, err := getUuid(string(listOut), appName)
	if err != nil {
		return false, errors.New("can not get uuid of rkt app" + appName)
	}
	logrus.Debugf("uuid: %v\n", uuid)
	//use rkt status to get status of app running in rkt container
	cmd = exec.Command("rkt", "status", uuid)
	statusOut, err := cmd.CombinedOutput()
	/*err occurs here, because of the bug from oci2aci
	  so we just deal with the ouput directly until the bug is fixed
	*/
	/*if err != nil {
		logrus.Fatalf("rkt status err %v\n", err)
	}*/
	logrus.Printf("stautsOut %v\n", string(statusOut))
	s, err := getAppStatus(string(statusOut), appName)
	if s != 0 || err != nil {
		return false, err
	}
	return true, nil
}

func getAppStatus(Out string, appName string) (int64, error) {
	line, err := getLine(Out, appName)
	if err != nil {
		logrus.Debugln(err)
		return 1, err
	}
	a := strings.SplitAfter(line, "=")
	logrus.Printf("getAppStatus %v\n", a[1])

	res, err := strconv.ParseInt(a[1], 10, 32)
	if err != nil {
		logrus.Debugln(err)
		return 1, err
	}
	return res, nil
}

func getUuid(listOut string, appName string) (string, error) {

	line, err := getLine(listOut, appName)
	if err != nil {
		logrus.Debugln(err)
		return "", err
	}

	return splitUuid(line), nil
}

func splitUuid(line string) string {

	//strings.Fields(s)
	a := strings.Fields(line)
	/*for _, aa := range a {
		logrus.Printf("aaa %v\n", aa)
	}*/
	return strings.TrimSpace(a[0])
}

func getLine(Out string, objName string) (string, error) {

	outArray := strings.Split(Out, "\n")
	flag := false
	var wantLine string
	for _, o := range outArray {
		if strings.Contains(o, objName) {
			wantLine = o
			flag = true
			break
		}
	}

	if !flag {
		return wantLine, errors.New("no line containers " + objName)
	}
	return wantLine, nil
}

func (this *RKT) StopRT() error {
	return nil
}
<|endoftext|>


<commit_before>// +build ignore

package main

import (
	"fmt"
	"os"

	e "github.com/ahmdrz/goinsta/examples"
)

func main() {
	inst, err := e.InitGoinsta(3, "<your username> <target user>")
	e.CheckErr(err)

	user, err := inst.Profiles.ByName(os.Args[2])
	e.CheckErr(err)

	media := user.Feed(nil)
	e.CheckErr(err)

	for media.Next() {
		fmt.Println("Next:", media.NextID)
		for _, item := range media.Items {
			if len(item.Images.Versions) != 0 {
				fmt.Printf("  - %s\n", item.Images.Versions[0].URL)
			}
		}
	}
	fmt.Println(media.Error())

	if !e.UsingSession {
		err = inst.Logout()
		e.CheckErr(err)
	}
}
<commit_msg>Changed example<commit_after>// +build ignore

package main

import (
	"fmt"
	"os"

	e "github.com/ahmdrz/goinsta/examples"
)

func main() {
	inst, err := e.InitGoinsta(3, "<your username> <target user>")
	e.CheckErr(err)

	user, err := inst.Profiles.ByName(os.Args[2])
	e.CheckErr(err)

	media := user.Feed(nil)
	e.CheckErr(err)

	for media.Next() {
		fmt.Println("Next:", media.NextID)
		for _, item := range media.Items {
			if len(item.Images.Versions) != 0 {
				fmt.Printf("  %v - %s\n", item.ID, item.Images.Versions[0].URL)
			}
		}
	}
	fmt.Println(media.Error())

	if !e.UsingSession {
		err = inst.Logout()
		e.CheckErr(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	log "github.com/Sirupsen/logrus"
	mesos "github.com/mesos/mesos-go/mesosproto"
	"os"
	"text/template"
)

type RiakNode struct {
	executor *ExecutorCore
	taskInfo *mesos.TaskInfo
}

type templateData struct {
	HTTPPort int
	PBPort   int
	NodeName string
	HostName string
}

func NewRiakNode(taskInfo *mesos.TaskInfo, executor *ExecutorCore) *RiakNode {
	return &RiakNode{
		executor: executor,
		taskInfo: taskInfo,
	}
}
func (riakNode *RiakNode) Run() {

	var err error
	log.Info("Other hilarious facts: ", riakNode.taskInfo)
	data, err := Asset("data/riak.conf")
	if err != nil {
		log.Panic("Got error", err)
	}
	tmpl, err := template.New("test").Parse(string(data))

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

	// Populate template data from the MesosTask
	vars := templateData{}
	_ = os.Stdout
	_ = vars
	_ = tmpl
	//err = tmpl.Execute(os.Stdout, vars)

	runStatus := &mesos.TaskStatus{
		TaskId: riakNode.taskInfo.GetTaskId(),
		State:  mesos.TaskState_TASK_RUNNING.Enum(),
	}
	_, err = riakNode.executor.Driver.SendStatusUpdate(runStatus)

	if err != nil {
		log.Panic("Got error", err)
	}
}

func (riakNode *RiakNode) finish() {
	runStatus := &mesos.TaskStatus{
		TaskId: riakNode.taskInfo.GetTaskId(),
		State:  mesos.TaskState_TASK_FINISHED.Enum(),
	}
	_, err := riakNode.executor.Driver.SendStatusUpdate(runStatus)
	if err != nil {
		log.Panic("Got error", err)
	}
	riakNode.executor.riakNode = nil
}
<commit_msg>Ensure thread safety\! for tast finishing / deletion<commit_after>package main

import (
	log "github.com/Sirupsen/logrus"
	mesos "github.com/mesos/mesos-go/mesosproto"
	"os"
	"text/template"
)

type RiakNode struct {
	executor *ExecutorCore
	taskInfo *mesos.TaskInfo
}

type templateData struct {
	HTTPPort int
	PBPort   int
	NodeName string
	HostName string
}

func NewRiakNode(taskInfo *mesos.TaskInfo, executor *ExecutorCore) *RiakNode {
	return &RiakNode{
		executor: executor,
		taskInfo: taskInfo,
	}
}
func (riakNode *RiakNode) Run() {

	var err error
	log.Info("Other hilarious facts: ", riakNode.taskInfo)
	data, err := Asset("data/riak.conf")
	if err != nil {
		log.Panic("Got error", err)
	}
	tmpl, err := template.New("test").Parse(string(data))

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

	// Populate template data from the MesosTask
	vars := templateData{}
	_ = os.Stdout
	_ = vars
	_ = tmpl
	//err = tmpl.Execute(os.Stdout, vars)

	runStatus := &mesos.TaskStatus{
		TaskId: riakNode.taskInfo.GetTaskId(),
		State:  mesos.TaskState_TASK_RUNNING.Enum(),
	}
	_, err = riakNode.executor.Driver.SendStatusUpdate(runStatus)

	if err != nil {
		log.Panic("Got error", err)
	}
}

func (riakNode *RiakNode) finish() {
	riakNode.executor.lock.Lock()
	defer riakNode.executor.lock.Unlock()
	runStatus := &mesos.TaskStatus{
		TaskId: riakNode.taskInfo.GetTaskId(),
		State:  mesos.TaskState_TASK_FINISHED.Enum(),
	}
	_, err := riakNode.executor.Driver.SendStatusUpdate(runStatus)
	if err != nil {
		log.Panic("Got error", err)
	}
	riakNode.executor.riakNode = nil
}
<|endoftext|>


<commit_before>package error

// TODO
// here define ONLY errors from the library NOT from flickr
// error from flickr have already a code and a message that are returned
// along with the HTTP Response

const (
	ApiError          = 10
	RequestTokenError = 20
)

var errors = map[int]string{
	ApiError:          "Flickr API returned an error, check the response for details",
	RequestTokenError: "An error occurred during token request, check the response for details",
}

type Error struct {
	ErrorCode int
	Message   string
}

// Implement error interface
func (e Error) Error() string {
	return e.Message
}

func NewError(errorCode int) *Error {
	return &Error{
		ErrorCode: errorCode,
		Message:   errors[errorCode],
	}
}
<commit_msg>added access token error<commit_after>package error

// TODO
// here define ONLY errors from the library NOT from flickr
// error from flickr have already a code and a message that are returned
// along with the HTTP Response

const (
	ApiError          = 10
	RequestTokenError = 20
	OAuthTokenError   = 30
)

var errors = map[int]string{
	ApiError:          "Flickr API returned an error, check the response for details",
	RequestTokenError: "An error occurred during token request, check the response for details",
	OAuthTokenError:   "An error occurred while getting the OAuth token, check the response for details",
}

type Error struct {
	ErrorCode int
	Message   string
}

// Implement error interface
func (e Error) Error() string {
	return e.Message
}

func NewError(errorCode int) *Error {
	return &Error{
		ErrorCode: errorCode,
		Message:   errors[errorCode],
	}
}
<|endoftext|>


<commit_before>package daemon

import (
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
	"github.com/pufferpanel/apufferi/v3/logging"
	"github.com/pufferpanel/apufferi/v3/response"
	"github.com/pufferpanel/pufferpanel/v2/database"
	"github.com/pufferpanel/pufferpanel/v2/models"
	"github.com/pufferpanel/pufferpanel/v2/services"
	netHttp "net/http"
	"strconv"
	"strings"
)

func RegisterRoutes(rg *gin.RouterGroup) {
	g := rg.Group("/server")
	{
		//g.Any("", proxyServerRequest)
		g.Any("/:id", proxyServerRequest)
		g.Any("/:id/*path", proxyServerRequest)
	}
	r := rg.Group("/node")
	{
		//g.Any("", proxyServerRequest)
		r.Any("/:id", proxyNodeRequest)
		r.Any("/:id/*path", proxyNodeRequest)
	}
}

func proxyServerRequest(c *gin.Context) {
	res := response.From(c)

	serverId := c.Param("id")
	if serverId == "" {
		res.Fail().Status(404)
		return
	}

	path := "/server/" + serverId + c.Param("path")

	db, err := database.GetConnection()
	if response.HandleError(res, err) {
		return
	}

	ss := &services.Server{DB: db}
	ns := &services.Node{DB: db}

	server, err := ss.Get(serverId)
	if err != nil && !gorm.IsRecordNotFoundError(err) && response.HandleError(res, err) {
		return
	} else if server == nil || server.Identifier == "" {
		res.Status(netHttp.StatusNotFound).Fail()
		return
	}

	if c.GetHeader("Upgrade") == "websocket" {
		proxySocketRequest(c, path, ns, &server.Node)
	} else {
		proxyHttpRequest(c, path, ns, &server.Node)
	}
}

func proxyNodeRequest(c *gin.Context) {
	path := c.Param("path")

	res := response.From(c)

	nodeId := c.Param("id")
	if nodeId == "" {
		res.Status(404).Fail()
		return
	}

	db, err := database.GetConnection()
	if response.HandleError(res, err) {
		return
	}

	ns := &services.Node{DB: db}

	id, err := strconv.ParseUint(nodeId, 10, 32)
	if response.HandleError(res, err) {
		return
	}

	node, exists, err := ns.Get(uint(id))
	if response.HandleError(res, err) {
		return
	} else if !exists {
		res.Fail().Status(404)
		return
	}

	if c.GetHeader("Upgrade") == "websocket" {
		proxySocketRequest(c, path, ns, node)
	} else {
		proxyHttpRequest(c, path, ns, node)
	}
}

func proxyHttpRequest(c *gin.Context, path string, ns *services.Node, node *models.Node) {
	callResponse, err := ns.CallNode(node, c.Request.Method, path, c.Request.Body, c.Request.Header)

	//this only will throw an error if we can't get to the node
	//so if error, use our response messenger, otherwise copy response from node to client
	if err != nil {
		response.From(c).Status(netHttp.StatusInternalServerError).Fail().Error(err)
		return
	}

	//Even though apache isn't going to be in place, we can't set certain headers
	newHeaders := make(map[string]string, 0)
	for k, v := range callResponse.Header {
		switch k {
		case "Transfer-Encoding":
		case "Content-Type":
		case "Content-Length":
			continue
		default:
			newHeaders[k] = strings.Join(v, ", ")
		}
	}

	response.From(c).Discard()
	c.DataFromReader(callResponse.StatusCode, callResponse.ContentLength, callResponse.Header.Get("Content-Type"), callResponse.Body, newHeaders)
}

func proxySocketRequest(c *gin.Context, path string, ns *services.Node, node *models.Node) {
	response.From(c).Discard()
	err := ns.OpenSocket(node, path, c.Writer, c.Request)
	if err != nil {
		logging.Exception("error opening socket", err)
		response.From(c).Status(netHttp.StatusInternalServerError).Fail().Error(err)
		return
	}
}
<commit_msg>Have daemon proxy change token if given session This will let the panel proxy user requests when done from the web interface<commit_after>package daemon

import (
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
	"github.com/pufferpanel/apufferi/v3"
	"github.com/pufferpanel/apufferi/v3/logging"
	"github.com/pufferpanel/apufferi/v3/response"
	"github.com/pufferpanel/apufferi/v3/scope"
	"github.com/pufferpanel/pufferpanel/v2/database"
	"github.com/pufferpanel/pufferpanel/v2/models"
	"github.com/pufferpanel/pufferpanel/v2/services"
	"github.com/pufferpanel/pufferpanel/v2/web/handlers"
	netHttp "net/http"
	"strconv"
	"strings"
	"time"
)

func RegisterRoutes(rg *gin.RouterGroup) {
	g := rg.Group("/server", handlers.HasOAuth2Token)
	{
		//g.Any("", proxyServerRequest)
		g.Any("/:id", proxyServerRequest)
		g.Any("/:id/*path", proxyServerRequest)
	}
	r := rg.Group("/node", handlers.HasOAuth2Token)
	{
		//g.Any("", proxyServerRequest)
		r.Any("/:id", proxyNodeRequest)
		r.Any("/:id/*path", proxyNodeRequest)
	}
}

func proxyServerRequest(c *gin.Context) {
	res := response.From(c)

	serverId := c.Param("id")
	if serverId == "" {
		res.Fail().Status(404)
		return
	}

	path := "/server/" + serverId + c.Param("path")

	db, err := database.GetConnection()
	if response.HandleError(res, err) {
		return
	}

	ss := &services.Server{DB: db}
	ns := &services.Node{DB: db}

	server, err := ss.Get(serverId)
	if err != nil && !gorm.IsRecordNotFoundError(err) && response.HandleError(res, err) {
		return
	} else if server == nil || server.Identifier == "" {
		res.Status(netHttp.StatusNotFound).Fail()
		return
	}

	token := c.MustGet("token").(*apufferi.Claim)

	//if a session-token, we need to convert it to an oauth2 token instead
	if token.Audience == "session" {
		newToken, err := generateOAuth2Token(token, server)
		if response.HandleError(res, err) {
			return
		}

		//set new header
		c.Header("Authorization", "Bearer "+newToken)
	}

	if c.GetHeader("Upgrade") == "websocket" {
		proxySocketRequest(c, path, ns, &server.Node)
	} else {
		proxyHttpRequest(c, path, ns, &server.Node)
	}
}

func proxyNodeRequest(c *gin.Context) {
	path := c.Param("path")

	res := response.From(c)

	nodeId := c.Param("id")
	if nodeId == "" {
		res.Status(404).Fail()
		return
	}

	db, err := database.GetConnection()
	if response.HandleError(res, err) {
		return
	}

	ns := &services.Node{DB: db}

	id, err := strconv.ParseUint(nodeId, 10, 32)
	if response.HandleError(res, err) {
		return
	}

	node, exists, err := ns.Get(uint(id))
	if response.HandleError(res, err) {
		return
	} else if !exists {
		res.Fail().Status(404)
		return
	}

	token := c.MustGet("token").(*apufferi.Claim)

	//if a session-token, we need to convert it to an oauth2 token instead
	if token.Audience == "session" {
		newToken, err := generateOAuth2Token(token, nil)
		if response.HandleError(res, err) {
			return
		}

		//set new header
		c.Header("Authorization", "Bearer "+newToken)
	}

	if c.GetHeader("Upgrade") == "websocket" {
		proxySocketRequest(c, path, ns, node)
	} else {
		proxyHttpRequest(c, path, ns, node)
	}
}

func proxyHttpRequest(c *gin.Context, path string, ns *services.Node, node *models.Node) {
	callResponse, err := ns.CallNode(node, c.Request.Method, path, c.Request.Body, c.Request.Header)

	//this only will throw an error if we can't get to the node
	//so if error, use our response messenger, otherwise copy response from node to client
	if err != nil {
		response.From(c).Status(netHttp.StatusInternalServerError).Fail().Error(err)
		return
	}

	//Even though apache isn't going to be in place, we can't set certain headers
	newHeaders := make(map[string]string, 0)
	for k, v := range callResponse.Header {
		switch k {
		case "Transfer-Encoding":
		case "Content-Type":
		case "Content-Length":
			continue
		default:
			newHeaders[k] = strings.Join(v, ", ")
		}
	}

	response.From(c).Discard()
	c.DataFromReader(callResponse.StatusCode, callResponse.ContentLength, callResponse.Header.Get("Content-Type"), callResponse.Body, newHeaders)
}

func proxySocketRequest(c *gin.Context, path string, ns *services.Node, node *models.Node) {
	response.From(c).Discard()
	err := ns.OpenSocket(node, path, c.Writer, c.Request)
	if err != nil {
		logging.Exception("error opening socket", err)
		response.From(c).Status(netHttp.StatusInternalServerError).Fail().Error(err)
		return
	}
}

func generateOAuth2Token(token *apufferi.Claim, server *models.Server) (string, error) {
	db, err := database.GetConnection()
	if err != nil {
		return "", err
	}

	ps := &services.Permission{DB: db}

	userId, err := strconv.Atoi(token.Subject)
	if err != nil {
		return "", err
	}

	var serverId *string
	if server != nil {
		serverId = &server.Identifier
	}

	perms, err := ps.GetForUserAndServer(uint(userId), serverId)
	if err != nil {
		return "", err
	}

	scopes := make(map[string][]scope.Scope)

	if serverId != nil {
		scopes[*serverId] = perms.ToScopes()
	} else {
		scopes[""] = perms.ToScopes()
	}

	claims := &apufferi.Claim{
		StandardClaims: jwt.StandardClaims{
			Audience:  "oauth2",
			ExpiresAt: token.ExpiresAt,
			IssuedAt:  time.Now().Unix(),
			Subject:   token.Subject,
		},
		PanelClaims: apufferi.PanelClaims{
			Scopes: scopes,
		},
	}

	newToken, err := services.Generate(claims)
	if err != nil {
		return "", err
	}

	return newToken, nil
}
<|endoftext|>


<commit_before>package module

import (
	"fmt"
	"github.com/davidscholberg/irkbot/lib/configure"
	"github.com/davidscholberg/irkbot/lib/message"
	"google.golang.org/api/googleapi/transport"
	"google.golang.org/api/youtube/v3"
	"net/http"
	"os"
	"strings"
	"time"
)

func helpYoutubeSearch() []string {
	s := "yt <phrase> - search youtube for the given phrase and link the top result"
	return []string{s}
}

func youtubeSearch(cfg *configure.Config, in *message.InboundMsg, actions *actions) {
	if !strings.HasPrefix(in.Src, "#") {
		actions.say("youtube searches not allowed in PMs")
		return
	}

	msg := strings.Join(in.MsgArgs[1:], " ")
	//fetch API key from config
	apiKey := cfg.Modules["youtube"]["api_key"]

	client := &http.Client{
		Timeout:   time.Duration(cfg.Http.Timeout) * time.Second,
		Transport: &transport.APIKey{Key: apiKey},
	}
	service, err := youtube.New(client)
	if err != nil {
		fmt.Fprintf(os.Stderr, "error creating youtube client: %v\n", err)
		actions.say("error creating youtube client")
		return
	}
	call := service.Search.List("id,snippet").Q(msg).MaxResults(1)
	resp, err := call.Do()
	if err != nil {
		fmt.Fprintf(os.Stderr, "error performing youtube search: %v\n", err)
		actions.say("error performing youtube search")
		return
	}
	var result = "no results found! ¯\\_(ツ)_/¯"
	for _, item := range resp.Items {
		switch item.Id.Kind {
		case "youtube#video":
			result = fmt.Sprintf(
				"%s - https://www.youtube.com/watch?v=%s",
				item.Snippet.Title,
				item.Id.VideoId,
			)
		case "youtube#channel":
			result = fmt.Sprintf(
				"%s - https://www.youtube.com/channel/%s",
				item.Snippet.Title,
				item.Id.ChannelId,
			)
		case "youtube#playlist":
			playlistId, err := getExternalPlaylistId(service, item.Id.PlaylistId)
			if err != nil {
				fmt.Fprintf(os.Stderr, "error getting playlist id: %v\n", err)
				break
			}
			result = fmt.Sprintf(
				"%s - https://www.youtube.com/playlist?list=%s",
				item.Snippet.Title,
				playlistId,
			)
		}
	}

	actions.say(result)
}

// getExternalPlaylistId does an extra call to the youtube api to get the
// actual external playlist ID that can be used in URLs.
func getExternalPlaylistId(service *youtube.Service, playlistId string) (string, error) {
	call := service.Playlists.List("id").Id(playlistId).MaxResults(1)
	resp, err := call.Do()
	if err != nil {
		return "", err
	}
	for _, item := range resp.Items {
		return item.Id, nil
	}
	return "", nil
}
<commit_msg>youtube: added html unescaping to output<commit_after>package module

import (
	"fmt"
	"github.com/davidscholberg/irkbot/lib/configure"
	"github.com/davidscholberg/irkbot/lib/message"
	"google.golang.org/api/googleapi/transport"
	"google.golang.org/api/youtube/v3"
	"html"
	"net/http"
	"os"
	"strings"
	"time"
)

func helpYoutubeSearch() []string {
	s := "yt <phrase> - search youtube for the given phrase and link the top result"
	return []string{s}
}

func youtubeSearch(cfg *configure.Config, in *message.InboundMsg, actions *actions) {
	if !strings.HasPrefix(in.Src, "#") {
		actions.say("youtube searches not allowed in PMs")
		return
	}

	msg := strings.Join(in.MsgArgs[1:], " ")
	//fetch API key from config
	apiKey := cfg.Modules["youtube"]["api_key"]

	client := &http.Client{
		Timeout:   time.Duration(cfg.Http.Timeout) * time.Second,
		Transport: &transport.APIKey{Key: apiKey},
	}
	service, err := youtube.New(client)
	if err != nil {
		fmt.Fprintf(os.Stderr, "error creating youtube client: %v\n", err)
		actions.say("error creating youtube client")
		return
	}
	call := service.Search.List("id,snippet").Q(msg).MaxResults(1)
	resp, err := call.Do()
	if err != nil {
		fmt.Fprintf(os.Stderr, "error performing youtube search: %v\n", err)
		actions.say("error performing youtube search")
		return
	}
	var result = "no results found! ¯\\_(ツ)_/¯"
	for _, item := range resp.Items {
		switch item.Id.Kind {
		case "youtube#video":
			result = fmt.Sprintf(
				"%s - https://www.youtube.com/watch?v=%s",
				html.UnescapeString(item.Snippet.Title),
				item.Id.VideoId,
			)
		case "youtube#channel":
			result = fmt.Sprintf(
				"%s - https://www.youtube.com/channel/%s",
				html.UnescapeString(item.Snippet.Title),
				item.Id.ChannelId,
			)
		case "youtube#playlist":
			playlistId, err := getExternalPlaylistId(service, item.Id.PlaylistId)
			if err != nil {
				fmt.Fprintf(os.Stderr, "error getting playlist id: %v\n", err)
				break
			}
			result = fmt.Sprintf(
				"%s - https://www.youtube.com/playlist?list=%s",
				html.UnescapeString(item.Snippet.Title),
				playlistId,
			)
		}
	}

	actions.say(result)
}

// getExternalPlaylistId does an extra call to the youtube api to get the
// actual external playlist ID that can be used in URLs.
func getExternalPlaylistId(service *youtube.Service, playlistId string) (string, error) {
	call := service.Playlists.List("id").Id(playlistId).MaxResults(1)
	resp, err := call.Do()
	if err != nil {
		return "", err
	}
	for _, item := range resp.Items {
		return item.Id, nil
	}
	return "", nil
}
<|endoftext|>


<commit_before>package libvirt

import (
	"encoding/json"
	"log"
	"strings"
	"time"

	"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
	libvirt "github.com/libvirt/libvirt-go"
)

const qemuGetIfaceWait = "qemu-agent-wait"
const qemuGetIfaceDone = "qemu-agent-done"

// QemuAgentInterfacesResponse type
type QemuAgentInterfacesResponse struct {
	Interfaces []QemuAgentInterface `json:"return"`
}

// QemuAgentInterface type
type QemuAgentInterface struct {
	Name        string                        `json:"name"`
	Hwaddr      string                        `json:"hardware-address"`
	IPAddresses []QemuAgentInterfaceIPAddress `json:"ip-addresses"`
}

// QemuAgentInterfaceIPAddress type
type QemuAgentInterfaceIPAddress struct {
	Type    string `json:"ip-address-type"`
	Address string `json:"ip-address"`
	Prefix  uint   `json:"prefix"`
}

func qemuAgentInterfacesRefreshFunc(domain Domain, wait4ipv4 bool) resource.StateRefreshFunc {
	return func() (interface{}, string, error) {

		var interfaces []libvirt.DomainInterface

		log.Printf("[DEBUG] sending command to qemu-agent")
		result, err := domain.QemuAgentCommand(
			"{\"execute\":\"guest-network-get-interfaces\"}",
			libvirt.DOMAIN_QEMU_AGENT_COMMAND_DEFAULT,
			0)
		if err != nil {
			log.Printf("[DEBUG] command error: %s", err)
			return interfaces, qemuGetIfaceWait, nil
		}

		log.Printf("[DEBUG] qemu-agent response: %s", result)

		response := QemuAgentInterfacesResponse{}
		if err := json.Unmarshal([]byte(result), &response); err != nil {
			log.Printf("[DEBUG] Error converting qemu-agent response about domain interfaces: %s", err)
			log.Printf("[DEBUG] Original message: %+v", response)
			log.Print("[DEBUG] Returning an empty list of interfaces")
			return interfaces, "", nil
		}
		log.Printf("[DEBUG] Parsed response %+v", response)

		for _, iface := range response.Interfaces {
			if iface.Name == "lo" {
				// ignore loopback interface
				continue
			}

			libVirtIface := libvirt.DomainInterface{
				Name:   iface.Name,
				Hwaddr: iface.Hwaddr}

			ipv4Assigned := false
			for _, addr := range iface.IPAddresses {
				if addr.Address == "" {
					// ignore interfaces without an address (eg. waiting for dhcp lease)
					continue
				}

				libVirtAddr := libvirt.DomainIPAddress{
					Addr:   addr.Address,
					Prefix: addr.Prefix,
				}

				switch strings.ToLower(addr.Type) {
				case "ipv4":
					libVirtAddr.Type = int(libvirt.IP_ADDR_TYPE_IPV4)
					ipv4Assigned = true
				case "ipv6":
					libVirtAddr.Type = int(libvirt.IP_ADDR_TYPE_IPV6)
				default:
					log.Printf("[ERROR] Cannot handle unknown address type %s", addr.Type)
					continue
				}
				libVirtIface.Addrs = append(libVirtIface.Addrs, libVirtAddr)
			}
			if len(libVirtIface.Addrs) > 0 && (ipv4Assigned || !wait4ipv4) {
				interfaces = append(interfaces, libVirtIface)
			}
		}

		log.Printf("[DEBUG] Interfaces obtained via qemu-agent: %+v", interfaces)
		return interfaces, qemuGetIfaceDone, nil
	}
}

// Retrieve all the interfaces attached to a domain and their addresses. Only
// the interfaces with at least an IP address are returned.
// When wait4ipv4 is turned on the code will not report interfaces that don't
// have a ipv4 address set. This is useful when a domain gets the ipv6 address
// before the ipv4 one.
func qemuAgentGetInterfacesInfo(domain Domain, wait4ipv4 bool) []libvirt.DomainInterface {

	qemuAgentQuery := &resource.StateChangeConf{
		Pending:    []string{qemuGetIfaceWait},
		Target:     []string{qemuGetIfaceDone},
		Refresh:    qemuAgentInterfacesRefreshFunc(domain, wait4ipv4),
		MinTimeout: 4 * time.Second,
		Delay:      4 * time.Second, // Wait this time before starting checks
		Timeout:    30 * time.Second,
	}

	interfaces, err := qemuAgentQuery.WaitForState()
	if err != nil {
		return []libvirt.DomainInterface{}
	}

	return interfaces.([]libvirt.DomainInterface)
}
<commit_msg>change time/delay for qemu-guest-agent<commit_after>package libvirt

import (
	"encoding/json"
	"log"
	"strings"
	"time"

	"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
	libvirt "github.com/libvirt/libvirt-go"
)

const qemuGetIfaceWait = "qemu-agent-wait"
const qemuGetIfaceDone = "qemu-agent-done"

// QemuAgentInterfacesResponse type
type QemuAgentInterfacesResponse struct {
	Interfaces []QemuAgentInterface `json:"return"`
}

// QemuAgentInterface type
type QemuAgentInterface struct {
	Name        string                        `json:"name"`
	Hwaddr      string                        `json:"hardware-address"`
	IPAddresses []QemuAgentInterfaceIPAddress `json:"ip-addresses"`
}

// QemuAgentInterfaceIPAddress type
type QemuAgentInterfaceIPAddress struct {
	Type    string `json:"ip-address-type"`
	Address string `json:"ip-address"`
	Prefix  uint   `json:"prefix"`
}

func qemuAgentInterfacesRefreshFunc(domain Domain, wait4ipv4 bool) resource.StateRefreshFunc {
	return func() (interface{}, string, error) {

		var interfaces []libvirt.DomainInterface

		log.Printf("[DEBUG] sending command to qemu-agent")
		result, err := domain.QemuAgentCommand(
			"{\"execute\":\"guest-network-get-interfaces\"}",
			libvirt.DOMAIN_QEMU_AGENT_COMMAND_DEFAULT,
			0)
		if err != nil {
			log.Printf("[DEBUG] command error: %s", err)
			return interfaces, qemuGetIfaceWait, nil
		}

		log.Printf("[DEBUG] qemu-agent response: %s", result)

		response := QemuAgentInterfacesResponse{}
		if err := json.Unmarshal([]byte(result), &response); err != nil {
			log.Printf("[DEBUG] Error converting qemu-agent response about domain interfaces: %s", err)
			log.Printf("[DEBUG] Original message: %+v", response)
			log.Print("[DEBUG] Returning an empty list of interfaces")
			return interfaces, "", nil
		}
		log.Printf("[DEBUG] Parsed response %+v", response)

		for _, iface := range response.Interfaces {
			if iface.Name == "lo" {
				// ignore loopback interface
				continue
			}

			libVirtIface := libvirt.DomainInterface{
				Name:   iface.Name,
				Hwaddr: iface.Hwaddr}

			ipv4Assigned := false
			for _, addr := range iface.IPAddresses {
				if addr.Address == "" {
					// ignore interfaces without an address (eg. waiting for dhcp lease)
					continue
				}

				libVirtAddr := libvirt.DomainIPAddress{
					Addr:   addr.Address,
					Prefix: addr.Prefix,
				}

				switch strings.ToLower(addr.Type) {
				case "ipv4":
					libVirtAddr.Type = int(libvirt.IP_ADDR_TYPE_IPV4)
					ipv4Assigned = true
				case "ipv6":
					libVirtAddr.Type = int(libvirt.IP_ADDR_TYPE_IPV6)
				default:
					log.Printf("[ERROR] Cannot handle unknown address type %s", addr.Type)
					continue
				}
				libVirtIface.Addrs = append(libVirtIface.Addrs, libVirtAddr)
			}
			if len(libVirtIface.Addrs) > 0 && (ipv4Assigned || !wait4ipv4) {
				interfaces = append(interfaces, libVirtIface)
			}
		}

		log.Printf("[DEBUG] Interfaces obtained via qemu-agent: %+v", interfaces)
		return interfaces, qemuGetIfaceDone, nil
	}
}

// Retrieve all the interfaces attached to a domain and their addresses. Only
// the interfaces with at least an IP address are returned.
// When wait4ipv4 is turned on the code will not report interfaces that don't
// have a ipv4 address set. This is useful when a domain gets the ipv6 address
// before the ipv4 one.
func qemuAgentGetInterfacesInfo(domain Domain, wait4ipv4 bool) []libvirt.DomainInterface {

	qemuAgentQuery := &resource.StateChangeConf{
		Pending:    []string{qemuGetIfaceWait},
		Target:     []string{qemuGetIfaceDone},
		Refresh:    qemuAgentInterfacesRefreshFunc(domain, wait4ipv4),
		MinTimeout:  1 * time.Minute,
		Delay:      30 * time.Second, // Wait this time before starting checks
		Timeout:    30 * time.Minute,
	}

	interfaces, err := qemuAgentQuery.WaitForState()
	if err != nil {
		return []libvirt.DomainInterface{}
	}

	return interfaces.([]libvirt.DomainInterface)
}
<|endoftext|>


<commit_before>// Copyright (c) 2013 The Go Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd.

// Package lintutil provides helpers for writing linter command lines.
package lintutil // import "honnef.co/go/tools/lint/lintutil"

import (
	"errors"
	"flag"
	"fmt"
	"go/build"
	"go/token"
	"log"
	"os"
	"regexp"
	"runtime"
	"runtime/pprof"
	"strconv"
	"strings"
	"time"

	"honnef.co/go/tools/config"
	"honnef.co/go/tools/lint"
	"honnef.co/go/tools/lint/lintutil/format"
	"honnef.co/go/tools/version"

	"golang.org/x/tools/go/packages"
)

func usage(name string, flags *flag.FlagSet) func() {
	return func() {
		fmt.Fprintf(os.Stderr, "Usage of %s:\n", name)
		fmt.Fprintf(os.Stderr, "\t%s [flags] # runs on package in current directory\n", name)
		fmt.Fprintf(os.Stderr, "\t%s [flags] packages\n", name)
		fmt.Fprintf(os.Stderr, "\t%s [flags] directory\n", name)
		fmt.Fprintf(os.Stderr, "\t%s [flags] files... # must be a single package\n", name)
		fmt.Fprintf(os.Stderr, "Flags:\n")
		flags.PrintDefaults()
	}
}

func parseIgnore(s string) ([]lint.Ignore, error) {
	var out []lint.Ignore
	if len(s) == 0 {
		return nil, nil
	}
	for _, part := range strings.Fields(s) {
		p := strings.Split(part, ":")
		if len(p) != 2 {
			return nil, errors.New("malformed ignore string")
		}
		path := p[0]
		checks := strings.Split(p[1], ",")
		out = append(out, &lint.GlobIgnore{Pattern: path, Checks: checks})
	}
	return out, nil
}

type versionFlag int

func (v *versionFlag) String() string {
	return fmt.Sprintf("1.%d", *v)
}

func (v *versionFlag) Set(s string) error {
	if len(s) < 3 {
		return errors.New("invalid Go version")
	}
	if s[0] != '1' {
		return errors.New("invalid Go version")
	}
	if s[1] != '.' {
		return errors.New("invalid Go version")
	}
	i, err := strconv.Atoi(s[2:])
	*v = versionFlag(i)
	return err
}

func (v *versionFlag) Get() interface{} {
	return int(*v)
}

type list []string

func (list *list) String() string {
	return `"` + strings.Join(*list, ",") + `"`
}

func (list *list) Set(s string) error {
	if s == "" {
		*list = nil
		return nil
	}

	*list = strings.Split(s, ",")
	return nil
}

func FlagSet(name string) *flag.FlagSet {
	flags := flag.NewFlagSet("", flag.ExitOnError)
	flags.Usage = usage(name, flags)
	flags.String("tags", "", "List of `build tags`")
	flags.String("ignore", "", "Deprecated: use linter directives instead")
	flags.Bool("tests", true, "Include tests")
	flags.Bool("version", false, "Print version and exit")
	flags.Bool("show-ignored", false, "Don't filter ignored problems")
	flags.String("f", "text", "Output `format` (valid choices are 'stylish', 'text' and 'json')")
	flags.String("explain", "", "Print description of `check`")

	flags.Int("debug.max-concurrent-jobs", 0, "Number of jobs to run concurrently")
	flags.Bool("debug.print-stats", false, "Print debug statistics")
	flags.String("debug.cpuprofile", "", "Write CPU profile to `file`")
	flags.String("debug.memprofile", "", "Write memory profile to `file`")

	checks := list{"inherit"}
	fail := list{"all"}
	flags.Var(&checks, "checks", "Comma-separated list of `checks` to enable.")
	flags.Var(&fail, "fail", "Comma-separated list of `checks` that can cause a non-zero exit status.")

	tags := build.Default.ReleaseTags
	v := tags[len(tags)-1][2:]
	version := new(versionFlag)
	if err := version.Set(v); err != nil {
		panic(fmt.Sprintf("internal error: %s", err))
	}

	flags.Var(version, "go", "Target Go `version` in the format '1.x'")
	return flags
}

func findCheck(cs []lint.Checker, check string) (lint.Check, bool) {
	for _, c := range cs {
		for _, cc := range c.Checks() {
			if cc.ID == check {
				return cc, true
			}
		}
	}
	return lint.Check{}, false
}

func ProcessFlagSet(cs []lint.Checker, fs *flag.FlagSet) {
	tags := fs.Lookup("tags").Value.(flag.Getter).Get().(string)
	ignore := fs.Lookup("ignore").Value.(flag.Getter).Get().(string)
	tests := fs.Lookup("tests").Value.(flag.Getter).Get().(bool)
	goVersion := fs.Lookup("go").Value.(flag.Getter).Get().(int)
	formatter := fs.Lookup("f").Value.(flag.Getter).Get().(string)
	printVersion := fs.Lookup("version").Value.(flag.Getter).Get().(bool)
	showIgnored := fs.Lookup("show-ignored").Value.(flag.Getter).Get().(bool)
	explain := fs.Lookup("explain").Value.(flag.Getter).Get().(string)

	maxConcurrentJobs := fs.Lookup("debug.max-concurrent-jobs").Value.(flag.Getter).Get().(int)
	printStats := fs.Lookup("debug.print-stats").Value.(flag.Getter).Get().(bool)
	cpuProfile := fs.Lookup("debug.cpuprofile").Value.(flag.Getter).Get().(string)
	memProfile := fs.Lookup("debug.memprofile").Value.(flag.Getter).Get().(string)

	cfg := config.Config{}
	cfg.Checks = *fs.Lookup("checks").Value.(*list)

	exit := func(code int) {
		if cpuProfile != "" {
			pprof.StopCPUProfile()
		}
		if memProfile != "" {
			f, err := os.Create(memProfile)
			if err != nil {
				panic(err)
			}
			runtime.GC()
			pprof.WriteHeapProfile(f)
		}
		os.Exit(code)
	}
	if cpuProfile != "" {
		f, err := os.Create(cpuProfile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
	}

	if printVersion {
		version.Print()
		exit(0)
	}

	if explain != "" {
		check, ok := findCheck(cs, explain)
		if !ok {
			fmt.Fprintln(os.Stderr, "Couldn't find check", explain)
			exit(1)
		}
		if check.Doc == "" {
			fmt.Fprintln(os.Stderr, explain, "has no documentation")
			exit(1)
		}
		fmt.Println(check.Doc)
		exit(0)
	}

	ps, err := Lint(cs, fs.Args(), &Options{
		Tags:          strings.Fields(tags),
		LintTests:     tests,
		Ignores:       ignore,
		GoVersion:     goVersion,
		ReturnIgnored: showIgnored,
		Config:        cfg,

		MaxConcurrentJobs: maxConcurrentJobs,
		PrintStats:        printStats,
	})
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		exit(1)
	}

	var f format.Formatter
	switch formatter {
	case "text":
		f = format.Text{W: os.Stdout}
	case "stylish":
		f = &format.Stylish{W: os.Stdout}
	case "json":
		f = format.JSON{W: os.Stdout}
	default:
		fmt.Fprintf(os.Stderr, "unsupported output format %q\n", formatter)
		exit(2)
	}

	var (
		total    int
		errors   int
		warnings int
	)

	fail := *fs.Lookup("fail").Value.(*list)
	var allChecks []string
	for _, p := range ps {
		allChecks = append(allChecks, p.Check)
	}

	shouldExit := lint.FilterChecks(allChecks, fail)

	total = len(ps)
	for _, p := range ps {
		if shouldExit[p.Check] {
			errors++
		} else {
			p.Severity = lint.Warning
			warnings++
		}
		f.Format(p)
	}
	if f, ok := f.(format.Statter); ok {
		f.Stats(total, errors, warnings)
	}
	if errors > 0 {
		exit(1)
	}
}

type Options struct {
	Config config.Config

	Tags          []string
	LintTests     bool
	Ignores       string
	GoVersion     int
	ReturnIgnored bool

	MaxConcurrentJobs int
	PrintStats        bool
}

func Lint(cs []lint.Checker, paths []string, opt *Options) ([]lint.Problem, error) {
	stats := lint.PerfStats{
		CheckerInits: map[string]time.Duration{},
	}

	if opt == nil {
		opt = &Options{}
	}
	ignores, err := parseIgnore(opt.Ignores)
	if err != nil {
		return nil, err
	}

	conf := &packages.Config{
		Mode:  packages.LoadAllSyntax,
		Tests: opt.LintTests,
		BuildFlags: []string{
			"-tags=" + strings.Join(opt.Tags, " "),
		},
	}

	t := time.Now()
	if len(paths) == 0 {
		paths = []string{"."}
	}
	pkgs, err := packages.Load(conf, paths...)
	if err != nil {
		return nil, err
	}
	stats.PackageLoading = time.Since(t)
	runtime.GC()

	var problems []lint.Problem
	workingPkgs := make([]*packages.Package, 0, len(pkgs))
	for _, pkg := range pkgs {
		if pkg.IllTyped {
			problems = append(problems, compileErrors(pkg)...)
		} else {
			workingPkgs = append(workingPkgs, pkg)
		}
	}

	if len(workingPkgs) == 0 {
		return problems, nil
	}

	l := &lint.Linter{
		Checkers:      cs,
		Ignores:       ignores,
		GoVersion:     opt.GoVersion,
		ReturnIgnored: opt.ReturnIgnored,
		Config:        opt.Config,

		MaxConcurrentJobs: opt.MaxConcurrentJobs,
		PrintStats:        opt.PrintStats,
	}
	problems = append(problems, l.Lint(workingPkgs, &stats)...)

	return problems, nil
}

var posRe = regexp.MustCompile(`^(.+?):(\d+)(?::(\d+)?)?$`)

func parsePos(pos string) token.Position {
	if pos == "-" || pos == "" {
		return token.Position{}
	}
	parts := posRe.FindStringSubmatch(pos)
	if parts == nil {
		panic(fmt.Sprintf("internal error: malformed position %q", pos))
	}
	file := parts[1]
	line, _ := strconv.Atoi(parts[2])
	col, _ := strconv.Atoi(parts[3])
	return token.Position{
		Filename: file,
		Line:     line,
		Column:   col,
	}
}

func compileErrors(pkg *packages.Package) []lint.Problem {
	if !pkg.IllTyped {
		return nil
	}
	if len(pkg.Errors) == 0 {
		// transitively ill-typed
		var ps []lint.Problem
		for _, imp := range pkg.Imports {
			ps = append(ps, compileErrors(imp)...)
		}
		return ps
	}
	var ps []lint.Problem
	for _, err := range pkg.Errors {
		p := lint.Problem{
			Position: parsePos(err.Pos),
			Text:     err.Msg,
			Checker:  "compiler",
			Check:    "compile",
		}
		ps = append(ps, p)
	}
	return ps
}

func ProcessArgs(name string, cs []lint.Checker, args []string) {
	flags := FlagSet(name)
	flags.Parse(args)

	ProcessFlagSet(cs, flags)
}
<commit_msg>lint/lintutil: set a default GOGC of 50<commit_after>// Copyright (c) 2013 The Go Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd.

// Package lintutil provides helpers for writing linter command lines.
package lintutil // import "honnef.co/go/tools/lint/lintutil"

import (
	"errors"
	"flag"
	"fmt"
	"go/build"
	"go/token"
	"log"
	"os"
	"regexp"
	"runtime"
	"runtime/debug"
	"runtime/pprof"
	"strconv"
	"strings"
	"time"

	"honnef.co/go/tools/config"
	"honnef.co/go/tools/lint"
	"honnef.co/go/tools/lint/lintutil/format"
	"honnef.co/go/tools/version"

	"golang.org/x/tools/go/packages"
)

func usage(name string, flags *flag.FlagSet) func() {
	return func() {
		fmt.Fprintf(os.Stderr, "Usage of %s:\n", name)
		fmt.Fprintf(os.Stderr, "\t%s [flags] # runs on package in current directory\n", name)
		fmt.Fprintf(os.Stderr, "\t%s [flags] packages\n", name)
		fmt.Fprintf(os.Stderr, "\t%s [flags] directory\n", name)
		fmt.Fprintf(os.Stderr, "\t%s [flags] files... # must be a single package\n", name)
		fmt.Fprintf(os.Stderr, "Flags:\n")
		flags.PrintDefaults()
	}
}

func parseIgnore(s string) ([]lint.Ignore, error) {
	var out []lint.Ignore
	if len(s) == 0 {
		return nil, nil
	}
	for _, part := range strings.Fields(s) {
		p := strings.Split(part, ":")
		if len(p) != 2 {
			return nil, errors.New("malformed ignore string")
		}
		path := p[0]
		checks := strings.Split(p[1], ",")
		out = append(out, &lint.GlobIgnore{Pattern: path, Checks: checks})
	}
	return out, nil
}

type versionFlag int

func (v *versionFlag) String() string {
	return fmt.Sprintf("1.%d", *v)
}

func (v *versionFlag) Set(s string) error {
	if len(s) < 3 {
		return errors.New("invalid Go version")
	}
	if s[0] != '1' {
		return errors.New("invalid Go version")
	}
	if s[1] != '.' {
		return errors.New("invalid Go version")
	}
	i, err := strconv.Atoi(s[2:])
	*v = versionFlag(i)
	return err
}

func (v *versionFlag) Get() interface{} {
	return int(*v)
}

type list []string

func (list *list) String() string {
	return `"` + strings.Join(*list, ",") + `"`
}

func (list *list) Set(s string) error {
	if s == "" {
		*list = nil
		return nil
	}

	*list = strings.Split(s, ",")
	return nil
}

func FlagSet(name string) *flag.FlagSet {
	flags := flag.NewFlagSet("", flag.ExitOnError)
	flags.Usage = usage(name, flags)
	flags.String("tags", "", "List of `build tags`")
	flags.String("ignore", "", "Deprecated: use linter directives instead")
	flags.Bool("tests", true, "Include tests")
	flags.Bool("version", false, "Print version and exit")
	flags.Bool("show-ignored", false, "Don't filter ignored problems")
	flags.String("f", "text", "Output `format` (valid choices are 'stylish', 'text' and 'json')")
	flags.String("explain", "", "Print description of `check`")

	flags.Int("debug.max-concurrent-jobs", 0, "Number of jobs to run concurrently")
	flags.Bool("debug.print-stats", false, "Print debug statistics")
	flags.String("debug.cpuprofile", "", "Write CPU profile to `file`")
	flags.String("debug.memprofile", "", "Write memory profile to `file`")

	checks := list{"inherit"}
	fail := list{"all"}
	flags.Var(&checks, "checks", "Comma-separated list of `checks` to enable.")
	flags.Var(&fail, "fail", "Comma-separated list of `checks` that can cause a non-zero exit status.")

	tags := build.Default.ReleaseTags
	v := tags[len(tags)-1][2:]
	version := new(versionFlag)
	if err := version.Set(v); err != nil {
		panic(fmt.Sprintf("internal error: %s", err))
	}

	flags.Var(version, "go", "Target Go `version` in the format '1.x'")
	return flags
}

func findCheck(cs []lint.Checker, check string) (lint.Check, bool) {
	for _, c := range cs {
		for _, cc := range c.Checks() {
			if cc.ID == check {
				return cc, true
			}
		}
	}
	return lint.Check{}, false
}

func ProcessFlagSet(cs []lint.Checker, fs *flag.FlagSet) {
	if _, ok := os.LookupEnv("GOGC"); !ok {
		debug.SetGCPercent(50)
	}

	tags := fs.Lookup("tags").Value.(flag.Getter).Get().(string)
	ignore := fs.Lookup("ignore").Value.(flag.Getter).Get().(string)
	tests := fs.Lookup("tests").Value.(flag.Getter).Get().(bool)
	goVersion := fs.Lookup("go").Value.(flag.Getter).Get().(int)
	formatter := fs.Lookup("f").Value.(flag.Getter).Get().(string)
	printVersion := fs.Lookup("version").Value.(flag.Getter).Get().(bool)
	showIgnored := fs.Lookup("show-ignored").Value.(flag.Getter).Get().(bool)
	explain := fs.Lookup("explain").Value.(flag.Getter).Get().(string)

	maxConcurrentJobs := fs.Lookup("debug.max-concurrent-jobs").Value.(flag.Getter).Get().(int)
	printStats := fs.Lookup("debug.print-stats").Value.(flag.Getter).Get().(bool)
	cpuProfile := fs.Lookup("debug.cpuprofile").Value.(flag.Getter).Get().(string)
	memProfile := fs.Lookup("debug.memprofile").Value.(flag.Getter).Get().(string)

	cfg := config.Config{}
	cfg.Checks = *fs.Lookup("checks").Value.(*list)

	exit := func(code int) {
		if cpuProfile != "" {
			pprof.StopCPUProfile()
		}
		if memProfile != "" {
			f, err := os.Create(memProfile)
			if err != nil {
				panic(err)
			}
			runtime.GC()
			pprof.WriteHeapProfile(f)
		}
		os.Exit(code)
	}
	if cpuProfile != "" {
		f, err := os.Create(cpuProfile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
	}

	if printVersion {
		version.Print()
		exit(0)
	}

	if explain != "" {
		check, ok := findCheck(cs, explain)
		if !ok {
			fmt.Fprintln(os.Stderr, "Couldn't find check", explain)
			exit(1)
		}
		if check.Doc == "" {
			fmt.Fprintln(os.Stderr, explain, "has no documentation")
			exit(1)
		}
		fmt.Println(check.Doc)
		exit(0)
	}

	ps, err := Lint(cs, fs.Args(), &Options{
		Tags:          strings.Fields(tags),
		LintTests:     tests,
		Ignores:       ignore,
		GoVersion:     goVersion,
		ReturnIgnored: showIgnored,
		Config:        cfg,

		MaxConcurrentJobs: maxConcurrentJobs,
		PrintStats:        printStats,
	})
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		exit(1)
	}

	var f format.Formatter
	switch formatter {
	case "text":
		f = format.Text{W: os.Stdout}
	case "stylish":
		f = &format.Stylish{W: os.Stdout}
	case "json":
		f = format.JSON{W: os.Stdout}
	default:
		fmt.Fprintf(os.Stderr, "unsupported output format %q\n", formatter)
		exit(2)
	}

	var (
		total    int
		errors   int
		warnings int
	)

	fail := *fs.Lookup("fail").Value.(*list)
	var allChecks []string
	for _, p := range ps {
		allChecks = append(allChecks, p.Check)
	}

	shouldExit := lint.FilterChecks(allChecks, fail)

	total = len(ps)
	for _, p := range ps {
		if shouldExit[p.Check] {
			errors++
		} else {
			p.Severity = lint.Warning
			warnings++
		}
		f.Format(p)
	}
	if f, ok := f.(format.Statter); ok {
		f.Stats(total, errors, warnings)
	}
	if errors > 0 {
		exit(1)
	}
}

type Options struct {
	Config config.Config

	Tags          []string
	LintTests     bool
	Ignores       string
	GoVersion     int
	ReturnIgnored bool

	MaxConcurrentJobs int
	PrintStats        bool
}

func Lint(cs []lint.Checker, paths []string, opt *Options) ([]lint.Problem, error) {
	stats := lint.PerfStats{
		CheckerInits: map[string]time.Duration{},
	}

	if opt == nil {
		opt = &Options{}
	}
	ignores, err := parseIgnore(opt.Ignores)
	if err != nil {
		return nil, err
	}

	conf := &packages.Config{
		Mode:  packages.LoadAllSyntax,
		Tests: opt.LintTests,
		BuildFlags: []string{
			"-tags=" + strings.Join(opt.Tags, " "),
		},
	}

	t := time.Now()
	if len(paths) == 0 {
		paths = []string{"."}
	}
	pkgs, err := packages.Load(conf, paths...)
	if err != nil {
		return nil, err
	}
	stats.PackageLoading = time.Since(t)
	runtime.GC()

	var problems []lint.Problem
	workingPkgs := make([]*packages.Package, 0, len(pkgs))
	for _, pkg := range pkgs {
		if pkg.IllTyped {
			problems = append(problems, compileErrors(pkg)...)
		} else {
			workingPkgs = append(workingPkgs, pkg)
		}
	}

	if len(workingPkgs) == 0 {
		return problems, nil
	}

	l := &lint.Linter{
		Checkers:      cs,
		Ignores:       ignores,
		GoVersion:     opt.GoVersion,
		ReturnIgnored: opt.ReturnIgnored,
		Config:        opt.Config,

		MaxConcurrentJobs: opt.MaxConcurrentJobs,
		PrintStats:        opt.PrintStats,
	}
	problems = append(problems, l.Lint(workingPkgs, &stats)...)

	return problems, nil
}

var posRe = regexp.MustCompile(`^(.+?):(\d+)(?::(\d+)?)?$`)

func parsePos(pos string) token.Position {
	if pos == "-" || pos == "" {
		return token.Position{}
	}
	parts := posRe.FindStringSubmatch(pos)
	if parts == nil {
		panic(fmt.Sprintf("internal error: malformed position %q", pos))
	}
	file := parts[1]
	line, _ := strconv.Atoi(parts[2])
	col, _ := strconv.Atoi(parts[3])
	return token.Position{
		Filename: file,
		Line:     line,
		Column:   col,
	}
}

func compileErrors(pkg *packages.Package) []lint.Problem {
	if !pkg.IllTyped {
		return nil
	}
	if len(pkg.Errors) == 0 {
		// transitively ill-typed
		var ps []lint.Problem
		for _, imp := range pkg.Imports {
			ps = append(ps, compileErrors(imp)...)
		}
		return ps
	}
	var ps []lint.Problem
	for _, err := range pkg.Errors {
		p := lint.Problem{
			Position: parsePos(err.Pos),
			Text:     err.Msg,
			Checker:  "compiler",
			Check:    "compile",
		}
		ps = append(ps, p)
	}
	return ps
}

func ProcessArgs(name string, cs []lint.Checker, args []string) {
	flags := FlagSet(name)
	flags.Parse(args)

	ProcessFlagSet(cs, flags)
}
<|endoftext|>