<commit_before>package main

import (
	"encoding/json"
	"os"
	"os/exec"
	"reflect"
	"strings"
	"time"

	"github.com/docker/docker/nat"
	"github.com/go-check/check"
)

// Make sure we can create a simple container with some args
func (s *DockerSuite) TestCreateArgs(c *check.C) {
	runCmd := exec.Command(dockerBinary, "create", "busybox", "command", "arg1", "arg2", "arg with space")
	out, _, _, err := runCommandWithStdoutStderr(runCmd)
	if err != nil {
		c.Fatal(out, err)
	}

	cleanedContainerID := strings.TrimSpace(out)

	inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
	out, _, err = runCommandWithOutput(inspectCmd)
	if err != nil {
		c.Fatalf("out should've been a container id: %s, %v", out, err)
	}

	containers := []struct {
		ID      string
		Created time.Time
		Path    string
		Args    []string
		Image   string
	}{}
	if err := json.Unmarshal([]byte(out), &containers); err != nil {
		c.Fatalf("Error inspecting the container: %s", err)
	}
	if len(containers) != 1 {
		c.Fatalf("Unexpected container count. Expected 0, received: %d", len(containers))
	}

	cont := containers[0]
	if cont.Path != "command" {
		c.Fatalf("Unexpected container path. Expected command, received: %s", cont.Path)
	}

	b := false
	expected := []string{"arg1", "arg2", "arg with space"}
	for i, arg := range expected {
		if arg != cont.Args[i] {
			b = true
			break
		}
	}
	if len(cont.Args) != len(expected) || b {
		c.Fatalf("Unexpected args. Expected %v, received: %v", expected, cont.Args)
	}

}

// Make sure we can set hostconfig options too
func (s *DockerSuite) TestCreateHostConfig(c *check.C) {

	runCmd := exec.Command(dockerBinary, "create", "-P", "busybox", "echo")
	out, _, _, err := runCommandWithStdoutStderr(runCmd)
	if err != nil {
		c.Fatal(out, err)
	}

	cleanedContainerID := strings.TrimSpace(out)

	inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
	out, _, err = runCommandWithOutput(inspectCmd)
	if err != nil {
		c.Fatalf("out should've been a container id: %s, %v", out, err)
	}

	containers := []struct {
		HostConfig *struct {
			PublishAllPorts bool
		}
	}{}
	if err := json.Unmarshal([]byte(out), &containers); err != nil {
		c.Fatalf("Error inspecting the container: %s", err)
	}
	if len(containers) != 1 {
		c.Fatalf("Unexpected container count. Expected 0, received: %d", len(containers))
	}

	cont := containers[0]
	if cont.HostConfig == nil {
		c.Fatalf("Expected HostConfig, got none")
	}

	if !cont.HostConfig.PublishAllPorts {
		c.Fatalf("Expected PublishAllPorts, got false")
	}

}

func (s *DockerSuite) TestCreateWithPortRange(c *check.C) {

	runCmd := exec.Command(dockerBinary, "create", "-p", "3300-3303:3300-3303/tcp", "busybox", "echo")
	out, _, _, err := runCommandWithStdoutStderr(runCmd)
	if err != nil {
		c.Fatal(out, err)
	}

	cleanedContainerID := strings.TrimSpace(out)

	inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
	out, _, err = runCommandWithOutput(inspectCmd)
	if err != nil {
		c.Fatalf("out should've been a container id: %s, %v", out, err)
	}

	containers := []struct {
		HostConfig *struct {
			PortBindings map[nat.Port][]nat.PortBinding
		}
	}{}
	if err := json.Unmarshal([]byte(out), &containers); err != nil {
		c.Fatalf("Error inspecting the container: %s", err)
	}
	if len(containers) != 1 {
		c.Fatalf("Unexpected container count. Expected 0, received: %d", len(containers))
	}

	cont := containers[0]
	if cont.HostConfig == nil {
		c.Fatalf("Expected HostConfig, got none")
	}

	if len(cont.HostConfig.PortBindings) != 4 {
		c.Fatalf("Expected 4 ports bindings, got %d", len(cont.HostConfig.PortBindings))
	}
	for k, v := range cont.HostConfig.PortBindings {
		if len(v) != 1 {
			c.Fatalf("Expected 1 ports binding, for the port  %s but found %s", k, v)
		}
		if k.Port() != v[0].HostPort {
			c.Fatalf("Expected host port %d to match published port  %d", k.Port(), v[0].HostPort)
		}
	}

}

func (s *DockerSuite) TestCreateWithiLargePortRange(c *check.C) {

	runCmd := exec.Command(dockerBinary, "create", "-p", "1-65535:1-65535/tcp", "busybox", "echo")
	out, _, _, err := runCommandWithStdoutStderr(runCmd)
	if err != nil {
		c.Fatal(out, err)
	}

	cleanedContainerID := strings.TrimSpace(out)

	inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
	out, _, err = runCommandWithOutput(inspectCmd)
	if err != nil {
		c.Fatalf("out should've been a container id: %s, %v", out, err)
	}

	containers := []struct {
		HostConfig *struct {
			PortBindings map[nat.Port][]nat.PortBinding
		}
	}{}
	if err := json.Unmarshal([]byte(out), &containers); err != nil {
		c.Fatalf("Error inspecting the container: %s", err)
	}
	if len(containers) != 1 {
		c.Fatalf("Unexpected container count. Expected 0, received: %d", len(containers))
	}

	cont := containers[0]
	if cont.HostConfig == nil {
		c.Fatalf("Expected HostConfig, got none")
	}

	if len(cont.HostConfig.PortBindings) != 65535 {
		c.Fatalf("Expected 65535 ports bindings, got %d", len(cont.HostConfig.PortBindings))
	}
	for k, v := range cont.HostConfig.PortBindings {
		if len(v) != 1 {
			c.Fatalf("Expected 1 ports binding, for the port  %s but found %s", k, v)
		}
		if k.Port() != v[0].HostPort {
			c.Fatalf("Expected host port %d to match published port  %d", k.Port(), v[0].HostPort)
		}
	}

}

// "test123" should be printed by docker create + start
func (s *DockerSuite) TestCreateEchoStdout(c *check.C) {

	runCmd := exec.Command(dockerBinary, "create", "busybox", "echo", "test123")
	out, _, _, err := runCommandWithStdoutStderr(runCmd)
	if err != nil {
		c.Fatal(out, err)
	}

	cleanedContainerID := strings.TrimSpace(out)

	runCmd = exec.Command(dockerBinary, "start", "-ai", cleanedContainerID)
	out, _, _, err = runCommandWithStdoutStderr(runCmd)
	if err != nil {
		c.Fatal(out, err)
	}

	if out != "test123\n" {
		c.Errorf("container should've printed 'test123', got %q", out)
	}

}

func (s *DockerSuite) TestCreateVolumesCreated(c *check.C) {
	testRequires(c, SameHostDaemon)

	name := "test_create_volume"
	if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "create", "--name", name, "-v", "/foo", "busybox")); err != nil {
		c.Fatal(out, err)
	}
	dir, err := inspectFieldMap(name, "Volumes", "/foo")
	if err != nil {
		c.Fatalf("Error getting volume host path: %q", err)
	}

	if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
		c.Fatalf("Volume was not created")
	}
	if err != nil {
		c.Fatalf("Error statting volume host path: %q", err)
	}

}

func (s *DockerSuite) TestCreateLabels(c *check.C) {
	name := "test_create_labels"
	expected := map[string]string{"k1": "v1", "k2": "v2"}
	if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "create", "--name", name, "-l", "k1=v1", "--label", "k2=v2", "busybox")); err != nil {
		c.Fatal(out, err)
	}

	actual := make(map[string]string)
	err := inspectFieldAndMarshall(name, "Config.Labels", &actual)
	if err != nil {
		c.Fatal(err)
	}

	if !reflect.DeepEqual(expected, actual) {
		c.Fatalf("Expected %s got %s", expected, actual)
	}
}

func (s *DockerSuite) TestCreateLabelFromImage(c *check.C) {
	imageName := "testcreatebuildlabel"
	_, err := buildImage(imageName,
		`FROM busybox
		LABEL k1=v1 k2=v2`,
		true)
	if err != nil {
		c.Fatal(err)
	}

	name := "test_create_labels_from_image"
	expected := map[string]string{"k2": "x", "k3": "v3", "k1": "v1"}
	if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "create", "--name", name, "-l", "k2=x", "--label", "k3=v3", imageName)); err != nil {
		c.Fatal(out, err)
	}

	actual := make(map[string]string)
	err = inspectFieldAndMarshall(name, "Config.Labels", &actual)
	if err != nil {
		c.Fatal(err)
	}

	if !reflect.DeepEqual(expected, actual) {
		c.Fatalf("Expected %s got %s", expected, actual)
	}
}

func (s *DockerSuite) TestCreateHostnameWithNumber(c *check.C) {
	out, _ := dockerCmd(c, "run", "-h", "web.0", "busybox", "hostname")
	if strings.TrimSpace(out) != "web.0" {
		c.Fatalf("hostname not set, expected `web.0`, got: %s", out)
	}
}
<commit_msg>Add a 'docker create' + 'docker rm' testcase Per @thaJeztah's comment here: https://github.com/docker/docker/pull/13367#issuecomment-104286651 I couldn't find an existing test that covered this.<commit_after>package main

import (
	"encoding/json"
	"os"
	"os/exec"
	"reflect"
	"strings"
	"time"

	"github.com/docker/docker/nat"
	"github.com/go-check/check"
)

// Make sure we can create a simple container with some args
func (s *DockerSuite) TestCreateArgs(c *check.C) {
	runCmd := exec.Command(dockerBinary, "create", "busybox", "command", "arg1", "arg2", "arg with space")
	out, _, _, err := runCommandWithStdoutStderr(runCmd)
	if err != nil {
		c.Fatal(out, err)
	}

	cleanedContainerID := strings.TrimSpace(out)

	inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
	out, _, err = runCommandWithOutput(inspectCmd)
	if err != nil {
		c.Fatalf("out should've been a container id: %s, %v", out, err)
	}

	containers := []struct {
		ID      string
		Created time.Time
		Path    string
		Args    []string
		Image   string
	}{}
	if err := json.Unmarshal([]byte(out), &containers); err != nil {
		c.Fatalf("Error inspecting the container: %s", err)
	}
	if len(containers) != 1 {
		c.Fatalf("Unexpected container count. Expected 0, received: %d", len(containers))
	}

	cont := containers[0]
	if cont.Path != "command" {
		c.Fatalf("Unexpected container path. Expected command, received: %s", cont.Path)
	}

	b := false
	expected := []string{"arg1", "arg2", "arg with space"}
	for i, arg := range expected {
		if arg != cont.Args[i] {
			b = true
			break
		}
	}
	if len(cont.Args) != len(expected) || b {
		c.Fatalf("Unexpected args. Expected %v, received: %v", expected, cont.Args)
	}

}

// Make sure we can set hostconfig options too
func (s *DockerSuite) TestCreateHostConfig(c *check.C) {

	runCmd := exec.Command(dockerBinary, "create", "-P", "busybox", "echo")
	out, _, _, err := runCommandWithStdoutStderr(runCmd)
	if err != nil {
		c.Fatal(out, err)
	}

	cleanedContainerID := strings.TrimSpace(out)

	inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
	out, _, err = runCommandWithOutput(inspectCmd)
	if err != nil {
		c.Fatalf("out should've been a container id: %s, %v", out, err)
	}

	containers := []struct {
		HostConfig *struct {
			PublishAllPorts bool
		}
	}{}
	if err := json.Unmarshal([]byte(out), &containers); err != nil {
		c.Fatalf("Error inspecting the container: %s", err)
	}
	if len(containers) != 1 {
		c.Fatalf("Unexpected container count. Expected 0, received: %d", len(containers))
	}

	cont := containers[0]
	if cont.HostConfig == nil {
		c.Fatalf("Expected HostConfig, got none")
	}

	if !cont.HostConfig.PublishAllPorts {
		c.Fatalf("Expected PublishAllPorts, got false")
	}

}

func (s *DockerSuite) TestCreateWithPortRange(c *check.C) {

	runCmd := exec.Command(dockerBinary, "create", "-p", "3300-3303:3300-3303/tcp", "busybox", "echo")
	out, _, _, err := runCommandWithStdoutStderr(runCmd)
	if err != nil {
		c.Fatal(out, err)
	}

	cleanedContainerID := strings.TrimSpace(out)

	inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
	out, _, err = runCommandWithOutput(inspectCmd)
	if err != nil {
		c.Fatalf("out should've been a container id: %s, %v", out, err)
	}

	containers := []struct {
		HostConfig *struct {
			PortBindings map[nat.Port][]nat.PortBinding
		}
	}{}
	if err := json.Unmarshal([]byte(out), &containers); err != nil {
		c.Fatalf("Error inspecting the container: %s", err)
	}
	if len(containers) != 1 {
		c.Fatalf("Unexpected container count. Expected 0, received: %d", len(containers))
	}

	cont := containers[0]
	if cont.HostConfig == nil {
		c.Fatalf("Expected HostConfig, got none")
	}

	if len(cont.HostConfig.PortBindings) != 4 {
		c.Fatalf("Expected 4 ports bindings, got %d", len(cont.HostConfig.PortBindings))
	}
	for k, v := range cont.HostConfig.PortBindings {
		if len(v) != 1 {
			c.Fatalf("Expected 1 ports binding, for the port  %s but found %s", k, v)
		}
		if k.Port() != v[0].HostPort {
			c.Fatalf("Expected host port %d to match published port  %d", k.Port(), v[0].HostPort)
		}
	}

}

func (s *DockerSuite) TestCreateWithiLargePortRange(c *check.C) {

	runCmd := exec.Command(dockerBinary, "create", "-p", "1-65535:1-65535/tcp", "busybox", "echo")
	out, _, _, err := runCommandWithStdoutStderr(runCmd)
	if err != nil {
		c.Fatal(out, err)
	}

	cleanedContainerID := strings.TrimSpace(out)

	inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
	out, _, err = runCommandWithOutput(inspectCmd)
	if err != nil {
		c.Fatalf("out should've been a container id: %s, %v", out, err)
	}

	containers := []struct {
		HostConfig *struct {
			PortBindings map[nat.Port][]nat.PortBinding
		}
	}{}
	if err := json.Unmarshal([]byte(out), &containers); err != nil {
		c.Fatalf("Error inspecting the container: %s", err)
	}
	if len(containers) != 1 {
		c.Fatalf("Unexpected container count. Expected 0, received: %d", len(containers))
	}

	cont := containers[0]
	if cont.HostConfig == nil {
		c.Fatalf("Expected HostConfig, got none")
	}

	if len(cont.HostConfig.PortBindings) != 65535 {
		c.Fatalf("Expected 65535 ports bindings, got %d", len(cont.HostConfig.PortBindings))
	}
	for k, v := range cont.HostConfig.PortBindings {
		if len(v) != 1 {
			c.Fatalf("Expected 1 ports binding, for the port  %s but found %s", k, v)
		}
		if k.Port() != v[0].HostPort {
			c.Fatalf("Expected host port %d to match published port  %d", k.Port(), v[0].HostPort)
		}
	}

}

// "test123" should be printed by docker create + start
func (s *DockerSuite) TestCreateEchoStdout(c *check.C) {

	runCmd := exec.Command(dockerBinary, "create", "busybox", "echo", "test123")
	out, _, _, err := runCommandWithStdoutStderr(runCmd)
	if err != nil {
		c.Fatal(out, err)
	}

	cleanedContainerID := strings.TrimSpace(out)

	runCmd = exec.Command(dockerBinary, "start", "-ai", cleanedContainerID)
	out, _, _, err = runCommandWithStdoutStderr(runCmd)
	if err != nil {
		c.Fatal(out, err)
	}

	if out != "test123\n" {
		c.Errorf("container should've printed 'test123', got %q", out)
	}

}

func (s *DockerSuite) TestCreateVolumesCreated(c *check.C) {
	testRequires(c, SameHostDaemon)

	name := "test_create_volume"
	if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "create", "--name", name, "-v", "/foo", "busybox")); err != nil {
		c.Fatal(out, err)
	}
	dir, err := inspectFieldMap(name, "Volumes", "/foo")
	if err != nil {
		c.Fatalf("Error getting volume host path: %q", err)
	}

	if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
		c.Fatalf("Volume was not created")
	}
	if err != nil {
		c.Fatalf("Error statting volume host path: %q", err)
	}

}

func (s *DockerSuite) TestCreateLabels(c *check.C) {
	name := "test_create_labels"
	expected := map[string]string{"k1": "v1", "k2": "v2"}
	if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "create", "--name", name, "-l", "k1=v1", "--label", "k2=v2", "busybox")); err != nil {
		c.Fatal(out, err)
	}

	actual := make(map[string]string)
	err := inspectFieldAndMarshall(name, "Config.Labels", &actual)
	if err != nil {
		c.Fatal(err)
	}

	if !reflect.DeepEqual(expected, actual) {
		c.Fatalf("Expected %s got %s", expected, actual)
	}
}

func (s *DockerSuite) TestCreateLabelFromImage(c *check.C) {
	imageName := "testcreatebuildlabel"
	_, err := buildImage(imageName,
		`FROM busybox
		LABEL k1=v1 k2=v2`,
		true)
	if err != nil {
		c.Fatal(err)
	}

	name := "test_create_labels_from_image"
	expected := map[string]string{"k2": "x", "k3": "v3", "k1": "v1"}
	if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "create", "--name", name, "-l", "k2=x", "--label", "k3=v3", imageName)); err != nil {
		c.Fatal(out, err)
	}

	actual := make(map[string]string)
	err = inspectFieldAndMarshall(name, "Config.Labels", &actual)
	if err != nil {
		c.Fatal(err)
	}

	if !reflect.DeepEqual(expected, actual) {
		c.Fatalf("Expected %s got %s", expected, actual)
	}
}

func (s *DockerSuite) TestCreateHostnameWithNumber(c *check.C) {
	out, _ := dockerCmd(c, "run", "-h", "web.0", "busybox", "hostname")
	if strings.TrimSpace(out) != "web.0" {
		c.Fatalf("hostname not set, expected `web.0`, got: %s", out)
	}
}

func (s *DockerSuite) TestCreateRM(c *check.C) {
	// Test to make sure we can 'rm' a new container that is in
	// "Created" state, and has ever been run. Test "rm -f" too.

	// create a container
	createCmd := exec.Command(dockerBinary, "create", "busybox")
	out, _, err := runCommandWithOutput(createCmd)
	if err != nil {
		c.Fatalf("Failed to create container:%s\n%s", out, err)
	}
	cID := strings.TrimSpace(out)

	rmCmd := exec.Command(dockerBinary, "rm", cID)
	out, _, err = runCommandWithOutput(rmCmd)
	if err != nil {
		c.Fatalf("Failed to rm container:%s\n%s", out, err)
	}

	// Now do it again so we can "rm -f" this time
	createCmd = exec.Command(dockerBinary, "create", "busybox")
	out, _, err = runCommandWithOutput(createCmd)
	if err != nil {
		c.Fatalf("Failed to create 2nd container:%s\n%s", out, err)
	}

	cID = strings.TrimSpace(out)
	rmCmd = exec.Command(dockerBinary, "rm", "-f", cID)
	out, _, err = runCommandWithOutput(rmCmd)
	if err != nil {
		c.Fatalf("Failed to rm -f container:%s\n%s", out, err)
	}
}
<|endoftext|>


<commit_before>// Copyright 2018 Google LLC
//
// 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
//
//     https://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 amphtml

import (
	"regexp"
	"sort"
	"strings"
)

const defaultDensity = "1x"

var (
	// List of legitimate widths. These were computed with step size of 20% starting from 100.
	legitimateWidths = [...]int{39, 47, 56, 68, 82, 100, 120, 150, 180, 220, 270, 330, 390, 470, 560, 680, 820, 1000, 1200}

	// List of supported pixel device densities (DPRs)
	dprs = [3]float32{1.0, 2.0, 3.0}
)

// GetSrcsetWidths returns a slice of widths based on the input width, or false if there are
// not at least two legitimate widths.
func GetSrcsetWidths(w int) ([]int, bool) {
	if w < 0 {
		return nil, false
	}
	prev := -1
	var widths []int
	for _, dpr := range dprs {
		// int cast truncates. Add 0.5 to achieve rounding.
		width := roundUp(int(dpr*float32(w) + 0.5))
		if width != prev {
			widths = append(widths, width)
		}
		prev = width
	}
	if len(widths) > 1 {
		return widths, true
	}
	return nil, false
}

// roundUp rounds up to the closest legitimate width (or the largest possible) and returns it.
func roundUp(w int) int {
	for _, width := range legitimateWidths {
		if width >= w {
			return width
		}
	}
	return legitimateWidths[len(legitimateWidths)-1]
}

// Regex for leading spaces, followed by an optional comma and whitespace,
// followed by an URL*, followed by an optional space, followed by an
// optional width or pixel density**, followed by spaces, followed by an
// optional comma and whitespace.
//
// URL*: matches non-space, non-empty string which neither ends nor begins
// with a comma. The set of space characters in the srcset attribute is
// defined to include only ascii characters, so using \s, which is an
// ascii only character set, is fine. See
// https://html.spec.whatwg.org/multipage/infrastructure.html#space-character.
//
// Optional width or pixel density**: Matches the empty string or (one or
// more spaces + a non empty string containing no space or commas).
// Doesn't capture the initial space.
//
// \s*                       Match, but don't capture leading spaces.
// (?:,\s*)?                 Optionally match comma and trailing space,
//                           but don't capture comma.
// ([^,\s]\S*[^,\s])         Match something like "google.com/favicon.ico"
//                           but not ",google.com/favicon.ico,".
// \s*                       Match, but don't capture spaces.
// (                         Match the width or density descriptor...
//   [1-9]\d*[wx]            which is a non-zero integer followed by a w
//                           or an x ...
//   |                       or ...
//   [1-9]\d*\.\d+x          a decimal with its whole-number part greater
//                           than zero and followed by an x ...
//   |                       or ...
//   0.\d*[1-9]\d*x          a decimal with its fractional part greater
//                           than zero and followed by an x ...
// )?                        and make it optional.
// \s*                       Match, but don't capture space
// (?:(,)\s*)?               Optionally match comma and trailing space,
//                           capturing comma.
var imageCandidateRE = regexp.MustCompile(
	`\s*` +
		`(?:,\s*)?` +
		`([^,\s]\S*[^,\s])` +
		`\s*` +
		`(` +
		`[1-9]\d*[wx]` +
		`|` +
		`[1-9]\d*\.\d+x` +
		`|` +
		`0.\d*[1-9]\d*` +
		`)?` +
		`\s*` +
		`(?:(,)\s*)?`)

// ParseSrcset parses the given srcset attribute value of its
// image candidates (as defined by
// https://html.spec.whatwg.org/multipage/images.html#image-candidate-string)
// and returns the normalized srcset value, and a slice of SubresourceOffset structs
// corresponding to the normalized value. If there is no width or
// pixel density, it defaults to 1x.
// If any portion of the input is unparseable, or if there are duplicate widths
// or pixel densities, return input unparsed.
func ParseSrcset(in string) (string, []SubresourceOffset) {
	matches := imageCandidateRE.FindAllStringSubmatch(in, -1)
	if len(matches) == 0 {
		return in, []SubresourceOffset{}
	}
	var keys []string
	// map of density to url
	seen := make(map[string]string)
	for i, m := range matches {
		d := defaultDensity
		if len(m[2]) > 0 {
			d = m[2]
		}
		if _, ok := seen[d]; ok {
			// duplicate width or pixel density
			return in, []SubresourceOffset{}
		}
		seen[d] = m[1]
		keys = append(keys, d)
		if i < len(matches)-1 {
			if len(m[3]) == 0 {
				// missing expected comma delimiter
				return in, []SubresourceOffset{}
			}
		}
	}

	// Sort the keys of our map (for deterministic behavior)
	sort.Strings(keys)

	// Reconstitute the input and build the offsets.
	var ret []SubresourceOffset
	var pos int
	var sb strings.Builder
	for i, key := range keys {
		src := seen[key]
		slen, _ := sb.WriteString(src + " " + key)
		ret = append(ret, SubresourceOffset{Start: pos, End: pos + len(src)})
		pos += slen
		if i < len(seen)-1 {
			slen, _ := sb.WriteString(", ")
			pos += slen
		}
	}
	return sb.String(), ret
}

<commit_msg>Fix regex in srcset parser. One of the . was not being escaped, and an x was missing.<commit_after>// Copyright 2018 Google LLC
//
// 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
//
//     https://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 amphtml

import (
	"regexp"
	"sort"
	"strings"
)

const defaultDensity = "1x"

var (
	// List of legitimate widths. These were computed with step size of 20% starting from 100.
	legitimateWidths = [...]int{39, 47, 56, 68, 82, 100, 120, 150, 180, 220, 270, 330, 390, 470, 560, 680, 820, 1000, 1200}

	// List of supported pixel device densities (DPRs)
	dprs = [3]float32{1.0, 2.0, 3.0}
)

// GetSrcsetWidths returns a slice of widths based on the input width, or false if there are
// not at least two legitimate widths.
func GetSrcsetWidths(w int) ([]int, bool) {
	if w < 0 {
		return nil, false
	}
	prev := -1
	var widths []int
	for _, dpr := range dprs {
		// int cast truncates. Add 0.5 to achieve rounding.
		width := roundUp(int(dpr*float32(w) + 0.5))
		if width != prev {
			widths = append(widths, width)
		}
		prev = width
	}
	if len(widths) > 1 {
		return widths, true
	}
	return nil, false
}

// roundUp rounds up to the closest legitimate width (or the largest possible) and returns it.
func roundUp(w int) int {
	for _, width := range legitimateWidths {
		if width >= w {
			return width
		}
	}
	return legitimateWidths[len(legitimateWidths)-1]
}

// Regex for leading spaces, followed by an optional comma and whitespace,
// followed by an URL*, followed by an optional space, followed by an
// optional width or pixel density**, followed by spaces, followed by an
// optional comma and whitespace.
//
// URL*: matches non-space, non-empty string which neither ends nor begins
// with a comma. The set of space characters in the srcset attribute is
// defined to include only ascii characters, so using \s, which is an
// ascii only character set, is fine. See
// https://html.spec.whatwg.org/multipage/infrastructure.html#space-character.
//
// Optional width or pixel density**: Matches the empty string or (one or
// more spaces + a non empty string containing no space or commas).
// Doesn't capture the initial space.
//
// \s*                       Match, but don't capture leading spaces.
// (?:,\s*)?                 Optionally match comma and trailing space,
//                           but don't capture comma.
// ([^,\s]\S*[^,\s])         Match something like "google.com/favicon.ico"
//                           but not ",google.com/favicon.ico,".
// \s*                       Match, but don't capture spaces.
// (                         Match the width or density descriptor...
//   [1-9]\d*[wx]            which is a non-zero integer followed by a w
//                           or an x ...
//   |                       or ...
//   [1-9]\d*\.\d+x          a decimal with its whole-number part greater
//                           than zero and followed by an x ...
//   |                       or ...
//   0\.\d*[1-9]\d*x         a decimal with its fractional part greater
//                           than zero and followed by an x ...
// )?                        and make it optional.
// \s*                       Match, but don't capture space
// (?:(,)\s*)?               Optionally match comma and trailing space,
//                           capturing comma.
var imageCandidateRE = regexp.MustCompile(
	`\s*` +
		`(?:,\s*)?` +
		`([^,\s]\S*[^,\s])` +
		`\s*` +
		`(` +
		`[1-9]\d*[wx]` +
		`|` +
		`[1-9]\d*\.\d+x` +
		`|` +
		`0\.\d*[1-9]\d*x` +
		`)?` +
		`\s*` +
		`(?:(,)\s*)?`)

// ParseSrcset parses the given srcset attribute value of its
// image candidates (as defined by
// https://html.spec.whatwg.org/multipage/images.html#image-candidate-string)
// and returns the normalized srcset value, and a slice of SubresourceOffset structs
// corresponding to the normalized value. If there is no width or
// pixel density, it defaults to 1x.
// If any portion of the input is unparseable, or if there are duplicate widths
// or pixel densities, return input unparsed.
func ParseSrcset(in string) (string, []SubresourceOffset) {
	matches := imageCandidateRE.FindAllStringSubmatch(in, -1)
	if len(matches) == 0 {
		return in, []SubresourceOffset{}
	}
	var keys []string
	// map of density to url
	seen := make(map[string]string)
	for i, m := range matches {
		d := defaultDensity
		if len(m[2]) > 0 {
			d = m[2]
		}
		if _, ok := seen[d]; ok {
			// duplicate width or pixel density
			return in, []SubresourceOffset{}
		}
		seen[d] = m[1]
		keys = append(keys, d)
		if i < len(matches)-1 {
			if len(m[3]) == 0 {
				// missing expected comma delimiter
				return in, []SubresourceOffset{}
			}
		}
	}

	// Sort the keys of our map (for deterministic behavior)
	sort.Strings(keys)

	// Reconstitute the input and build the offsets.
	var ret []SubresourceOffset
	var pos int
	var sb strings.Builder
	for i, key := range keys {
		src := seen[key]
		slen, _ := sb.WriteString(src + " " + key)
		ret = append(ret, SubresourceOffset{Start: pos, End: pos + len(src)})
		pos += slen
		if i < len(seen)-1 {
			slen, _ := sb.WriteString(", ")
			pos += slen
		}
	}
	return sb.String(), ret
}

<|endoftext|>


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

package pic

import (
	"bytes"
	"encoding/base64"
	"fmt"
	"image"
	"image/png"
)

func Show(f func(int, int) [][]uint8) {
	const (
		dx = 256
		dy = 256
	)
	data := f(dx, dy)
	m := image.NewNRGBA(image.Rect(0, 0, dx, dy))
	for y := 0; y < dy; y++ {
		for x := 0; x < dx; x++ {
			v := data[y][x]
			i := y*m.Stride + x*4
			m.Pix[i] = v
			m.Pix[i+1] = v
			m.Pix[i+2] = 255
			m.Pix[i+3] = 255
		}
	}
	ShowImage(m)
}

func ShowImage(m image.Image) {
	var buf bytes.Buffer
	png.Encode(&buf, m)
	enc := base64.StdEncoding.EncodeToString(buf.Bytes())
	fmt.Println("IMAGE:" + enc)
}
<commit_msg>go-tour: panic on failed png encode in tour/pic.ShowImage<commit_after>// Copyright 2011 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package pic

import (
	"bytes"
	"encoding/base64"
	"fmt"
	"image"
	"image/png"
)

func Show(f func(int, int) [][]uint8) {
	const (
		dx = 256
		dy = 256
	)
	data := f(dx, dy)
	m := image.NewNRGBA(image.Rect(0, 0, dx, dy))
	for y := 0; y < dy; y++ {
		for x := 0; x < dx; x++ {
			v := data[y][x]
			i := y*m.Stride + x*4
			m.Pix[i] = v
			m.Pix[i+1] = v
			m.Pix[i+2] = 255
			m.Pix[i+3] = 255
		}
	}
	ShowImage(m)
}

func ShowImage(m image.Image) {
	var buf bytes.Buffer
	err := png.Encode(&buf, m)
	if err != nil {
		panic(err)
	}
	enc := base64.StdEncoding.EncodeToString(buf.Bytes())
	fmt.Println("IMAGE:" + enc)
}
<|endoftext|>


<commit_before>// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package bzr_test

import (
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"testing"

	gc "launchpad.net/gocheck"

	"launchpad.net/juju-core/bzr"
	"launchpad.net/juju-core/testing/testbase"
)

func Test(t *testing.T) {
	gc.TestingT(t)
}

var _ = gc.Suite(&BzrSuite{})

type BzrSuite struct {
	testbase.LoggingSuite
	b *bzr.Branch
}

const bzr_config = `[DEFAULT]
email = testing <test@example.com>
`

func (s *BzrSuite) SetUpTest(c *gc.C) {
	s.LoggingSuite.SetUpTest(c)
	bzrdir := c.MkDir()
	s.PatchEnvironment("BZR_HOME", bzrdir)
	err := os.Mkdir(filepath.Join(bzrdir, ".bazaar"), 0755)
	c.Assert(err, gc.IsNil)
	err = ioutil.WriteFile(
		filepath.Join(bzrdir, ".bazaar", "bazaar.conf"),
		[]byte(bzr_config), 0644)
	c.Assert(err, gc.IsNil)
	s.b = bzr.New(c.MkDir())
	c.Assert(s.b.Init(), gc.IsNil)
}

func (s *BzrSuite) TestNewFindsRoot(c *gc.C) {
	err := os.Mkdir(s.b.Join("dir"), 0755)
	c.Assert(err, gc.IsNil)
	b := bzr.New(s.b.Join("dir"))
	c.Assert(b.Location(), gc.Equals, s.b.Location())
}

func (s *BzrSuite) TestJoin(c *gc.C) {
	path := bzr.New("lp:foo").Join("baz", "bar")
	c.Assert(path, gc.Equals, "lp:foo/baz/bar")
}

func (s *BzrSuite) TestErrorHandling(c *gc.C) {
	err := bzr.New("/non/existent/path").Init()
	c.Assert(err, gc.ErrorMatches, `(?s)error running "bzr init":.*does not exist.*`)
}

func (s *BzrSuite) TestInit(c *gc.C) {
	_, err := os.Stat(s.b.Join(".bzr"))
	c.Assert(err, gc.IsNil)
}

func (s *BzrSuite) TestRevisionIdOnEmpty(c *gc.C) {
	revid, err := s.b.RevisionId()
	c.Assert(err, gc.ErrorMatches, "branch has no content")
	c.Assert(revid, gc.Equals, "")
}

func (s *BzrSuite) TestCommit(c *gc.C) {
	f, err := os.Create(s.b.Join("myfile"))
	c.Assert(err, gc.IsNil)
	f.Close()
	err = s.b.Add("myfile")
	c.Assert(err, gc.IsNil)
	err = s.b.Commit("my log message")
	c.Assert(err, gc.IsNil)

	revid, err := s.b.RevisionId()
	c.Assert(err, gc.IsNil)

	cmd := exec.Command("bzr", "log", "--long", "--show-ids", "-v", s.b.Location())
	output, err := cmd.CombinedOutput()
	c.Assert(err, gc.IsNil)
	c.Assert(string(output), gc.Matches, "(?s).*revision-id: "+revid+"\n.*message:\n.*my log message\n.*added:\n.*myfile .*")
}

func (s *BzrSuite) TestPush(c *gc.C) {
	b1 := bzr.New(c.MkDir())
	b2 := bzr.New(c.MkDir())
	b3 := bzr.New(c.MkDir())
	c.Assert(b1.Init(), gc.IsNil)
	c.Assert(b2.Init(), gc.IsNil)
	c.Assert(b3.Init(), gc.IsNil)

	// Create and add b1/file to the branch.
	f, err := os.Create(b1.Join("file"))
	c.Assert(err, gc.IsNil)
	f.Close()
	err = b1.Add("file")
	c.Assert(err, gc.IsNil)
	err = b1.Commit("added file")
	c.Assert(err, gc.IsNil)

	// Push file to b2.
	err = b1.Push(&bzr.PushAttr{Location: b2.Location()})
	c.Assert(err, gc.IsNil)

	// Push location should be set to b2.
	location, err := b1.PushLocation()
	c.Assert(err, gc.IsNil)
	c.Assert(location, gc.Equals, b2.Location())

	// Now push it to b3.
	err = b1.Push(&bzr.PushAttr{Location: b3.Location()})
	c.Assert(err, gc.IsNil)

	// Push location is still set to b2.
	location, err = b1.PushLocation()
	c.Assert(err, gc.IsNil)
	c.Assert(location, gc.Equals, b2.Location())

	// Push it again, this time with the remember flag set.
	err = b1.Push(&bzr.PushAttr{Location: b3.Location(), Remember: true})
	c.Assert(err, gc.IsNil)

	// Now the push location has shifted to b3.
	location, err = b1.PushLocation()
	c.Assert(err, gc.IsNil)
	c.Assert(location, gc.Equals, b3.Location())

	// Both b2 and b3 should have the file.
	_, err = os.Stat(b2.Join("file"))
	c.Assert(err, gc.IsNil)
	_, err = os.Stat(b3.Join("file"))
	c.Assert(err, gc.IsNil)
}

func (s *BzrSuite) TestCheckClean(c *gc.C) {
	err := s.b.CheckClean()
	c.Assert(err, gc.IsNil)

	// Create and add b1/file to the branch.
	f, err := os.Create(s.b.Join("file"))
	c.Assert(err, gc.IsNil)
	f.Close()

	err = s.b.CheckClean()
	c.Assert(err, gc.ErrorMatches, `branch is not clean \(bzr status\)`)
}
<commit_msg>[r=jameinel] bzr: fix a test about paths<commit_after>// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package bzr_test

import (
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"testing"

	gc "launchpad.net/gocheck"

	"launchpad.net/juju-core/bzr"
	"launchpad.net/juju-core/testing/testbase"
)

func Test(t *testing.T) {
	gc.TestingT(t)
}

var _ = gc.Suite(&BzrSuite{})

type BzrSuite struct {
	testbase.LoggingSuite
	b *bzr.Branch
}

const bzr_config = `[DEFAULT]
email = testing <test@example.com>
`

func (s *BzrSuite) SetUpTest(c *gc.C) {
	s.LoggingSuite.SetUpTest(c)
	bzrdir := c.MkDir()
	s.PatchEnvironment("BZR_HOME", bzrdir)
	err := os.Mkdir(filepath.Join(bzrdir, ".bazaar"), 0755)
	c.Assert(err, gc.IsNil)
	err = ioutil.WriteFile(
		filepath.Join(bzrdir, ".bazaar", "bazaar.conf"),
		[]byte(bzr_config), 0644)
	c.Assert(err, gc.IsNil)
	s.b = bzr.New(c.MkDir())
	c.Assert(s.b.Init(), gc.IsNil)
}

func (s *BzrSuite) TestNewFindsRoot(c *gc.C) {
	err := os.Mkdir(s.b.Join("dir"), 0755)
	c.Assert(err, gc.IsNil)
	b := bzr.New(s.b.Join("dir"))
	// When bzr has to search for the root, it will expand any symlinks it
	// found along the way.
	path, err := filepath.EvalSymlinks(s.b.Location())
	c.Assert(err, gc.IsNil)
	c.Assert(b.Location(), gc.Equals, path)
}

func (s *BzrSuite) TestJoin(c *gc.C) {
	path := bzr.New("lp:foo").Join("baz", "bar")
	c.Assert(path, gc.Equals, "lp:foo/baz/bar")
}

func (s *BzrSuite) TestErrorHandling(c *gc.C) {
	err := bzr.New("/non/existent/path").Init()
	c.Assert(err, gc.ErrorMatches, `(?s)error running "bzr init":.*does not exist.*`)
}

func (s *BzrSuite) TestInit(c *gc.C) {
	_, err := os.Stat(s.b.Join(".bzr"))
	c.Assert(err, gc.IsNil)
}

func (s *BzrSuite) TestRevisionIdOnEmpty(c *gc.C) {
	revid, err := s.b.RevisionId()
	c.Assert(err, gc.ErrorMatches, "branch has no content")
	c.Assert(revid, gc.Equals, "")
}

func (s *BzrSuite) TestCommit(c *gc.C) {
	f, err := os.Create(s.b.Join("myfile"))
	c.Assert(err, gc.IsNil)
	f.Close()
	err = s.b.Add("myfile")
	c.Assert(err, gc.IsNil)
	err = s.b.Commit("my log message")
	c.Assert(err, gc.IsNil)

	revid, err := s.b.RevisionId()
	c.Assert(err, gc.IsNil)

	cmd := exec.Command("bzr", "log", "--long", "--show-ids", "-v", s.b.Location())
	output, err := cmd.CombinedOutput()
	c.Assert(err, gc.IsNil)
	c.Assert(string(output), gc.Matches, "(?s).*revision-id: "+revid+"\n.*message:\n.*my log message\n.*added:\n.*myfile .*")
}

func (s *BzrSuite) TestPush(c *gc.C) {
	b1 := bzr.New(c.MkDir())
	b2 := bzr.New(c.MkDir())
	b3 := bzr.New(c.MkDir())
	c.Assert(b1.Init(), gc.IsNil)
	c.Assert(b2.Init(), gc.IsNil)
	c.Assert(b3.Init(), gc.IsNil)

	// Create and add b1/file to the branch.
	f, err := os.Create(b1.Join("file"))
	c.Assert(err, gc.IsNil)
	f.Close()
	err = b1.Add("file")
	c.Assert(err, gc.IsNil)
	err = b1.Commit("added file")
	c.Assert(err, gc.IsNil)

	// Push file to b2.
	err = b1.Push(&bzr.PushAttr{Location: b2.Location()})
	c.Assert(err, gc.IsNil)

	// Push location should be set to b2.
	location, err := b1.PushLocation()
	c.Assert(err, gc.IsNil)
	c.Assert(location, gc.Equals, b2.Location())

	// Now push it to b3.
	err = b1.Push(&bzr.PushAttr{Location: b3.Location()})
	c.Assert(err, gc.IsNil)

	// Push location is still set to b2.
	location, err = b1.PushLocation()
	c.Assert(err, gc.IsNil)
	c.Assert(location, gc.Equals, b2.Location())

	// Push it again, this time with the remember flag set.
	err = b1.Push(&bzr.PushAttr{Location: b3.Location(), Remember: true})
	c.Assert(err, gc.IsNil)

	// Now the push location has shifted to b3.
	location, err = b1.PushLocation()
	c.Assert(err, gc.IsNil)
	c.Assert(location, gc.Equals, b3.Location())

	// Both b2 and b3 should have the file.
	_, err = os.Stat(b2.Join("file"))
	c.Assert(err, gc.IsNil)
	_, err = os.Stat(b3.Join("file"))
	c.Assert(err, gc.IsNil)
}

func (s *BzrSuite) TestCheckClean(c *gc.C) {
	err := s.b.CheckClean()
	c.Assert(err, gc.IsNil)

	// Create and add b1/file to the branch.
	f, err := os.Create(s.b.Join("file"))
	c.Assert(err, gc.IsNil)
	f.Close()

	err = s.b.CheckClean()
	c.Assert(err, gc.ErrorMatches, `branch is not clean \(bzr status\)`)
}
<|endoftext|>


<commit_before>package contract

import (
	"encoding/json"
	"io/ioutil"
)

type Response struct {
	Code    int32  `json:"code"`
	Message string `json:"message"`
	Data    string `json:"data"`
}

func (r Response) Encode() []byte {
	data, err := json.Marshal(r)
	if err != nil {
		panic(err)
	}

	return data
}

func (r Response) String() string {
	data := r.Encode()
	return string(data)
}

/*
type Contract struct {
	URL  string   `json:"url"`
	Get  Response `json:"get"`
	Post Response `json:"post"`
}
*/

type Contract struct {
	URL  string   `json:"url"`
	Get  Response `json:"get"`
	Post string   `json:"post"`
}

func NewContract(file string) *Contract {
	data, err := ioutil.ReadFile(file)
	if err != nil {
		panic(err)
	}

	c := new(Contract)
	err = json.Unmarshal([]byte(data), c)
	if err != nil {
		panic(err)
	}

	return c
}
<commit_msg>change contract to slice<commit_after>package contract

import (
	"encoding/json"
	"io/ioutil"
)

type Response struct {
	Code    int32  `json:"code"`
	Message string `json:"message"`
	Data    string `json:"data"`
}

func (r Response) Encode() []byte {
	data, err := json.Marshal(r)
	if err != nil {
		panic(err)
	}

	return data
}

func (r Response) String() string {
	data := r.Encode()
	return string(data)
}

/*
type Contract struct {
	URL  string   `json:"url"`
	Get  Response `json:"get"`
	Post Response `json:"post"`
}
*/

type Contract struct {
	URL  string   `json:"url"`
	Get  Response `json:"get"`
	Post string   `json:"post"`
}

type ContractList struct {
	Contracts []Contract `json:"contracts"`
}

func NewContract(file string) *ContractList {
	data, err := ioutil.ReadFile(file)
	if err != nil {
		panic(err)
	}

	c := new(ContractList)
	c.Contracts = make([]Contract, 0)
	err = json.Unmarshal([]byte(data), c)
	if err != nil {
		panic(err)
	}

	return c
}
<|endoftext|>


<commit_before>package goselenium

import "encoding/json"

// Browser defines a supported selenium enabled browser.
type Browser interface {
	BrowserName() string
}

// Browser represents a browser to run within Selenium.
type browser struct {
	browserName string
}

// BrowserName returns the browser name assigned to the current browser object.
func (b browser) BrowserName() string {
	return b.browserName
}

// FirefoxBrowser returns a Firefox browser object.
func FirefoxBrowser() Browser {
	return browser{"firefox"}
}

// ChromeBrowser returns a Chrome browser object.
func ChromeBrowser() Browser {
	return browser{"chrome"}
}

// AndroidBrowser returns an Android browser object.
func AndroidBrowser() Browser {
	return browser{"android"}
}

// HTMLUnitBrowser returns a HTMLUnit browser object.
func HTMLUnitBrowser() Browser {
	return browser{"htmlunit"}
}

// InternetExplorerBrowser returns an IE browser object.
func InternetExplorerBrowser() Browser {
	return browser{"internetexplorer"}
}

// IPhoneBrowser returns an IPhone browser object.
func IPhoneBrowser() Browser {
	return browser{"iphone"}
}

// IPadBrowser returns an IPad browser object.
func IPadBrowser() Browser {
	return browser{"ipad"}
}

// OperaBrowser returns an Opera browser object.
func OperaBrowser() Browser {
	return browser{"opera"}
}

// SafariBrowser returns a Safari browser object.
func SafariBrowser() Browser {
	return browser{"safari"}
}

// Capabilities represents the capabilities defined in the W3C specification.
// The main capability is the browser, which can be set by calling one of the
// \wBrowser\(\) methods.
type Capabilities struct {
	browser Browser
}

// Browser yields the browser capability assigned to the current Capabilities
// object..
func (c *Capabilities) Browser() Browser {
	if c.browser != nil {
		return c.browser
	}

	return browser{}
}

// SetBrowser sets the browser capability to be one of the allowed browsers.
func (c *Capabilities) SetBrowser(b Browser) {
	c.browser = b
}

func (c *Capabilities) toJSON() (string, error) {
	capabilities := map[string]map[string]interface{}{
		"desiredCapabilities": map[string]interface{}{
			"browserName": c.browser.BrowserName(),
		},
	}

	capabilitiesJSON, err := json.Marshal(capabilities)
	if err != nil {
		return "", err
	}

	return string(capabilitiesJSON), nil
}
<commit_msg>One more report card fix<commit_after>package goselenium

import "encoding/json"

// Browser defines a supported selenium enabled browser.
type Browser interface {
	BrowserName() string
}

// Browser represents a browser to run within Selenium.
type browser struct {
	browserName string
}

// BrowserName returns the browser name assigned to the current browser object.
func (b browser) BrowserName() string {
	return b.browserName
}

// FirefoxBrowser returns a Firefox browser object.
func FirefoxBrowser() Browser {
	return browser{"firefox"}
}

// ChromeBrowser returns a Chrome browser object.
func ChromeBrowser() Browser {
	return browser{"chrome"}
}

// AndroidBrowser returns an Android browser object.
func AndroidBrowser() Browser {
	return browser{"android"}
}

// HTMLUnitBrowser returns a HTMLUnit browser object.
func HTMLUnitBrowser() Browser {
	return browser{"htmlunit"}
}

// InternetExplorerBrowser returns an IE browser object.
func InternetExplorerBrowser() Browser {
	return browser{"internetexplorer"}
}

// IPhoneBrowser returns an IPhone browser object.
func IPhoneBrowser() Browser {
	return browser{"iphone"}
}

// IPadBrowser returns an IPad browser object.
func IPadBrowser() Browser {
	return browser{"ipad"}
}

// OperaBrowser returns an Opera browser object.
func OperaBrowser() Browser {
	return browser{"opera"}
}

// SafariBrowser returns a Safari browser object.
func SafariBrowser() Browser {
	return browser{"safari"}
}

// Capabilities represents the capabilities defined in the W3C specification.
// The main capability is the browser, which can be set by calling one of the
// \wBrowser\(\) methods.
type Capabilities struct {
	browser Browser
}

// Browser yields the browser capability assigned to the current Capabilities
// object..
func (c *Capabilities) Browser() Browser {
	if c.browser != nil {
		return c.browser
	}

	return browser{}
}

// SetBrowser sets the browser capability to be one of the allowed browsers.
func (c *Capabilities) SetBrowser(b Browser) {
	c.browser = b
}

func (c *Capabilities) toJSON() (string, error) {
	capabilities := map[string]map[string]interface{}{
		"desiredCapabilities": {
			"browserName": c.browser.BrowserName(),
		},
	}

	capabilitiesJSON, err := json.Marshal(capabilities)
	if err != nil {
		return "", err
	}

	return string(capabilitiesJSON), nil
}
<|endoftext|>


<commit_before>// Copyright (c) 2016, Janoš Guljaš <janos@resenje.org>
// All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package httpCertificate provides a Service that is a HTTP client to
// an external certificate service that can respond to HTTP requests defined here.
package httpCertificate

import (
	"bytes"
	"encoding/json"
	"net/url"
	"strconv"
	"time"

	"resenje.org/httputils/client/api"

	"gopherpit.com/gopherpit/services/certificate"
)

// Service implements gopherpit.com/gopherpit/services/certificates.Service interface.
type Service struct {
	Client *apiClient.Client
}

// NewService creates a new Service and injects certificate.ErrorRegistry
// in the API Client.
func NewService(c *apiClient.Client) *Service {
	if c == nil {
		c = &apiClient.Client{}
	}
	c.ErrorRegistry = certificate.ErrorRegistry
	return &Service{Client: c}
}

// Certificate retrieves an existing Certificate instance by making a HTTP GET request
// to {Client.Endpoint}/certificates/{fqdn}.
func (s Service) Certificate(fqdn string) (c *certificate.Certificate, err error) {
	err = s.Client.JSON("GET", "/certificates/"+fqdn, nil, nil, c)
	return
}

// ObtainCertificateRequest is a structure that is passed as JSON-encoded body
// to ObtainCertificate HTTP request.
type ObtainCertificateRequest struct {
	FQDN string `json:"fqdn"`
}

// ObtainCertificate obtains a new certificate from ACME provider by making a HTTP POST
// request to {Client.Endpoint}/certificates. Post body is a JSON-encoded
// ObtainCertificateRequest instance.
func (s Service) ObtainCertificate(fqdn string) (c *certificate.Certificate, err error) {
	body, err := json.Marshal(ObtainCertificateRequest{
		FQDN: fqdn,
	})
	if err != nil {
		return
	}
	err = s.Client.JSON("POST", "/certificates", nil, bytes.NewReader(body), c)
	return
}

// IsCertificateBeingObtainedResponse is expected structure of JSON-encoded response
// body for IsCertificateBeingObtained HTTP request.
type IsCertificateBeingObtainedResponse struct {
	Yes bool `json:"yes"`
}

// IsCertificateBeingObtained tests if certificate is being obtained currently
// by making a HTTP GET request to {Client.Endpoint}/certificates/{fqdn}/being-obtained.
// Expected response body is a JSON-encoded instance of IsCertificateBeingObtainedResponse.
func (s Service) IsCertificateBeingObtained(fqdn string) (yes bool, err error) {
	response := &IsCertificateBeingObtainedResponse{}
	err = s.Client.JSON("GET", "/certificates/"+fqdn+"/being-obtained", nil, nil, response)
	yes = response.Yes
	return
}

// UpdateCertificate changes the data of an existing Certificate by making a HTTP POST
// request to {Client.Endpoint}/certificates/{fqdn}. Post body is a JSON-encoded
// certificate.Options instance.
func (s Service) UpdateCertificate(fqdn string, o *certificate.Options) (c *certificate.Certificate, err error) {
	body, err := json.Marshal(o)
	if err != nil {
		return
	}
	err = s.Client.JSON("POST", "/certificates/"+fqdn, nil, bytes.NewReader(body), c)
	return
}

// DeleteCertificate deletes an existing Certificate by making a HTTP DELETE request
// to {Client.Endpoint}/certificates/{fqdn}.
func (s Service) DeleteCertificate(fqdn string) (c *certificate.Certificate, err error) {
	err = s.Client.JSON("DELETE", "/certificates/"+fqdn, nil, nil, c)
	return
}

// Certificates retrieves a paginated list of Certificate instances
// ordered by FQDN, by making a HTTP GET request to {Client.Endpoint}/certificates.
func (s Service) Certificates(start string, limit int) (page *certificate.CertificatesPage, err error) {
	query := url.Values{}
	if start != "" {
		query.Set("start", start)
	}
	if limit > 0 {
		query.Set("limit", strconv.Itoa(limit))
	}
	err = s.Client.JSON("GET", "/certificates", query, nil, page)
	return
}

// CertificatesInfoByExpiry retrieves a paginated list of Info instances
// ordered by expiration time by making a HTTP GET request to
// {Client.Endpoint}/certificates-info-by-expiry.
func (s Service) CertificatesInfoByExpiry(since time.Time, start string, limit int) (page *certificate.InfosPage, err error) {
	query := url.Values{}
	if start != "" {
		query.Set("start", start)
	}
	if limit > 0 {
		query.Set("limit", strconv.Itoa(limit))
	}
	if !since.IsZero() {
		query.Set("since", since.String())
	}
	err = s.Client.JSON("GET", "/certificates-info-by-expiry", query, nil, page)
	return
}

// ACMEUser returns ACME user with ACME authentication details by making a HTTP GET
// request to {Client.Endpoint}/acme/user.
func (s Service) ACMEUser() (u *certificate.ACMEUser, err error) {
	err = s.Client.JSON("GET", "/acme/user", nil, nil, u)
	return
}

// RegisterACMEUserRequest is a structure that is passed as JSON-encoded body
// to RegisterACMEUser HTTP request.
type RegisterACMEUserRequest struct {
	DirectoryURL string `json:"directory-url"`
	Email        string `json:"email"`
}

// RegisterACMEUser registers and saves ACME user authentication data by making a
// HTTP POST request to {Client.Endpoint}/acme/user. Post body is a JSON-encoded
// RegisterACMEUserRequest instance.
func (s Service) RegisterACMEUser(directoryURL, email string) (u *certificate.ACMEUser, err error) {
	body, err := json.Marshal(RegisterACMEUserRequest{
		DirectoryURL: directoryURL,
		Email:        email,
	})
	if err != nil {
		return
	}
	err = s.Client.JSON("POST", "/acme/user", nil, bytes.NewReader(body), u)
	return
}

// ACMEChallenge returns an instance of ACMEChallenge for a FQDN by making a
// HTTP GET request to {Client.Endpoint}/acme/challenges/{fqdn}.
func (s Service) ACMEChallenge(fqdn string) (c *certificate.ACMEChallenge, err error) {
	err = s.Client.JSON("GET", "/acme/challenges/"+fqdn, nil, nil, c)
	return
}

// UpdateACMEChallenge alters the fields of existing ACMEChallenge by making a
// HTTP POST request to {Client.Endpoint}/acme/challenges/{fqdn}. Post body is a JSON-encoded
// certificate.ACMEChallengeOptions instance.
func (s Service) UpdateACMEChallenge(fqdn string, o *certificate.ACMEChallengeOptions) (c *certificate.ACMEChallenge, err error) {
	body, err := json.Marshal(o)
	if err != nil {
		return
	}
	err = s.Client.JSON("POST", "/acme/challenges/"+fqdn, nil, bytes.NewReader(body), c)
	return
}

// DeleteACMEChallenge deletes an existing ACMEChallenge for a provided FQDN
// and returns it by making a HTTP DELETE request to {Client.Endpoint}/acme/challenges/{fqdn}.
func (s Service) DeleteACMEChallenge(fqdn string) (c *certificate.ACMEChallenge, err error) {
	err = s.Client.JSON("DELETE", "/acme/challenges/"+fqdn, nil, nil, c)
	return
}

// ACMEChallenges retrieves a paginated list of ACMEChallenge instances by making a
// HTTP GET request to {Client.Endpoint}/acme/challenges.
func (s Service) ACMEChallenges(start string, limit int) (page *certificate.ACMEChallengesPage, err error) {
	query := url.Values{}
	if start != "" {
		query.Set("start", start)
	}
	if limit > 0 {
		query.Set("limit", strconv.Itoa(limit))
	}
	err = s.Client.JSON("GET", "/acme/challenges", query, nil, page)
	return
}
<commit_msg>certificate http service: initialize return values<commit_after>// Copyright (c) 2016, Janoš Guljaš <janos@resenje.org>
// All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package httpCertificate provides a Service that is a HTTP client to
// an external certificate service that can respond to HTTP requests defined here.
package httpCertificate

import (
	"bytes"
	"encoding/json"
	"net/url"
	"strconv"
	"time"

	"resenje.org/httputils/client/api"

	"gopherpit.com/gopherpit/services/certificate"
)

// Service implements gopherpit.com/gopherpit/services/certificates.Service interface.
type Service struct {
	Client *apiClient.Client
}

// NewService creates a new Service and injects certificate.ErrorRegistry
// in the API Client.
func NewService(c *apiClient.Client) *Service {
	if c == nil {
		c = &apiClient.Client{}
	}
	c.ErrorRegistry = certificate.ErrorRegistry
	return &Service{Client: c}
}

// Certificate retrieves an existing Certificate instance by making a HTTP GET request
// to {Client.Endpoint}/certificates/{fqdn}.
func (s Service) Certificate(fqdn string) (c *certificate.Certificate, err error) {
	c = &certificate.Certificate{}
	err = s.Client.JSON("GET", "/certificates/"+fqdn, nil, nil, c)
	return
}

// ObtainCertificateRequest is a structure that is passed as JSON-encoded body
// to ObtainCertificate HTTP request.
type ObtainCertificateRequest struct {
	FQDN string `json:"fqdn"`
}

// ObtainCertificate obtains a new certificate from ACME provider by making a HTTP POST
// request to {Client.Endpoint}/certificates. Post body is a JSON-encoded
// ObtainCertificateRequest instance.
func (s Service) ObtainCertificate(fqdn string) (c *certificate.Certificate, err error) {
	body, err := json.Marshal(ObtainCertificateRequest{
		FQDN: fqdn,
	})
	if err != nil {
		return
	}
	c = &certificate.Certificate{}
	err = s.Client.JSON("POST", "/certificates", nil, bytes.NewReader(body), c)
	return
}

// IsCertificateBeingObtainedResponse is expected structure of JSON-encoded response
// body for IsCertificateBeingObtained HTTP request.
type IsCertificateBeingObtainedResponse struct {
	Yes bool `json:"yes"`
}

// IsCertificateBeingObtained tests if certificate is being obtained currently
// by making a HTTP GET request to {Client.Endpoint}/certificates/{fqdn}/being-obtained.
// Expected response body is a JSON-encoded instance of IsCertificateBeingObtainedResponse.
func (s Service) IsCertificateBeingObtained(fqdn string) (yes bool, err error) {
	response := &IsCertificateBeingObtainedResponse{}
	err = s.Client.JSON("GET", "/certificates/"+fqdn+"/being-obtained", nil, nil, response)
	yes = response.Yes
	return
}

// UpdateCertificate changes the data of an existing Certificate by making a HTTP POST
// request to {Client.Endpoint}/certificates/{fqdn}. Post body is a JSON-encoded
// certificate.Options instance.
func (s Service) UpdateCertificate(fqdn string, o *certificate.Options) (c *certificate.Certificate, err error) {
	body, err := json.Marshal(o)
	if err != nil {
		return
	}
	c = &certificate.Certificate{}
	err = s.Client.JSON("POST", "/certificates/"+fqdn, nil, bytes.NewReader(body), c)
	return
}

// DeleteCertificate deletes an existing Certificate by making a HTTP DELETE request
// to {Client.Endpoint}/certificates/{fqdn}.
func (s Service) DeleteCertificate(fqdn string) (c *certificate.Certificate, err error) {
	c = &certificate.Certificate{}
	err = s.Client.JSON("DELETE", "/certificates/"+fqdn, nil, nil, c)
	return
}

// Certificates retrieves a paginated list of Certificate instances
// ordered by FQDN, by making a HTTP GET request to {Client.Endpoint}/certificates.
func (s Service) Certificates(start string, limit int) (page *certificate.CertificatesPage, err error) {
	query := url.Values{}
	if start != "" {
		query.Set("start", start)
	}
	if limit > 0 {
		query.Set("limit", strconv.Itoa(limit))
	}
	page = &certificate.CertificatesPage{}
	err = s.Client.JSON("GET", "/certificates", query, nil, page)
	return
}

// CertificatesInfoByExpiry retrieves a paginated list of Info instances
// ordered by expiration time by making a HTTP GET request to
// {Client.Endpoint}/certificates-info-by-expiry.
func (s Service) CertificatesInfoByExpiry(since time.Time, start string, limit int) (page *certificate.InfosPage, err error) {
	query := url.Values{}
	if start != "" {
		query.Set("start", start)
	}
	if limit > 0 {
		query.Set("limit", strconv.Itoa(limit))
	}
	if !since.IsZero() {
		query.Set("since", since.String())
	}
	page = &certificate.InfosPage{}
	err = s.Client.JSON("GET", "/certificates-info-by-expiry", query, nil, page)
	return
}

// ACMEUser returns ACME user with ACME authentication details by making a HTTP GET
// request to {Client.Endpoint}/acme/user.
func (s Service) ACMEUser() (u *certificate.ACMEUser, err error) {
	err = s.Client.JSON("GET", "/acme/user", nil, nil, u)
	return
}

// RegisterACMEUserRequest is a structure that is passed as JSON-encoded body
// to RegisterACMEUser HTTP request.
type RegisterACMEUserRequest struct {
	DirectoryURL string `json:"directory-url"`
	Email        string `json:"email"`
}

// RegisterACMEUser registers and saves ACME user authentication data by making a
// HTTP POST request to {Client.Endpoint}/acme/user. Post body is a JSON-encoded
// RegisterACMEUserRequest instance.
func (s Service) RegisterACMEUser(directoryURL, email string) (u *certificate.ACMEUser, err error) {
	body, err := json.Marshal(RegisterACMEUserRequest{
		DirectoryURL: directoryURL,
		Email:        email,
	})
	if err != nil {
		return
	}
	u = &certificate.ACMEUser{}
	err = s.Client.JSON("POST", "/acme/user", nil, bytes.NewReader(body), u)
	return
}

// ACMEChallenge returns an instance of ACMEChallenge for a FQDN by making a
// HTTP GET request to {Client.Endpoint}/acme/challenges/{fqdn}.
func (s Service) ACMEChallenge(fqdn string) (c *certificate.ACMEChallenge, err error) {
	c = &certificate.ACMEChallenge{}
	err = s.Client.JSON("GET", "/acme/challenges/"+fqdn, nil, nil, c)
	return
}

// UpdateACMEChallenge alters the fields of existing ACMEChallenge by making a
// HTTP POST request to {Client.Endpoint}/acme/challenges/{fqdn}. Post body is a JSON-encoded
// certificate.ACMEChallengeOptions instance.
func (s Service) UpdateACMEChallenge(fqdn string, o *certificate.ACMEChallengeOptions) (c *certificate.ACMEChallenge, err error) {
	body, err := json.Marshal(o)
	if err != nil {
		return
	}
	c = &certificate.ACMEChallenge{}
	err = s.Client.JSON("POST", "/acme/challenges/"+fqdn, nil, bytes.NewReader(body), c)
	return
}

// DeleteACMEChallenge deletes an existing ACMEChallenge for a provided FQDN
// and returns it by making a HTTP DELETE request to {Client.Endpoint}/acme/challenges/{fqdn}.
func (s Service) DeleteACMEChallenge(fqdn string) (c *certificate.ACMEChallenge, err error) {
	c = &certificate.ACMEChallenge{}
	err = s.Client.JSON("DELETE", "/acme/challenges/"+fqdn, nil, nil, c)
	return
}

// ACMEChallenges retrieves a paginated list of ACMEChallenge instances by making a
// HTTP GET request to {Client.Endpoint}/acme/challenges.
func (s Service) ACMEChallenges(start string, limit int) (page *certificate.ACMEChallengesPage, err error) {
	query := url.Values{}
	if start != "" {
		query.Set("start", start)
	}
	if limit > 0 {
		query.Set("limit", strconv.Itoa(limit))
	}
	page = &certificate.ACMEChallengesPage{}
	err = s.Client.JSON("GET", "/acme/challenges", query, nil, page)
	return
}
<|endoftext|>


<commit_before>package syscallcompat

import (
	"bytes"
	"syscall"
	"testing"
)

func TestReadlinkat(t *testing.T) {
	for _, targetLen := range []int{100, 500, 4000} {
		target := string(bytes.Repeat([]byte("x"), targetLen))
		err := syscall.Symlink(target, tmpDir+"/readlinkat")
		if err != nil {
			if targetLen > 1000 {
				// Symlinks longer than 1024 (?) bytes are not supported on
				// MacOS and XFS
				t.Logf("skipping targetLen=%d: %v", targetLen, err)
				continue
			}
			t.Fatalf("targetLen=%d: %v", targetLen, err)
		}
		target2, err := Readlinkat(tmpDirFd, "readlinkat")
		if err != nil {
			t.Fatal(err)
		}
		if target != target2 {
			t.Errorf("target=%q != target2=%q", target, target2)
		}
		err = syscall.Unlink(tmpDir + "/readlinkat")
		if err != nil {
			t.Fatal(err)
		}
	}
}
<commit_msg>tests: add Fchmodat test<commit_after>package syscallcompat

import (
	"bytes"
	"os"
	"syscall"
	"testing"
)

func TestReadlinkat(t *testing.T) {
	for _, targetLen := range []int{100, 500, 4000} {
		target := string(bytes.Repeat([]byte("x"), targetLen))
		err := syscall.Symlink(target, tmpDir+"/readlinkat")
		if err != nil {
			if targetLen > 1000 {
				// Symlinks longer than 1024 (?) bytes are not supported on
				// MacOS and XFS
				t.Logf("skipping targetLen=%d: %v", targetLen, err)
				continue
			}
			t.Fatalf("targetLen=%d: %v", targetLen, err)
		}
		target2, err := Readlinkat(tmpDirFd, "readlinkat")
		if err != nil {
			t.Fatal(err)
		}
		if target != target2 {
			t.Errorf("target=%q != target2=%q", target, target2)
		}
		err = syscall.Unlink(tmpDir + "/readlinkat")
		if err != nil {
			t.Fatal(err)
		}
	}
}

func TestFchmodat(t *testing.T) {
	regular := "TestFchmodat_Regular"
	f, err := os.OpenFile(tmpDir+"/"+regular, os.O_CREATE|os.O_WRONLY, 0000)
	if err != nil {
		t.Fatal(err)
	}
	f.Close()
	symlink := "TestFchmodat_Symlink"
	err = syscall.Symlink(regular, tmpDir+"/"+symlink)
	if err != nil {
		t.Fatal(err)
	}
	dirfd, err := syscall.Open(tmpDir, syscall.O_RDONLY, 0)
	if err != nil {
		t.Fatal(err)
	}
	defer syscall.Close(dirfd)

	// Check that chmod on a regular file works ok
	err = Fchmodat(dirfd, regular, 0111, 0)
	if err != nil {
		t.Fatal(err)
	}
	var st syscall.Stat_t
	syscall.Lstat(tmpDir+"/"+regular, &st)
	st.Mode &= 0777
	if st.Mode != 0111 {
		t.Errorf("wrong mode: %#0o", st.Mode)
	}
	err = Fchmodat(dirfd, regular, 0000, 0)
	if err != nil {
		t.Error(err)
	}
	syscall.Lstat(tmpDir+"/"+regular, &st)
	st.Mode &= 0777
	if st.Mode != 0000 {
		t.Errorf("wrong mode: %#0o", st.Mode)
	}

	// Check what happens on a symlink
	err = Fchmodat(dirfd, symlink, 0333, 0)
	if err == nil {
		syscall.Lstat(tmpDir+"/"+symlink, &st)
		st.Mode &= 0777
		t.Errorf("chmod on symlink should have failed, but did not. New mode=%#0o", st.Mode)
	}
	syscall.Lstat(tmpDir+"/"+regular, &st)
	st.Mode &= 0777
	if st.Mode != 0000 {
		t.Errorf("chmod on symlink affected symlink target: New mode=%#0o", st.Mode)
	}
}
<|endoftext|>


<commit_before>// Copyright William Schwartz 2014. See the LICENSE file for more information.

// Package pigosat is a Go binding for the PicoSAT satisfiability solver.
//
// Designing your model is beyond the scope of this document, but Googling
// "satisfiability problem", "conjunctive normal form", and "DIMACS" are good
// places to start. Once you have your model, create a Pigosat instance p with
// pigosat.New, add the model to the instance with p.AddClauses, and solve with
// p.Solve.
package pigosat

// #cgo CFLAGS: -DNDEBUG -O3
// #cgo windows CFLAGS: -DNGETRUSAGE -DNALLSIGNALS
// #include "picosat.h" /* REMEMBER TO UPDATE PicosatVersion BELOW! */
import "C"
import (
	"fmt"
	"os"
	"runtime"
	"sync"
	"syscall"
	"time"
	"unsafe"
)

var Version = SemanticVersion{0, 4, 0, "", 0}

// PicosatVersion is the version string from the underlying Picosat library.
const PicosatVersion = "960"

// Argument/result types for Pigosat methods.

// Literals describe the variables in the formula. A positive value indicates
// the variable must be true; negative indicates it must be false. Variables
// should be indexed from one. The zero literal indicates the end of a clause.
type Literal int32
// Clauses are slices of literals ORed together. An optional zero ends a clause,
// even in the middle of a slice; [1, 0, 2] is the same as [1, 0] is the same as
// [1].
type Clause []Literal
// Formulas are slices of Clauses ANDed together.
type Formula []Clause
// Solutions are indexed by variable and return the truth value of the given
// variable. The zeroth element has no meaning and is always false.
type Solution []bool
// Statuses are returned by Pigosat.Solve to indicate success or failure.
type Status int

// Return values for Pigosat.Solve's status.
const (
	// PicoSAT cannot determine the satisfiability of the formula.
	Unknown Status = C.PICOSAT_UNKNOWN
	// The formula is satisfiable.
	Satisfiable Status = C.PICOSAT_SATISFIABLE
	// The formula cannot be satisfied.
	Unsatisfiable Status = C.PICOSAT_UNSATISFIABLE
)

// Struct Pigosat must be created with New and stores the state of the
// solver. It is safe for concurrent use.
//
// You must not use runtime.SetFinalizer with Pigosat objects. Attempting to
// call a method on an uninitialized Pigosat object panics.
type Pigosat struct {
	// Pointer to the underlying C struct.
	p    *C.PicoSAT
	lock *sync.RWMutex
}

// Struct Options contains optional settings for the Pigosat constructor. Zero
// values for each field indicate default behavior.
type Options struct {
	// Set PropagationLimit to a positive value to limit how long the solver
	// tries to find a solution.
	PropagationLimit uint64

	// Default (nil value) output file stdout
	OutputFile *os.File

	/* Set verbosity level. A verbosity level of 1 and above prints more and
	 * more detailed progress reports on the output file, set by
	 * 'picosat_set_output'. Verbose messages are prefixed with the string set
	 * by 'picosat_set_prefix'.
	 */
	Verbosity uint

	// Set the prefix used for printing verbose messages and statistics.
	// Default is "c ".
	Prefix string

	/* Measure all time spent in all calls in the solver.  By default only the
	 * time spent in 'picosat_sat' is measured.  Enabling this function may for
	 * instance triple the time needed to add large CNFs, since every call to
	 * 'picosat_add' will trigger a call to 'getrusage'.
	 */
	MeasureAllCalls bool
}

// cfdopen returns a C-level FILE*. mode should be as described in fdopen(3).
func cfdopen(file *os.File, mode string) (*C.FILE, error) {
	cmode := C.CString(mode)
	defer C.free(unsafe.Pointer(cmode))
	// FILE * fdopen(int fildes, const char *mode);
	cfile, err := C.fdopen(C.int(file.Fd()), cmode)
	if err != nil {
		return nil, err
	}
	if cfile == nil {
		return nil, syscall.EINVAL
	}
	return cfile, nil
}

// New returns a new Pigosat instance, ready to have literals added to it. The
// error return value need only be checked if the OutputFile option is non-nil.
func New(options *Options) (*Pigosat, error) {
	// PicoSAT * picosat_init (void);
	p := C.picosat_init()
	if options != nil {
		// void picosat_set_propagation_limit (PicoSAT *, unsigned long long limit);
		C.picosat_set_propagation_limit(p, C.ulonglong(options.PropagationLimit))
		if options.OutputFile != nil {
			cfile, err := cfdopen(options.OutputFile, "a")
			if err != nil {
				C.picosat_reset(p)
				return nil, &os.PathError{Op: "fdopen",
					Path: options.OutputFile.Name(), Err: err}
			}
			// void picosat_set_output (PicoSAT *, FILE *);
			C.picosat_set_output(p, cfile)
		}
		// void picosat_set_verbosity (PicoSAT *, int new_verbosity_level);
		C.picosat_set_verbosity(p, C.int(options.Verbosity))
		if options.Prefix != "" {
			// void picosat_set_prefix (PicoSAT *, const char *);
			prefix := C.CString(options.Prefix)
			defer C.free(unsafe.Pointer(prefix))
			C.picosat_set_prefix(p, prefix)
		}
		if options.MeasureAllCalls {
			// void picosat_measure_all_calls (PicoSAT *);
			C.picosat_measure_all_calls(p)
		}
	}
	pgo := &Pigosat{p: p, lock: new(sync.RWMutex)}
	runtime.SetFinalizer(pgo, (*Pigosat).delete)
	return pgo, nil
}

// delete frees memory associated with p's PicoSAT object. It only needs to be
// called from the runtime.SetFinalizer set in New.
func (p *Pigosat) delete() {
	// For some reason, SetFinalizer needs delete to be idempotent/reentrant.
	// That said, since finalizers are only run when there are no more
	// references to the object, there doesn't seem to be any point in locking.
	if p.p == nil {
		return
	}
	// void picosat_reset (PicoSAT *);
	C.picosat_reset(p.p)
	p.p = nil
}

// ready readies a Pigosat object for use in a public method. It obtains the
// appropriate lock and returns the appropriate unlocking method, so it can be
// used like
//     defer p.ready(readonly)()
// where readonly should be true if the method does not write to p and must be
// false if the method does write to p. If p is uninitialized or deleted,
// ready panics.
func (p *Pigosat) ready(readonly bool) (unlock func()) {
	if readonly {
		p.lock.RLock()
		unlock = p.lock.RUnlock
	} else {
		p.lock.Lock()
		unlock = p.lock.Unlock
	}
	if p.p == nil {
		defer unlock()
		panic("Attempted to use a deleted Pigosat object")
	}
	return
}

// Variables returns the number of variables in the formula: The m in the DIMACS
// header "p cnf <m> n".
func (p *Pigosat) Variables() int {
	defer p.ready(true)()
	// int picosat_variables (PicoSAT *);
	return int(C.picosat_variables(p.p))
}

// AddedOriginalClauses returns the number of clauses in the formula: The n in
// the DIMACS header "p cnf m <n>".
func (p *Pigosat) AddedOriginalClauses() int {
	defer p.ready(true)()
	// int picosat_added_original_clauses (PicoSAT *);
	return int(C.picosat_added_original_clauses(p.p))
}

// Seconds returns the time spent in the PicoSAT library.
func (p *Pigosat) Seconds() time.Duration {
	defer p.ready(true)()
	// double picosat_seconds (PicoSAT *);
	return time.Duration(float64(C.picosat_seconds(p.p)) * float64(time.Second))
}

// AddClauses adds a slice of clauses, each of which are a slice of literals.
// Each clause is a list of integers called literals. The absolute value of the literal i is
// the subscript for some variable x_i. If the literal is positive, x_i must end
// up being true when the formula is solved. If the literal is negative, it must
// end up false. Each clause ORs the literals together. All the clauses are
// ANDed together. An optional zero ends a clause, even in the middle of a
// slice; [1, 0, 2] is the same as [1, 0] is the same as [1].
func (p *Pigosat) AddClauses(clauses Formula) {
	defer p.ready(false)()
	var count int
	for _, clause := range clauses {
		count = len(clause)
		if count == 0 {
			continue
		}
		if clause[count-1] != 0 { // 0 tells PicoSAT where to stop reading array
			clause = append(clause, 0)
		}
		// int picosat_add_lits (PicoSAT *, int * lits);
		C.picosat_add_lits(p.p, (*C.int)(&clause[0]))
	}
}

// Print appends the CNF in DIMACS format to the given file.
func (p *Pigosat) Print(file *os.File) error {
	defer p.ready(true)()
	cfile, err := cfdopen(file, "a")
	if err != nil {
		return err
	}
	// void picosat_print (PicoSAT *, FILE *);
	_, err = C.picosat_print(p.p, cfile)
	return err
}

// blocksol adds the inverse of the solution to the clauses.
// This private method does not acquire the lock or check if p is nil.
func (p *Pigosat) blocksol(sol Solution) {
	n := C.picosat_variables(p.p)
	clause := make([]C.int, n+1)
	for i := C.int(1); i <= n; i++ {
		if sol[i] {
			clause[i-1] = -i
		} else {
			clause[i-1] = i
		}
	}
	// int picosat_add_lits (PicoSAT *, int * lits);
	C.picosat_add_lits(p.p, &clause[0])
}

// Solve the formula and return the status of the solution: one of the constants
// Unsatisfiable, Satisfiable, or Unknown. If satisfiable, return a slice
// indexed by the variables in the formula (so the first element is always
// false). Solve can be used like an iterator, yielding a new solution until
// there are no more feasible solutions:
//    for status, solution := p.Solve(); status == Satisfiable; status, solution = p.Solve() {
//        // Do stuff with status, solution
//    }
func (p *Pigosat) Solve() (status Status, solution Solution) {
	defer p.ready(false)()
	// int picosat_sat (PicoSAT *, int decision_limit);
	status = Status(C.picosat_sat(p.p, -1))
	if status == Unsatisfiable || status == Unknown {
		return
	} else if status != Satisfiable {
		panic(fmt.Errorf("Unknown sat status: %d", status))
	}
	n := int(C.picosat_variables(p.p)) // Calling Pigosat.Variables deadlocks
	solution = make(Solution, n+1)
	for i := 1; i <= n; i++ {
		// int picosat_deref (PicoSAT *, int lit);
		if val := C.picosat_deref(p.p, C.int(i)); val > 0 {
			solution[i] = true
		} else if val == 0 {
			panic(fmt.Errorf("Variable %d was assigned value 0", i))
		}
	}
	p.blocksol(solution)
	return
}

// Res returns Solve's last status, or Unknown if Solve hasn't yet been called.
func (p *Pigosat) Res() (status Status) {
	defer p.ready(true)()
	// int picosat_res (PicoSAT *);
	return Status(C.picosat_res(p.p))
}

// BlockSolution adds a clause to the formula ruling out a given solution. It is
// a no-op if p is nil and returns an error if the solution is the wrong
// length. There is no need to call BlockSolution after calling Pigosat.Solve,
// which calls it automatically for every Satisfiable solution.
func (p *Pigosat) BlockSolution(solution Solution) error {
	defer p.ready(false)()
	if n := int(C.picosat_variables(p.p)); len(solution) != n+1 {
		return fmt.Errorf("solution length %d, but have %d variables",
			len(solution), n)
	}
	p.blocksol(solution)
	return nil
}
<commit_msg>White space and go fmt<commit_after>// Copyright William Schwartz 2014. See the LICENSE file for more information.

// Package pigosat is a Go binding for the PicoSAT satisfiability solver.
//
// Designing your model is beyond the scope of this document, but Googling
// "satisfiability problem", "conjunctive normal form", and "DIMACS" are good
// places to start. Once you have your model, create a Pigosat instance p with
// pigosat.New, add the model to the instance with p.AddClauses, and solve with
// p.Solve.
package pigosat

// #cgo CFLAGS: -DNDEBUG -O3
// #cgo windows CFLAGS: -DNGETRUSAGE -DNALLSIGNALS
// #include "picosat.h" /* REMEMBER TO UPDATE PicosatVersion BELOW! */
import "C"
import (
	"fmt"
	"os"
	"runtime"
	"sync"
	"syscall"
	"time"
	"unsafe"
)

var Version = SemanticVersion{0, 4, 0, "", 0}

// PicosatVersion is the version string from the underlying Picosat library.
const PicosatVersion = "960"

// Argument/result types for Pigosat methods.

// Literals describe the variables in the formula. A positive value indicates
// the variable must be true; negative indicates it must be false. Variables
// should be indexed from one. The zero literal indicates the end of a clause.
type Literal int32

// Clauses are slices of literals ORed together. An optional zero ends a clause,
// even in the middle of a slice; [1, 0, 2] is the same as [1, 0] is the same as
// [1].
type Clause []Literal

// Formulas are slices of Clauses ANDed together.
type Formula []Clause

// Solutions are indexed by variable and return the truth value of the given
// variable. The zeroth element has no meaning and is always false.
type Solution []bool

// Statuses are returned by Pigosat.Solve to indicate success or failure.
type Status int

// Return values for Pigosat.Solve's status.
const (
	// PicoSAT cannot determine the satisfiability of the formula.
	Unknown Status = C.PICOSAT_UNKNOWN
	// The formula is satisfiable.
	Satisfiable Status = C.PICOSAT_SATISFIABLE
	// The formula cannot be satisfied.
	Unsatisfiable Status = C.PICOSAT_UNSATISFIABLE
)

// Struct Pigosat must be created with New and stores the state of the
// solver. It is safe for concurrent use.
//
// You must not use runtime.SetFinalizer with Pigosat objects. Attempting to
// call a method on an uninitialized Pigosat object panics.
type Pigosat struct {
	// Pointer to the underlying C struct.
	p    *C.PicoSAT
	lock *sync.RWMutex
}

// Struct Options contains optional settings for the Pigosat constructor. Zero
// values for each field indicate default behavior.
type Options struct {
	// Set PropagationLimit to a positive value to limit how long the solver
	// tries to find a solution.
	PropagationLimit uint64

	// Default (nil value) output file stdout
	OutputFile *os.File

	/* Set verbosity level. A verbosity level of 1 and above prints more and
	 * more detailed progress reports on the output file, set by
	 * 'picosat_set_output'. Verbose messages are prefixed with the string set
	 * by 'picosat_set_prefix'.
	 */
	Verbosity uint

	// Set the prefix used for printing verbose messages and statistics.
	// Default is "c ".
	Prefix string

	/* Measure all time spent in all calls in the solver.  By default only the
	 * time spent in 'picosat_sat' is measured.  Enabling this function may for
	 * instance triple the time needed to add large CNFs, since every call to
	 * 'picosat_add' will trigger a call to 'getrusage'.
	 */
	MeasureAllCalls bool
}

// cfdopen returns a C-level FILE*. mode should be as described in fdopen(3).
func cfdopen(file *os.File, mode string) (*C.FILE, error) {
	cmode := C.CString(mode)
	defer C.free(unsafe.Pointer(cmode))
	// FILE * fdopen(int fildes, const char *mode);
	cfile, err := C.fdopen(C.int(file.Fd()), cmode)
	if err != nil {
		return nil, err
	}
	if cfile == nil {
		return nil, syscall.EINVAL
	}
	return cfile, nil
}

// New returns a new Pigosat instance, ready to have literals added to it. The
// error return value need only be checked if the OutputFile option is non-nil.
func New(options *Options) (*Pigosat, error) {
	// PicoSAT * picosat_init (void);
	p := C.picosat_init()
	if options != nil {
		// void picosat_set_propagation_limit (PicoSAT *, unsigned long long limit);
		C.picosat_set_propagation_limit(p, C.ulonglong(options.PropagationLimit))
		if options.OutputFile != nil {
			cfile, err := cfdopen(options.OutputFile, "a")
			if err != nil {
				C.picosat_reset(p)
				return nil, &os.PathError{Op: "fdopen",
					Path: options.OutputFile.Name(), Err: err}
			}
			// void picosat_set_output (PicoSAT *, FILE *);
			C.picosat_set_output(p, cfile)
		}
		// void picosat_set_verbosity (PicoSAT *, int new_verbosity_level);
		C.picosat_set_verbosity(p, C.int(options.Verbosity))
		if options.Prefix != "" {
			// void picosat_set_prefix (PicoSAT *, const char *);
			prefix := C.CString(options.Prefix)
			defer C.free(unsafe.Pointer(prefix))
			C.picosat_set_prefix(p, prefix)
		}
		if options.MeasureAllCalls {
			// void picosat_measure_all_calls (PicoSAT *);
			C.picosat_measure_all_calls(p)
		}
	}
	pgo := &Pigosat{p: p, lock: new(sync.RWMutex)}
	runtime.SetFinalizer(pgo, (*Pigosat).delete)
	return pgo, nil
}

// delete frees memory associated with p's PicoSAT object. It only needs to be
// called from the runtime.SetFinalizer set in New.
func (p *Pigosat) delete() {
	// For some reason, SetFinalizer needs delete to be idempotent/reentrant.
	// That said, since finalizers are only run when there are no more
	// references to the object, there doesn't seem to be any point in locking.
	if p.p == nil {
		return
	}
	// void picosat_reset (PicoSAT *);
	C.picosat_reset(p.p)
	p.p = nil
}

// ready readies a Pigosat object for use in a public method. It obtains the
// appropriate lock and returns the appropriate unlocking method, so it can be
// used like
//     defer p.ready(readonly)()
// where readonly should be true if the method does not write to p and must be
// false if the method does write to p. If p is uninitialized or deleted,
// ready panics.
func (p *Pigosat) ready(readonly bool) (unlock func()) {
	if readonly {
		p.lock.RLock()
		unlock = p.lock.RUnlock
	} else {
		p.lock.Lock()
		unlock = p.lock.Unlock
	}
	if p.p == nil {
		defer unlock()
		panic("Attempted to use a deleted Pigosat object")
	}
	return
}

// Variables returns the number of variables in the formula: The m in the DIMACS
// header "p cnf <m> n".
func (p *Pigosat) Variables() int {
	defer p.ready(true)()
	// int picosat_variables (PicoSAT *);
	return int(C.picosat_variables(p.p))
}

// AddedOriginalClauses returns the number of clauses in the formula: The n in
// the DIMACS header "p cnf m <n>".
func (p *Pigosat) AddedOriginalClauses() int {
	defer p.ready(true)()
	// int picosat_added_original_clauses (PicoSAT *);
	return int(C.picosat_added_original_clauses(p.p))
}

// Seconds returns the time spent in the PicoSAT library.
func (p *Pigosat) Seconds() time.Duration {
	defer p.ready(true)()
	// double picosat_seconds (PicoSAT *);
	return time.Duration(float64(C.picosat_seconds(p.p)) * float64(time.Second))
}

// AddClauses adds a slice of clauses, each of which are a slice of literals.
// Each clause is a list of integers called literals. The absolute value of the
// literal i is the subscript for some variable x_i. If the literal is positive,
// x_i must end up being true when the formula is solved. If the literal is
// negative, it must end up false. Each clause ORs the literals together. All
// the clauses are ANDed together. An optional zero ends a clause, even in the
// middle of a slice; [1, 0, 2] is the same as [1, 0] is the same as [1].
func (p *Pigosat) AddClauses(clauses Formula) {
	defer p.ready(false)()
	var count int
	for _, clause := range clauses {
		count = len(clause)
		if count == 0 {
			continue
		}
		if clause[count-1] != 0 { // 0 tells PicoSAT where to stop reading array
			clause = append(clause, 0)
		}
		// int picosat_add_lits (PicoSAT *, int * lits);
		C.picosat_add_lits(p.p, (*C.int)(&clause[0]))
	}
}

// Print appends the CNF in DIMACS format to the given file.
func (p *Pigosat) Print(file *os.File) error {
	defer p.ready(true)()
	cfile, err := cfdopen(file, "a")
	if err != nil {
		return err
	}
	// void picosat_print (PicoSAT *, FILE *);
	_, err = C.picosat_print(p.p, cfile)
	return err
}

// blocksol adds the inverse of the solution to the clauses.
// This private method does not acquire the lock or check if p is nil.
func (p *Pigosat) blocksol(sol Solution) {
	n := C.picosat_variables(p.p)
	clause := make([]C.int, n+1)
	for i := C.int(1); i <= n; i++ {
		if sol[i] {
			clause[i-1] = -i
		} else {
			clause[i-1] = i
		}
	}
	// int picosat_add_lits (PicoSAT *, int * lits);
	C.picosat_add_lits(p.p, &clause[0])
}

// Solve the formula and return the status of the solution: one of the constants
// Unsatisfiable, Satisfiable, or Unknown. If satisfiable, return a slice
// indexed by the variables in the formula (so the first element is always
// false). Solve can be used like an iterator, yielding a new solution until
// there are no more feasible solutions:
//    for status, solution := p.Solve(); status == Satisfiable; status, solution = p.Solve() {
//        // Do stuff with status, solution
//    }
func (p *Pigosat) Solve() (status Status, solution Solution) {
	defer p.ready(false)()
	// int picosat_sat (PicoSAT *, int decision_limit);
	status = Status(C.picosat_sat(p.p, -1))
	if status == Unsatisfiable || status == Unknown {
		return
	} else if status != Satisfiable {
		panic(fmt.Errorf("Unknown sat status: %d", status))
	}
	n := int(C.picosat_variables(p.p)) // Calling Pigosat.Variables deadlocks
	solution = make(Solution, n+1)
	for i := 1; i <= n; i++ {
		// int picosat_deref (PicoSAT *, int lit);
		if val := C.picosat_deref(p.p, C.int(i)); val > 0 {
			solution[i] = true
		} else if val == 0 {
			panic(fmt.Errorf("Variable %d was assigned value 0", i))
		}
	}
	p.blocksol(solution)
	return
}

// Res returns Solve's last status, or Unknown if Solve hasn't yet been called.
func (p *Pigosat) Res() (status Status) {
	defer p.ready(true)()
	// int picosat_res (PicoSAT *);
	return Status(C.picosat_res(p.p))
}

// BlockSolution adds a clause to the formula ruling out a given solution. It is
// a no-op if p is nil and returns an error if the solution is the wrong
// length. There is no need to call BlockSolution after calling Pigosat.Solve,
// which calls it automatically for every Satisfiable solution.
func (p *Pigosat) BlockSolution(solution Solution) error {
	defer p.ready(false)()
	if n := int(C.picosat_variables(p.p)); len(solution) != n+1 {
		return fmt.Errorf("solution length %d, but have %d variables",
			len(solution), n)
	}
	p.blocksol(solution)
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"sync"

	"github.com/codegangsta/cli"
	"github.com/streadway/amqp"
)

func failOnError(err error, msg string) {
	if err != nil {
		log.Fatalf("%s: %s", msg, err)
		panic(fmt.Sprintf("%s: %s", msg, err))
	}
}

func main() {
	app := cli.NewApp()
	app.Name = "pipecat"
	app.Usage = "Connect unix pipes and message queues"

	globalFlags := []cli.Flag{
		cli.StringFlag{
			Name:   "amqpUri",
			Value:  "amqp://guest:guest@localhost:5672/",
			Usage:  "AMQP URI",
			EnvVar: "AMQP_URI",
		},
		cli.StringFlag{
			Name:   "fack",
			Value:  os.DevNull,
			Usage:  "ACK file",
			EnvVar: "FACK",
		},
	}

	app.Commands = []cli.Command{
		{
			Name:    "publish",
			Aliases: []string{"p"},
			Usage:   "Publish messages to queue",
			Flags:   globalFlags,
			Action: func(c *cli.Context) {
				queueName := c.Args().First()
				if queueName == "" {
					fmt.Println("Please provide name of the queue")
					os.Exit(1)
				}

				conn, err := amqp.Dial(c.String("amqpUri"))
				failOnError(err, "Failed to connect to AMPQ broker")
				defer conn.Close()

				channel, err := conn.Channel()
				failOnError(err, "Failed to open a channel")
				defer channel.Close()

				q, err := channel.QueueDeclare(
					queueName, // name
					true,      // durable
					false,     // delete when unused
					false,     // exclusive
					false,     // no-wait
					nil,       // arguments
				)
				failOnError(err, "Failed to declare a queue")

				stdack, err := os.OpenFile(c.String("fack"), os.O_APPEND, 0660)
				failOnError(err, "Could not open ack file")
				defer stdack.Close()

				scanner := bufio.NewScanner(os.Stdin)
				for scanner.Scan() {
					line := scanner.Text()
					err = channel.Publish(
						"",     // exchange
						q.Name, // routing key
						false,  // mandatory
						false,  // immediate
						amqp.Publishing{
							ContentType: "text/plain",
							Body:        []byte(line),
						})

					failOnError(err, "Failed to publish a message")
					fmt.Println(line)
					fmt.Fprintln(stdack, line)
				}
				if err := scanner.Err(); err != nil {
					fmt.Fprintln(os.Stderr, "Reading standard input:", err)
				}

			},
		},
		{
			Name:    "consume",
			Flags:   globalFlags,
			Aliases: []string{"c"},
			Usage:   "Consume messages from queue",
			Action: func(c *cli.Context) {
				queueName := c.Args().First()
				if queueName == "" {
					fmt.Println("Please provide name of the queue")
					os.Exit(1)
				}

				conn, err := amqp.Dial(c.String("amqpUri"))
				failOnError(err, "Failed to connect to AMPQ broker")
				defer conn.Close()

				channel, err := conn.Channel()
				failOnError(err, "Failed to open a channel")
				defer channel.Close()

				var mutex sync.Mutex
				unackedMessages := make([]amqp.Delivery, 100)

				msgs, err := channel.Consume(
					queueName, // queue
					"",        // consumer
					false,     // auto-ack
					false,     // exclusive
					false,     // no-local
					false,     // no-wait
					nil,       // args
				)
				failOnError(err, "Failed to register a consumer")

				stdack, err := os.OpenFile(c.String("fack"), os.O_APPEND, 0660)
				failOnError(err, "Could not open ack file")
				defer stdack.Close()
				forever := make(chan bool)

				go func() {

					scanner := bufio.NewScanner(os.Stdin)
					for scanner.Scan() {
						ackedLine := scanner.Text()

						mutex.Lock()
						for _, msg := range unackedMessages {
							unackedLine := fmt.Sprintf("%s", msg.Body)
							if unackedLine == ackedLine {
								fmt.Fprintln(stdack, ackedLine)
								msg.Ack(false)
							}
						}
						mutex.Unlock()
					}
					if err := scanner.Err(); err != nil {
						fmt.Fprintln(os.Stderr, "Reading standard input:", err)
					}

				}()

				go func() {
					for msg := range msgs {
						mutex.Lock()
						unackedMessages = append(unackedMessages, msg)
						mutex.Unlock()

						line := fmt.Sprintf("%s", msg.Body)
						fmt.Println(line)
					}
				}()
				<-forever

			},
		},
	}

	app.Run(os.Args)
}
<commit_msg>Basic refactoring<commit_after>package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"sync"

	"github.com/codegangsta/cli"
	"github.com/streadway/amqp"
)

func failOnError(err error, msg string) {
	if err != nil {
		log.Fatalf("%s: %s", msg, err)
		panic(fmt.Sprintf("%s: %s", msg, err))
	}
}

func prepare(amqpUri string, queueName string) (*amqp.Connection, *amqp.Channel) {
	conn, err := amqp.Dial(amqpUri)
	failOnError(err, "Failed to connect to AMPQ broker")

	channel, err := conn.Channel()
	failOnError(err, "Failed to open a channel")

	_, err = channel.QueueDeclare(
		queueName, // name
		true,      // durable
		false,     // delete when unused
		false,     // exclusive
		false,     // no-wait
		nil,       // arguments
	)
	failOnError(err, "Failed to declare queue")

	return conn, channel
}

func main() {
	app := cli.NewApp()
	app.Name = "pipecat"
	app.Usage = "Connect unix pipes and message queues"

	globalFlags := []cli.Flag{
		cli.StringFlag{
			Name:   "amqpUri",
			Value:  "amqp://guest:guest@localhost:5672/",
			Usage:  "AMQP URI",
			EnvVar: "AMQP_URI",
		},
		cli.StringFlag{
			Name:   "fack",
			Value:  os.DevNull,
			Usage:  "ACK file",
			EnvVar: "FACK",
		},
	}

	app.Commands = []cli.Command{
		{
			Name:    "publish",
			Aliases: []string{"p"},
			Usage:   "Publish messages to queue",
			Flags:   globalFlags,
			Action: func(c *cli.Context) {
				queueName := c.Args().First()
				if queueName == "" {
					fmt.Println("Please provide name of the queue")
					os.Exit(1)
				}

				conn, channel := prepare(c.String("amqpUri"), queueName)
				defer conn.Close()
				defer channel.Close()

				stdack, err := os.OpenFile(c.String("fack"), os.O_APPEND, 0660)
				failOnError(err, "Could not open ack file")
				defer stdack.Close()

				scanner := bufio.NewScanner(os.Stdin)
				for scanner.Scan() {
					line := scanner.Text()
					err = channel.Publish(
						"",        // exchange
						queueName, // routing key
						false,     // mandatory
						false,     // immediate
						amqp.Publishing{
							ContentType: "text/plain",
							Body:        []byte(line),
						})

					failOnError(err, "Failed to publish a message")
					fmt.Println(line)
					fmt.Fprintln(stdack, line)
				}
				if err := scanner.Err(); err != nil {
					fmt.Fprintln(os.Stderr, "Reading standard input:", err)
				}

			},
		},
		{
			Name:    "consume",
			Flags:   globalFlags,
			Aliases: []string{"c"},
			Usage:   "Consume messages from queue",
			Action: func(c *cli.Context) {
				queueName := c.Args().First()
				if queueName == "" {
					fmt.Println("Please provide name of the queue")
					os.Exit(1)
				}

				conn, channel := prepare(c.String("amqpUri"), queueName)
				defer conn.Close()
				defer channel.Close()

				var mutex sync.Mutex
				unackedMessages := make([]amqp.Delivery, 100)

				msgs, err := channel.Consume(
					queueName, // queue
					"",        // consumer
					false,     // auto-ack
					false,     // exclusive
					false,     // no-local
					false,     // no-wait
					nil,       // args
				)
				failOnError(err, "Failed to register a consumer")

				stdack, err := os.OpenFile(c.String("fack"), os.O_APPEND, 0660)
				failOnError(err, "Could not open ack file")
				defer stdack.Close()
				forever := make(chan bool)

				go func() {

					scanner := bufio.NewScanner(os.Stdin)
					for scanner.Scan() {
						ackedLine := scanner.Text()

						mutex.Lock()
						for _, msg := range unackedMessages {
							unackedLine := fmt.Sprintf("%s", msg.Body)
							if unackedLine == ackedLine {
								fmt.Fprintln(stdack, ackedLine)
								msg.Ack(false)
							}
						}
						mutex.Unlock()
					}
					if err := scanner.Err(); err != nil {
						fmt.Fprintln(os.Stderr, "Reading standard input:", err)
					}

				}()

				go func() {
					for msg := range msgs {
						mutex.Lock()
						unackedMessages = append(unackedMessages, msg)
						mutex.Unlock()

						line := fmt.Sprintf("%s", msg.Body)
						fmt.Println(line)
					}
				}()
				<-forever

			},
		},
	}

	app.Run(os.Args)
}
<|endoftext|>


<commit_before>package sdees

import "fmt"

func GoDeleteEntry(cache Cache) {
	var yesno string
	fmt.Printf("Are you sure you want to delete the entry %s in document %s? (y/n) ", DeleteEntry, CurrentDocument)
	fmt.Scanln(&yesno)
	if string(yesno) == "y" {
		deleteSuccess := false
		for _, branch := range cache.Branch {
			if branch.Branch == DeleteEntry {
				err := DeleteBranch(DeleteEntry)
				deleteSuccess = true
				if err == nil {
					fmt.Printf("Deleted entry %s\n", DeleteEntry)
				} else {
					fmt.Printf("Error deleting %s, does it exist?\n", DeleteEntry)
				}
			}
		}
		if !deleteSuccess {
			fmt.Printf("Error deleting %s, it does not exist\n", DeleteEntry)
		}
	} else {
		fmt.Printf("Did not delete %s\n", DeleteEntry)
	}
}

func GoDeleteDocument(cache Cache) error {
	var yesno string
	fmt.Printf("Are you sure you want to delete the document %s? (y/n) ", CurrentDocument)
	fmt.Scanln(&yesno)
	if string(yesno) == "y" {
		for _, branch := range cache.Branch {
			err := Delete(RemoteFolder, branch.Branch)
			if err != nil {
				logger.Debug(err.Error())
				return err
			}
			if err == nil {
				fmt.Printf("Deleted entry %s\n", branch.Branch)
			} else {
				fmt.Printf("Error deleting %s\n", branch.Branch)
			}
		}
	} else {
		fmt.Printf("Did not delete %s\n", CurrentDocument)
	}

	err := DeleteCache()
	if err != nil {
		logger.Debug(err.Error())
		return err
	}
	fmt.Print("Deleting on remote")
	err = Push(RemoteFolder)
	if err != nil {
		logger.Debug(err.Error())
		return err
	}
	fmt.Println("...done")
	return nil
}
<commit_msg>Updating delete<commit_after>package sdees

import (
	"errors"
	"fmt"
	"os"
	"os/exec"
)

func GoDeleteEntry(cache Cache) {
	var yesno string
	fmt.Printf("Are you sure you want to delete the entry %s in document %s? (y/n) ", DeleteEntry, CurrentDocument)
	fmt.Scanln(&yesno)
	if string(yesno) == "y" {
		deleteSuccess := false
		for _, branch := range cache.Branch {
			if branch.Branch == DeleteEntry {
				err := DeleteBranch(DeleteEntry)
				deleteSuccess = true
				if err == nil {
					fmt.Printf("Deleted entry %s\n", DeleteEntry)
				} else {
					fmt.Printf("Error deleting %s, does it exist?\n", DeleteEntry)
				}
			}
		}
		if !deleteSuccess {
			fmt.Printf("Error deleting %s, it does not exist\n", DeleteEntry)
		}
	} else {
		fmt.Printf("Did not delete %s\n", DeleteEntry)
	}
}

func GoDeleteDocument(cache Cache) error {
	var yesno string
	fmt.Printf("Are you sure you want to delete the document %s? (y/n) ", CurrentDocument)
	fmt.Scanln(&yesno)
	if string(yesno) == "y" {
		for _, branch := range cache.Branch {
			err := Delete(RemoteFolder, branch.Branch)
			if err != nil {
				logger.Debug(err.Error())
				return err
			}
			if err == nil {
				fmt.Printf("Deleted entry %s\n", branch.Branch)
			} else {
				fmt.Printf("Error deleting %s\n", branch.Branch)
			}
		}
	} else {
		fmt.Printf("Did not delete %s\n", CurrentDocument)
	}

	logger.Debug("Deleting cache")
	err := DeleteCache()
	if err != nil {
		logger.Debug(err.Error())
		return err
	}

	logger.Debug("Deleting master index file: %s", CurrentDocument)
	cwd, _ := os.Getwd()
	defer os.Chdir(cwd)
	os.Chdir(RemoteFolder)

	// Make sure we aren't on that branch
	cmd := exec.Command("git", "checkout", "master")
	_, err = cmd.Output()
	if err != nil {
		return errors.New("Problem switching to master")
	}

	document := CurrentDocument
	if Encrypt {
		document += ".gpg"
	}
	// Remove file from index
	logger.Debug("git rm -f %s",document)
	cmd = exec.Command("git", "rm", "-f", document)
	_, err = cmd.Output()
	if err != nil {
		return errors.New("Problem git rm -f ")
	}

	logger.Debug("git commit -m %s",document)
	cmd = exec.Command("git", "commit", "-m", "removed '"+document+"'")
	_, err = cmd.Output()
	if err != nil {
		return errors.New("Problem git commit -m ")
	}

	fmt.Print("Deleting on remote")
	err = Push(RemoteFolder)
	if err != nil {
		logger.Debug(err.Error())
		return err
	}
	fmt.Println("...done")
	return nil
}
<|endoftext|>