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

// An open source project for official documentation and blog website of beego app framework.
package main

import (
	"os"

	"github.com/astaxie/beego"
	"github.com/beego/i18n"

	"github.com/beego/beeweb/models"
	"github.com/beego/beeweb/routers"
)

const (
	APP_VER = "0.9.4.1229"
)

// We have to call a initialize function manully
// because we use `bee bale` to pack static resources
// and we cannot make sure that which init() execute first.
func initialize() {
	models.InitModels()

	// Set App version and log level.
	beego.AppName = models.Cfg.MustValue("beego", "app_name")
	beego.RunMode = models.Cfg.MustValue("beego", "run_mode")
	beego.HttpPort = models.Cfg.MustInt("beego", "http_port_"+beego.RunMode)

	routers.IsPro = beego.RunMode == "prod"
	if routers.IsPro {
		beego.SetLevel(beego.LevelInfo)
		os.Mkdir("./log", os.ModePerm)
		beego.BeeLogger.SetLogger("file", `{"filename": "log/log"}`)
	}

	routers.InitApp()
}

func main() {

	initialize()

	beego.Info(beego.AppName, APP_VER)

	beego.AddFilter("/docs/images/:all", "BeforeRouter", routers.DocsStatic)

	if !routers.IsPro {
		beego.SetStaticPath("/static_source", "static_source")
		beego.DirectoryIndex = true
	}

	beego.SetStaticPath("/products/images/", "products/images/")

	// Register routers.
	beego.Router("/", &routers.HomeRouter{})
	beego.Router("/community", &routers.CommunityRouter{})
	beego.Router("/quickstart", &routers.QuickStartRouter{})
	beego.Router("/products", &routers.ProductsRouter{})
	beego.Router("/team", &routers.PageRouter{})
	beego.Router("/about", &routers.AboutRouter{})
	beego.Router("/donate", &routers.DonateRouter{})
	beego.Router("/docs/", &routers.DocsRouter{})
	beego.Router("/docs/:all", &routers.DocsRouter{})
	beego.Router("/blog", &routers.BlogRouter{})
	beego.Router("/blog/:all", &routers.BlogRouter{})

	// Register template functions.
	beego.AddFuncMap("i18n", i18n.Tr)

	beego.Run()
}
<commit_msg>Bug fix<commit_after>// Copyright 2013 Beego Web authors
//
// Licensed under the Apache License, Version 2.0 (the "License"): you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.

// An open source project for official documentation and blog website of beego app framework.
package main

import (
	"os"

	"github.com/astaxie/beego"
	"github.com/beego/i18n"

	"github.com/beego/beeweb/models"
	"github.com/beego/beeweb/routers"
)

const (
	APP_VER = "0.9.4.0406"
)

// We have to call a initialize function manully
// because we use `bee bale` to pack static resources
// and we cannot make sure that which init() execute first.
func initialize() {
	models.InitModels()

	// Set App version and log level.
	beego.AppName = models.Cfg.MustValue("beego", "app_name")
	beego.RunMode = models.Cfg.MustValue("beego", "run_mode")
	beego.HttpPort = models.Cfg.MustInt("beego", "http_port_"+beego.RunMode)

	routers.IsPro = beego.RunMode == "prod"
	if routers.IsPro {
		beego.SetLevel(beego.LevelInfo)
		os.Mkdir("./log", os.ModePerm)
		beego.BeeLogger.SetLogger("file", `{"filename": "log/log"}`)
	}

	routers.InitApp()
}

func main() {

	initialize()

	beego.Info(beego.AppName, APP_VER)

	beego.AddFilter("/docs/images/:all", "BeforeRouter", routers.DocsStatic)

	if !routers.IsPro {
		beego.SetStaticPath("/static_source", "static_source")
		beego.DirectoryIndex = true
	}

	beego.SetStaticPath("/products/images", "products/images/")

	// Register routers.
	beego.Router("/", &routers.HomeRouter{})
	beego.Router("/community", &routers.CommunityRouter{})
	beego.Router("/quickstart", &routers.QuickStartRouter{})
	beego.Router("/products", &routers.ProductsRouter{})
	beego.Router("/team", &routers.PageRouter{})
	beego.Router("/about", &routers.AboutRouter{})
	beego.Router("/donate", &routers.DonateRouter{})
	beego.Router("/docs/", &routers.DocsRouter{})
	beego.Router("/docs/:all", &routers.DocsRouter{})
	beego.Router("/blog", &routers.BlogRouter{})
	beego.Router("/blog/:all", &routers.BlogRouter{})

	// Register template functions.
	beego.AddFuncMap("i18n", i18n.Tr)

	beego.Run()
}
<|endoftext|>


<commit_before>// Package aws provides core functionality for making requests to AWS services.
package aws

// SDKName is the name of this AWS SDK
const SDKName = "aws-sdk-go"

// SDKVersion is the version of this SDK
const SDKVersion = "0.9.3rc4"
<commit_msg>Tag release v0.9.4rc5<commit_after>// Package aws provides core functionality for making requests to AWS services.
package aws

// SDKName is the name of this AWS SDK
const SDKName = "aws-sdk-go"

// SDKVersion is the version of this SDK
const SDKVersion = "0.9.4rc5"
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"net/url"
	"os"
	"strings"
	"time"

	"github.com/drone/drone-template-lib/template"
	"github.com/nlopes/slack"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
)

type (
	// MessageOptions contains the slack message.
	MessageOptions struct {
		Icon             string
		Username         string
		Template         string
		ImageAttachments []string
	}

	// Repo information.
	Repo struct {
		FullName string
		Owner    string
		Name     string
		Link     string
	}

	// Build information.
	Build struct {
		Commit    string
		Branch    string
		Ref       string
		Link      string
		Message   string
		Author    string
		Email     string
		Number    int
		Status    string
		Event     string
		Deploy    string
		BuildLink string
	}

	// Config for the plugin.
	Config struct {
		Token   string
		Channel string
		Mapping string
		Success MessageOptions
		Failure MessageOptions
	}

	// Plugin values.
	Plugin struct {
		Repo      Repo
		Build     Build
		BuildLast Build
		Config    Config
		User      *slack.User
	}

	// searchFunc determines how to search for a slack user.
	searchFunc func(*slack.User, string) bool
)

// Exec executes the plugin.
func (p Plugin) Exec() error {
	// create the API
	api := slack.New(p.Config.Token)

	// verify the connection
	authResponse, err := api.AuthTest()

	if err != nil {
		return errors.Wrap(err, "failed to test auth")
	}

	logrus.WithFields(logrus.Fields{
		"team": authResponse.Team,
		"user": authResponse.User,
	}).Info("Successfully authenticated with Slack API")

	// get the user
	p.User, _ = p.findSlackUser(api)

	// get the associated @ string
	messageParams := p.createMessage()
	var userAt string

	if p.User != nil {
		userAt = fmt.Sprintf("@%s", p.User.Name)

		_, _, err := api.PostMessage(userAt, "", messageParams)

		if err == nil {
			logrus.WithFields(logrus.Fields{
				"username": p.User.Name,
			}).Info("Notified user")
		} else {
			logrus.WithFields(logrus.Fields{
				"username": p.User.Name,
			}).Error("Could not notify user")
		}
	} else {
		userAt = p.Build.Author
		logrus.WithFields(logrus.Fields{
			"author": userAt,
		}).Error("Could not find author")
	}

	if p.Config.Channel != "" {
		if !strings.HasPrefix(p.Config.Channel, "#") {
			p.Config.Channel = "#" + p.Config.Channel
		}
		_, _, err := api.PostMessage(p.Config.Channel, "", messageParams)

		if err == nil {
			logrus.WithFields(logrus.Fields{
				"channel": p.Config.Channel,
			}).Info("Channel notified")
		} else {
			logrus.WithFields(logrus.Fields{
				"channel": p.Config.Channel,
			}).Error("Unable to notify channel")
		}
	}

	return nil
}

// createMessage generates the message to post to Slack.
func (p Plugin) createMessage() slack.PostMessageParameters {
	var messageOptions MessageOptions
	var color string
	var messageTitle string

	// Determine if the build was a success
	if p.Build.Status == "success" {
		messageOptions = p.Config.Success
		color = "good"
		messageTitle = "Build succeeded"
	} else {
		messageOptions = p.Config.Failure
		color = "danger"
		messageTitle = "Build failed"
	}

	// setup the message
	messageParams := slack.PostMessageParameters{
		Username: messageOptions.Username,
	}

	if strings.HasPrefix(messageOptions.Icon, "http") {
		logrus.Info("Icon is a URL")
		messageParams.IconURL = messageOptions.Icon
	} else {
		logrus.Info("Icon is an emoji")
		messageParams.IconEmoji = messageOptions.Icon
	}

	messageText, err := template.Render(messageOptions.Template, &p)

	if err != nil {
		logrus.Error("Could not parse template")
	}

	// create the attachment
	attachment := slack.Attachment{
		Color:     color,
		Text:      messageText,
		Title:     messageTitle,
		TitleLink: p.Build.Link,
	}

	// Add image if any are provided
	imageCount := len(messageOptions.ImageAttachments)

	if imageCount > 0 {
		logrus.WithFields(logrus.Fields{
			"count": imageCount,
		}).Info("Choosing from images")
		rand.Seed(time.Now().UTC().UnixNano())
		attachment.ImageURL = messageOptions.ImageAttachments[rand.Intn(imageCount)]
	}

	messageParams.Attachments = []slack.Attachment{attachment}

	return messageParams
}

// findSlackUser uses the slack API to find the user who made the commit that
// is being built.
func (p Plugin) findSlackUser(api *slack.Client) (*slack.User, error) {
	// get the mapping
	mapping := userMapping(p.Config.Mapping)

	// determine the search function to use
	var search searchFunc
	var find string

	if val, ok := mapping[p.Build.Email]; ok {
		logrus.WithFields(logrus.Fields{
			"username": val,
		}).Info("Searching for user by name, using build.email as key")
		search = checkUsername
		find = val
	} else if val, ok := mapping[p.Build.Author]; ok {
		logrus.WithFields(logrus.Fields{
			"username": val,
		}).Info("Searching for user by name, using build.author as key")
		search = checkUsername
		find = val
	} else {
		logrus.WithFields(logrus.Fields{
			"email": p.Build.Email,
		}).Info("Searching for user by email")
		search = checkEmail
		find = p.Build.Email
	}

	if len(find) == 0 {
		return nil, errors.New("No user to search for")
	}

	// search for the user
	users, err := api.GetUsers()

	if err != nil {
		return nil, errors.Wrap(err, "failed to query users")
	}

	var blameUser *slack.User

	for _, user := range users {
		if search(&user, find) {
			logrus.WithFields(logrus.Fields{
				"username": user.Name,
				"email":    user.Profile.Email,
			}).Info("Found user")

			blameUser = &user
			break
		} else {
			logrus.WithFields(logrus.Fields{
				"username": user.Name,
				"email":    user.Profile.Email,
			}).Debug("User")
		}
	}

	return blameUser, nil
}

// userMapping gets the user mapping file.
func userMapping(value string) map[string]string {
	mapping := []byte(contents(value))

	// turn into a map
	values := map[string]string{}
	err := json.Unmarshal(mapping, &values)

	if err != nil {
		if len(mapping) != 0 {
			logrus.WithFields(logrus.Fields{
				"mapping": value,
				"error":   err,
			}).Error("Could not parse mapping")
		}

		values = make(map[string]string)
	}

	return values
}

// contents gets the value referenced either in a local filem, a URL or the
// string value itself.
func contents(s string) string {
	if _, err := os.Stat(s); err == nil {
		o, _ := ioutil.ReadFile(s)
		return string(o)
	}
	if _, err := url.Parse(s); err == nil {
		resp, err := http.Get(s)
		if err != nil {
			return s
		}
		defer resp.Body.Close()
		o, _ := ioutil.ReadAll(resp.Body)
		return string(o)
	}
	return s
}

// checkEmail sees if the email is used by the user.
func checkEmail(user *slack.User, email string) bool {
	return strings.EqualFold(user.Profile.Email, email)
}

// checkUsername sees if the username is the same as the user.
func checkUsername(user *slack.User, name string) bool {
	return user.Name == name
}
<commit_msg>This will use the display name to map users instead of the legacy username in slack (#40)<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"net/url"
	"os"
	"strings"
	"time"

	"github.com/drone/drone-template-lib/template"
	"github.com/nlopes/slack"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
)

type (
	// MessageOptions contains the slack message.
	MessageOptions struct {
		Icon             string
		Username         string
		Template         string
		ImageAttachments []string
	}

	// Repo information.
	Repo struct {
		FullName string
		Owner    string
		Name     string
		Link     string
	}

	// Build information.
	Build struct {
		Commit    string
		Branch    string
		Ref       string
		Link      string
		Message   string
		Author    string
		Email     string
		Number    int
		Status    string
		Event     string
		Deploy    string
		BuildLink string
	}

	// Config for the plugin.
	Config struct {
		Token   string
		Channel string
		Mapping string
		Success MessageOptions
		Failure MessageOptions
	}

	// Plugin values.
	Plugin struct {
		Repo      Repo
		Build     Build
		BuildLast Build
		Config    Config
		User      *slack.User
	}

	// searchFunc determines how to search for a slack user.
	searchFunc func(*slack.User, string) bool
)

// Exec executes the plugin.
func (p Plugin) Exec() error {
	// create the API
	api := slack.New(p.Config.Token)

	// verify the connection
	authResponse, err := api.AuthTest()

	if err != nil {
		return errors.Wrap(err, "failed to test auth")
	}

	logrus.WithFields(logrus.Fields{
		"team": authResponse.Team,
		"user": authResponse.User,
	}).Info("Successfully authenticated with Slack API")

	// get the user
	p.User, _ = p.findSlackUser(api)

	// get the associated @ string
	messageParams := p.createMessage()
	var userAt string

	if p.User != nil {
		userAt = fmt.Sprintf("@%s", p.User.Name)

		_, _, err := api.PostMessage(userAt, "", messageParams)

		if err == nil {
			logrus.WithFields(logrus.Fields{
				"username": p.User.Name,
			}).Info("Notified user")
		} else {
			logrus.WithFields(logrus.Fields{
				"username": p.User.Name,
			}).Error("Could not notify user")
		}
	} else {
		userAt = p.Build.Author
		logrus.WithFields(logrus.Fields{
			"author": userAt,
		}).Error("Could not find author")
	}

	if p.Config.Channel != "" {
		if !strings.HasPrefix(p.Config.Channel, "#") {
			p.Config.Channel = "#" + p.Config.Channel
		}
		_, _, err := api.PostMessage(p.Config.Channel, "", messageParams)

		if err == nil {
			logrus.WithFields(logrus.Fields{
				"channel": p.Config.Channel,
			}).Info("Channel notified")
		} else {
			logrus.WithFields(logrus.Fields{
				"channel": p.Config.Channel,
			}).Error("Unable to notify channel")
		}
	}

	return nil
}

// createMessage generates the message to post to Slack.
func (p Plugin) createMessage() slack.PostMessageParameters {
	var messageOptions MessageOptions
	var color string
	var messageTitle string

	// Determine if the build was a success
	if p.Build.Status == "success" {
		messageOptions = p.Config.Success
		color = "good"
		messageTitle = "Build succeeded"
	} else {
		messageOptions = p.Config.Failure
		color = "danger"
		messageTitle = "Build failed"
	}

	// setup the message
	messageParams := slack.PostMessageParameters{
		Username: messageOptions.Username,
	}

	if strings.HasPrefix(messageOptions.Icon, "http") {
		logrus.Info("Icon is a URL")
		messageParams.IconURL = messageOptions.Icon
	} else {
		logrus.Info("Icon is an emoji")
		messageParams.IconEmoji = messageOptions.Icon
	}

	messageText, err := template.Render(messageOptions.Template, &p)

	if err != nil {
		logrus.Error("Could not parse template")
	}

	// create the attachment
	attachment := slack.Attachment{
		Color:     color,
		Text:      messageText,
		Title:     messageTitle,
		TitleLink: p.Build.Link,
	}

	// Add image if any are provided
	imageCount := len(messageOptions.ImageAttachments)

	if imageCount > 0 {
		logrus.WithFields(logrus.Fields{
			"count": imageCount,
		}).Info("Choosing from images")
		rand.Seed(time.Now().UTC().UnixNano())
		attachment.ImageURL = messageOptions.ImageAttachments[rand.Intn(imageCount)]
	}

	messageParams.Attachments = []slack.Attachment{attachment}

	return messageParams
}

// findSlackUser uses the slack API to find the user who made the commit that
// is being built.
func (p Plugin) findSlackUser(api *slack.Client) (*slack.User, error) {
	// get the mapping
	mapping := userMapping(p.Config.Mapping)

	// determine the search function to use
	var search searchFunc
	var find string

	if val, ok := mapping[p.Build.Email]; ok {
		logrus.WithFields(logrus.Fields{
			"username": val,
		}).Info("Searching for user by name, using build.email as key")
		search = checkUsername
		find = val
	} else if val, ok := mapping[p.Build.Author]; ok {
		logrus.WithFields(logrus.Fields{
			"username": val,
		}).Info("Searching for user by name, using build.author as key")
		search = checkUsername
		find = val
	} else {
		logrus.WithFields(logrus.Fields{
			"email": p.Build.Email,
		}).Info("Searching for user by email")
		search = checkEmail
		find = p.Build.Email
	}

	if len(find) == 0 {
		return nil, errors.New("No user to search for")
	}

	// search for the user
	users, err := api.GetUsers()

	if err != nil {
		return nil, errors.Wrap(err, "failed to query users")
	}

	var blameUser *slack.User

	for _, user := range users {
		if search(&user, find) {
			logrus.WithFields(logrus.Fields{
				"username": user.Name,
				"email":    user.Profile.Email,
			}).Info("Found user")

			blameUser = &user
			break
		} else {
			logrus.WithFields(logrus.Fields{
				"username": user.Name,
				"email":    user.Profile.Email,
			}).Debug("User")
		}
	}

	return blameUser, nil
}

// userMapping gets the user mapping file.
func userMapping(value string) map[string]string {
	mapping := []byte(contents(value))

	// turn into a map
	values := map[string]string{}
	err := json.Unmarshal(mapping, &values)

	if err != nil {
		if len(mapping) != 0 {
			logrus.WithFields(logrus.Fields{
				"mapping": value,
				"error":   err,
			}).Error("Could not parse mapping")
		}

		values = make(map[string]string)
	}

	return values
}

// contents gets the value referenced either in a local filem, a URL or the
// string value itself.
func contents(s string) string {
	if _, err := os.Stat(s); err == nil {
		o, _ := ioutil.ReadFile(s)
		return string(o)
	}
	if _, err := url.Parse(s); err == nil {
		resp, err := http.Get(s)
		if err != nil {
			return s
		}
		defer resp.Body.Close()
		o, _ := ioutil.ReadAll(resp.Body)
		return string(o)
	}
	return s
}

// checkEmail sees if the email is used by the user.
func checkEmail(user *slack.User, email string) bool {
	return strings.EqualFold(user.Profile.Email, email)
}

// checkUsername sees if the username is the same as the user.
func checkUsername(user *slack.User, name string) bool {
	return user.Profile.DisplayName == name
}
<|endoftext|>


<commit_before>// Package aws provides core functionality for making requests to AWS services.
package aws

// SDKName is the name of this AWS SDK
const SDKName = "aws-sdk-go"

// SDKVersion is the version of this SDK
const SDKVersion = "0.6.8"
<commit_msg>Tag release v0.7.0<commit_after>// Package aws provides core functionality for making requests to AWS services.
package aws

// SDKName is the name of this AWS SDK
const SDKName = "aws-sdk-go"

// SDKVersion is the version of this SDK
const SDKVersion = "0.7.0"
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"net/http"
	"path/filepath"
	"regexp"

	dockerapi "github.com/docker/docker/api"
	dockerclient "github.com/docker/engine-api/client"
	"github.com/docker/go-plugins-helpers/authorization"
)

func newPlugin(dockerHost, certPath string, tlsVerify bool) (*novolume, error) {
	var transport *http.Transport
	if certPath != "" {
		tlsc := &tls.Config{}

		cert, err := tls.LoadX509KeyPair(filepath.Join(certPath, "cert.pem"), filepath.Join(certPath, "key.pem"))
		if err != nil {
			return nil, fmt.Errorf("Error loading x509 key pair: %s", err)
		}

		tlsc.Certificates = append(tlsc.Certificates, cert)
		tlsc.InsecureSkipVerify = !tlsVerify
		transport = &http.Transport{
			TLSClientConfig: tlsc,
		}
	}

	client, err := dockerclient.NewClient(dockerHost, dockerapi.DefaultVersion.String(), transport, nil)
	if err != nil {
		return nil, err
	}
	return &novolume{client: client}, nil
}

var (
	startRegExp = regexp.MustCompile(`/containers/(.*)/start`)
)

type novolume struct {
	client *dockerclient.Client
}

func (p *novolume) AuthZReq(req authorization.Request) authorization.Response {
	if req.RequestMethod == "POST" && startRegExp.MatchString(req.RequestURI) {
		// this is deprecated in docker, remove once hostConfig is dropped to
		// being available at start time
		if req.RequestBody != nil {
			type vfrom struct {
				VolumesFrom []string
			}
			vf := &vfrom{}
			if err := json.NewDecoder(bytes.NewReader(req.RequestBody)).Decode(vf); err != nil {
				return authorization.Response{Err: err.Error()}
			}
			if len(vf.VolumesFrom) > 0 {
				goto noallow
			}
		}
		res := startRegExp.FindStringSubmatch(req.RequestURI)
		if len(res) < 1 {
			return authorization.Response{Err: "unable to find container name"}
		}
		container, err := p.client.ContainerInspect(res[1])
		if err != nil {
			return authorization.Response{Err: err.Error()}
		}
		bindDests := []string{}
		for _, m := range container.Mounts {
			if m.Driver != "" {
				goto noallow
			}
			bindDests = append(bindDests, m.Destination)
		}
		image, _, err := p.client.ImageInspectWithRaw(container.Image, false)
		if err != nil {
			return authorization.Response{Err: err.Error()}
		}
		if len(bindDests) == 0 && len(image.Config.Volumes) > 0 {
			goto noallow
		}
		if len(image.Config.Volumes) > 0 {
			for _, bd := range bindDests {
				if _, ok := image.Config.Volumes[bd]; !ok {
					goto noallow
				}
			}
		}
		if len(container.HostConfig.VolumesFrom) > 0 {
			goto noallow
		}
		// TODO(runcom): FROM scratch ?!?!
	}
	return authorization.Response{Allow: true}

noallow:
	return authorization.Response{Msg: "volumes are not allowed"}
}

func (p *novolume) AuthZRes(req authorization.Request) authorization.Response {
	return authorization.Response{Allow: true}
}
<commit_msg>correctly escape the request URI<commit_after>package main

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"path/filepath"
	"regexp"

	dockerapi "github.com/docker/docker/api"
	dockerclient "github.com/docker/engine-api/client"
	"github.com/docker/go-plugins-helpers/authorization"
)

func newPlugin(dockerHost, certPath string, tlsVerify bool) (*novolume, error) {
	var transport *http.Transport
	if certPath != "" {
		tlsc := &tls.Config{}

		cert, err := tls.LoadX509KeyPair(filepath.Join(certPath, "cert.pem"), filepath.Join(certPath, "key.pem"))
		if err != nil {
			return nil, fmt.Errorf("Error loading x509 key pair: %s", err)
		}

		tlsc.Certificates = append(tlsc.Certificates, cert)
		tlsc.InsecureSkipVerify = !tlsVerify
		transport = &http.Transport{
			TLSClientConfig: tlsc,
		}
	}

	client, err := dockerclient.NewClient(dockerHost, dockerapi.DefaultVersion.String(), transport, nil)
	if err != nil {
		return nil, err
	}
	return &novolume{client: client}, nil
}

var (
	startRegExp = regexp.MustCompile(`/containers/(.*)/start`)
)

type novolume struct {
	client *dockerclient.Client
}

func (p *novolume) AuthZReq(req authorization.Request) authorization.Response {
	ruri := url.QueryEscape(req.RequestURI)
	if req.RequestMethod == "POST" && startRegExp.MatchString(ruri) {
		// this is deprecated in docker, remove once hostConfig is dropped to
		// being available at start time
		if req.RequestBody != nil {
			type vfrom struct {
				VolumesFrom []string
			}
			vf := &vfrom{}
			if err := json.NewDecoder(bytes.NewReader(req.RequestBody)).Decode(vf); err != nil {
				return authorization.Response{Err: err.Error()}
			}
			if len(vf.VolumesFrom) > 0 {
				goto noallow
			}
		}
		res := startRegExp.FindStringSubmatch(ruri)
		if len(res) < 1 {
			return authorization.Response{Err: "unable to find container name"}
		}
		container, err := p.client.ContainerInspect(res[1])
		if err != nil {
			return authorization.Response{Err: err.Error()}
		}
		bindDests := []string{}
		for _, m := range container.Mounts {
			if m.Driver != "" {
				goto noallow
			}
			bindDests = append(bindDests, m.Destination)
		}
		image, _, err := p.client.ImageInspectWithRaw(container.Image, false)
		if err != nil {
			return authorization.Response{Err: err.Error()}
		}
		if len(bindDests) == 0 && len(image.Config.Volumes) > 0 {
			goto noallow
		}
		if len(image.Config.Volumes) > 0 {
			for _, bd := range bindDests {
				if _, ok := image.Config.Volumes[bd]; !ok {
					goto noallow
				}
			}
		}
		if len(container.HostConfig.VolumesFrom) > 0 {
			goto noallow
		}
		// TODO(runcom): FROM scratch ?!?!
	}
	return authorization.Response{Allow: true}

noallow:
	return authorization.Response{Msg: "volumes are not allowed"}
}

func (p *novolume) AuthZRes(req authorization.Request) authorization.Response {
	return authorization.Response{Allow: true}
}
<|endoftext|>


<commit_before>package rpc

import (
	"encoding/json"
	"errors"
	"strconv"
	"strings"

	"github.com/go-steem/rpc/types"
)

type Config struct {
	SteemitBlockchainVersion string `json:"STEEMIT_BLOCKCHAIN_VERSION"`
	SteemitBlockInterval     uint   `json:"STEEMIT_BLOCK_INTERVAL"`
}

type DynamicGlobalProperties struct {
	Time                     *types.Time `json:"time"`
	TotalPow                 *types.Int  `json:"total_pow"`
	NumPowWitnesses          *types.Int  `json:"num_pow_witnesses"`
	ConfidentialSupply       string      `json:"confidential_supply"`
	TotalVestingShares       string      `json:"total_vesting_shares"`
	CurrentReserveRatio      *types.Int  `json:"current_reserve_ratio"`
	Id                       *types.ID   `json:"id"`
	CurrentSupply            string      `json:"current_supply"`
	MaximumBlockSize         *types.Int  `json:"maximum_block_size"`
	RecentSlotsFilled        string      `json:"recent_slots_filled"`
	CurrentWitness           string      `json:"current_witness"`
	TotalRewardShares2       string      `json:"total_reward_shares2"`
	AverageBlockSize         *types.Int  `json:"average_block_size"`
	CurrentAslot             *types.Int  `json:"current_aslot"`
	LastIrreversibleBlockNum uint32      `json:"last_irreversible_block_num"`
	TotalVersingFundSteem    string      `json:"total_vesting_fund_steem"`
	HeadBlockId              string      `json:"head_block_id"`
	VirtualSupply            string      `json:"virtual_supply"`
	CurrentSBDSupply         string      `json:"current_sbd_supply"`
	ConfidentialSBDSupply    string      `json:"confidential_sbd_supply"`
	TotalRewardFundSteem     string      `json:"total_reward_fund_steem"`
	SBDInterestRate          *types.Int  `json:"sbd_interest_rate"`
	MaxVirtualBandwidth      string      `json:"max_virtual_bandwidth"`
	HeadBlockNumber          *types.Int  `json:"head_block_number"`
}

type Block struct {
	Number                uint32          `json:"-"`
	Timestamp             *types.Time     `json:"timestamp"`
	Witness               string          `json:"witness"`
	WitnessSignature      string          `json:"witness_signature"`
	TransactionMerkleRoot string          `json:"transaction_merkle_root"`
	Previous              string          `json:"previous"`
	Extensions            [][]interface{} `json:"extensions"`
	Transactions          []*Transaction  `json:"transactions"`
}

type Transaction struct {
	RefBlockNum    *types.Int   `json:"ref_block_num"`
	RefBlockPrefix *types.Int   `json:"ref_block_prefix"`
	Expiration     string       `json:"expiration"`
	Operations     []*Operation `json:"operations"`
}

type Operation struct {
	Type string
	Body interface{}
}

func (op *Operation) UnmarshalJSON(data []byte) error {
	raw := make([]json.RawMessage, 2)
	if err := json.Unmarshal(data, &raw); err != nil {
		return err
	}

	if len(raw) != 2 {
		return errors.New("invalid transaction object")
	}

	var operationType string
	if err := json.Unmarshal(raw[0], &operationType); err != nil {
		return err
	}

	switch operationType {
	case OpTypeVote:
		var body VoteOperation
		if err := json.Unmarshal(raw[1], &body); err != nil {
			return err
		}
		op.Body = &body
	case OpTypeComment:
		var body CommentOperation
		if err := json.Unmarshal(raw[1], &body); err != nil {
			return err
		}
		op.Body = &body
	default:
		var body map[string]interface{}
		if err := json.Unmarshal(raw[1], &body); err != nil {
			return err
		}
		op.Body = body
	}

	op.Type = operationType
	return nil
}

type VoteOperation struct {
	Voter    string     `json:"voter"`
	Author   string     `json:"author"`
	Permlink string     `json:"permlink"`
	Weight   *types.Int `json:"weight"`
}

// CommentOperation represents either a new post or a comment.
//
// In case Title is filled in and ParentAuthor is empty, it is a new post.
// The post category can be read from ParentPermlink.
//
// In case the author is just updating an existing post,
// Body contains only the diff against the original content.
type CommentOperation struct {
	Author         string `json:"author"`
	Title          string `json:"title"`
	Permlink       string `json:"permlink"`
	ParentAuthor   string `json:"parent_author"`
	ParentPermlink string `json:"parent_permlink"`
	Body           string `json:"body"`
}

func (op *CommentOperation) IsStoryOperation() bool {
	return op.ParentAuthor == ""
}

type Content struct {
	Id                      *types.ID                `json:"id"`
	RootTitle               string                   `json:"root_title"`
	Active                  *types.Time              `json:"active"`
	AbsRshares              *types.Int               `json:"abs_rshares"`
	PendingPayoutValue      string                   `json:"pending_payout_value"`
	TotalPendingPayoutValue string                   `json:"total_pending_payout_value"`
	Category                string                   `json:"category"`
	Title                   string                   `json:"title"`
	LastUpdate              *types.Time              `json:"last_update"`
	Stats                   string                   `json:"stats"`
	Body                    string                   `json:"body"`
	Created                 *types.Time              `json:"created"`
	Replies                 []map[string]interface{} `json:"replies"`
	Permlink                string                   `json:"permlink"`
	JsonMetadata            *ContentMetadata         `json:"json_metadata"`
	Children                *types.Int               `json:"children"`
	NetRshares              *types.Int               `json:"net_rshares"`
	URL                     string                   `json:"url"`
	ActiveVotes             []*Vote                  `json:"active_votes"`
	ParentPermlink          string                   `json:"parent_permlink"`
	CashoutTime             *types.Time              `json:"cashout_time"`
	TotalPayoutValue        string                   `json:"total_payout_value"`
	ParentAuthor            string                   `json:"parent_author"`
	ChildrenRshares2        *types.Int               `json:"children_rshares2"`
	Author                  string                   `json:"author"`
	Depth                   *types.Int               `json:"depth"`
	TotalVoteWeight         *types.Int               `json:"total_vote_weight"`
}

func (content *Content) IsStory() bool {
	return content.ParentAuthor == ""
}

type ContentMetadata struct {
	Users []string
	Tags  []string
	Image []string
}

type ContentMetadataRaw struct {
	Users []string `json:"users"`
	Tags  []string `json:"tags"`
	Image []string `json:"image"`
}

func (metadata *ContentMetadata) UnmarshalJSON(data []byte) error {
	unquoted, err := strconv.Unquote(string(data))
	if err != nil {
		return err
	}

	if len(unquoted) == 0 {
		var value ContentMetadata
		metadata = &value
		return nil
	}

	var raw ContentMetadataRaw
	if err := json.NewDecoder(strings.NewReader(unquoted)).Decode(&raw); err != nil {
		return err
	}

	metadata.Users = raw.Users
	metadata.Tags = raw.Tags
	metadata.Image = raw.Image

	return nil
}

type Vote struct {
	Voter  string     `json:"voter"`
	Weight *types.Int `json:"weight"`
}
<commit_msg>Revert "Config: Add STEEMIT_BLOCKCHAIN_VERSION"<commit_after>package rpc

import (
	"encoding/json"
	"errors"
	"strconv"
	"strings"

	"github.com/go-steem/rpc/types"
)

type Config struct {
	SteemitBlockInterval uint `json:"STEEMIT_BLOCK_INTERVAL"`
}

type DynamicGlobalProperties struct {
	Time                     *types.Time `json:"time"`
	TotalPow                 *types.Int  `json:"total_pow"`
	NumPowWitnesses          *types.Int  `json:"num_pow_witnesses"`
	ConfidentialSupply       string      `json:"confidential_supply"`
	TotalVestingShares       string      `json:"total_vesting_shares"`
	CurrentReserveRatio      *types.Int  `json:"current_reserve_ratio"`
	Id                       *types.ID   `json:"id"`
	CurrentSupply            string      `json:"current_supply"`
	MaximumBlockSize         *types.Int  `json:"maximum_block_size"`
	RecentSlotsFilled        string      `json:"recent_slots_filled"`
	CurrentWitness           string      `json:"current_witness"`
	TotalRewardShares2       string      `json:"total_reward_shares2"`
	AverageBlockSize         *types.Int  `json:"average_block_size"`
	CurrentAslot             *types.Int  `json:"current_aslot"`
	LastIrreversibleBlockNum uint32      `json:"last_irreversible_block_num"`
	TotalVersingFundSteem    string      `json:"total_vesting_fund_steem"`
	HeadBlockId              string      `json:"head_block_id"`
	VirtualSupply            string      `json:"virtual_supply"`
	CurrentSBDSupply         string      `json:"current_sbd_supply"`
	ConfidentialSBDSupply    string      `json:"confidential_sbd_supply"`
	TotalRewardFundSteem     string      `json:"total_reward_fund_steem"`
	SBDInterestRate          *types.Int  `json:"sbd_interest_rate"`
	MaxVirtualBandwidth      string      `json:"max_virtual_bandwidth"`
	HeadBlockNumber          *types.Int  `json:"head_block_number"`
}

type Block struct {
	Number                uint32          `json:"-"`
	Timestamp             *types.Time     `json:"timestamp"`
	Witness               string          `json:"witness"`
	WitnessSignature      string          `json:"witness_signature"`
	TransactionMerkleRoot string          `json:"transaction_merkle_root"`
	Previous              string          `json:"previous"`
	Extensions            [][]interface{} `json:"extensions"`
	Transactions          []*Transaction  `json:"transactions"`
}

type Transaction struct {
	RefBlockNum    *types.Int   `json:"ref_block_num"`
	RefBlockPrefix *types.Int   `json:"ref_block_prefix"`
	Expiration     string       `json:"expiration"`
	Operations     []*Operation `json:"operations"`
}

type Operation struct {
	Type string
	Body interface{}
}

func (op *Operation) UnmarshalJSON(data []byte) error {
	raw := make([]json.RawMessage, 2)
	if err := json.Unmarshal(data, &raw); err != nil {
		return err
	}

	if len(raw) != 2 {
		return errors.New("invalid transaction object")
	}

	var operationType string
	if err := json.Unmarshal(raw[0], &operationType); err != nil {
		return err
	}

	switch operationType {
	case OpTypeVote:
		var body VoteOperation
		if err := json.Unmarshal(raw[1], &body); err != nil {
			return err
		}
		op.Body = &body
	case OpTypeComment:
		var body CommentOperation
		if err := json.Unmarshal(raw[1], &body); err != nil {
			return err
		}
		op.Body = &body
	default:
		var body map[string]interface{}
		if err := json.Unmarshal(raw[1], &body); err != nil {
			return err
		}
		op.Body = body
	}

	op.Type = operationType
	return nil
}

type VoteOperation struct {
	Voter    string     `json:"voter"`
	Author   string     `json:"author"`
	Permlink string     `json:"permlink"`
	Weight   *types.Int `json:"weight"`
}

// CommentOperation represents either a new post or a comment.
//
// In case Title is filled in and ParentAuthor is empty, it is a new post.
// The post category can be read from ParentPermlink.
//
// In case the author is just updating an existing post,
// Body contains only the diff against the original content.
type CommentOperation struct {
	Author         string `json:"author"`
	Title          string `json:"title"`
	Permlink       string `json:"permlink"`
	ParentAuthor   string `json:"parent_author"`
	ParentPermlink string `json:"parent_permlink"`
	Body           string `json:"body"`
}

func (op *CommentOperation) IsStoryOperation() bool {
	return op.ParentAuthor == ""
}

type Content struct {
	Id                      *types.ID                `json:"id"`
	RootTitle               string                   `json:"root_title"`
	Active                  *types.Time              `json:"active"`
	AbsRshares              *types.Int               `json:"abs_rshares"`
	PendingPayoutValue      string                   `json:"pending_payout_value"`
	TotalPendingPayoutValue string                   `json:"total_pending_payout_value"`
	Category                string                   `json:"category"`
	Title                   string                   `json:"title"`
	LastUpdate              *types.Time              `json:"last_update"`
	Stats                   string                   `json:"stats"`
	Body                    string                   `json:"body"`
	Created                 *types.Time              `json:"created"`
	Replies                 []map[string]interface{} `json:"replies"`
	Permlink                string                   `json:"permlink"`
	JsonMetadata            *ContentMetadata         `json:"json_metadata"`
	Children                *types.Int               `json:"children"`
	NetRshares              *types.Int               `json:"net_rshares"`
	URL                     string                   `json:"url"`
	ActiveVotes             []*Vote                  `json:"active_votes"`
	ParentPermlink          string                   `json:"parent_permlink"`
	CashoutTime             *types.Time              `json:"cashout_time"`
	TotalPayoutValue        string                   `json:"total_payout_value"`
	ParentAuthor            string                   `json:"parent_author"`
	ChildrenRshares2        *types.Int               `json:"children_rshares2"`
	Author                  string                   `json:"author"`
	Depth                   *types.Int               `json:"depth"`
	TotalVoteWeight         *types.Int               `json:"total_vote_weight"`
}

func (content *Content) IsStory() bool {
	return content.ParentAuthor == ""
}

type ContentMetadata struct {
	Users []string
	Tags  []string
	Image []string
}

type ContentMetadataRaw struct {
	Users []string `json:"users"`
	Tags  []string `json:"tags"`
	Image []string `json:"image"`
}

func (metadata *ContentMetadata) UnmarshalJSON(data []byte) error {
	unquoted, err := strconv.Unquote(string(data))
	if err != nil {
		return err
	}

	if len(unquoted) == 0 {
		var value ContentMetadata
		metadata = &value
		return nil
	}

	var raw ContentMetadataRaw
	if err := json.NewDecoder(strings.NewReader(unquoted)).Decode(&raw); err != nil {
		return err
	}

	metadata.Users = raw.Users
	metadata.Tags = raw.Tags
	metadata.Image = raw.Image

	return nil
}

type Vote struct {
	Voter  string     `json:"voter"`
	Weight *types.Int `json:"weight"`
}
<|endoftext|>


<commit_before>package main

import (
	"UNO6401/helper"
	"fmt"
	"os"
	"time"
)

var helpChan chan helper.Message
var okToUse chan int
var userlc int
var myID int

func main() {
	helpChan = make(chan helper.Message, 20)
	okToUse = make(chan int)
	if len(os.Args) != 3 {
		fmt.Println("Usage: " + os.Args[0] + " fileToRead PortListen")
		os.Exit(1)
	}

	hosts, err := helper.ReadLines(os.Args[1])
	if err != nil {
		fmt.Println("Fatal Err:" + err.Error())
		os.Exit(1)
	}
	for pos, val := range hosts {
		if val == os.Args[2] {
			myID = pos
		}
	}

	check(err)

	go helper.Handler(helpChan, myID, hosts, okToUse)
	time.Sleep(time.Second * 3)

	userlc := 0

	for {
		helper.Prompt()
		var cmd string
		fmt.Scanf("%s", &cmd)
		if cmd == "v" || cmd == "V" {
			fmt.Println("V Command Issued")
			msg := helper.Message{Sender: myID, Kind: "reqV", Timestamp: userlc}
			helpChan <- msg
			userlc++
		} else if cmd == "p" || cmd == "P" {
			fmt.Println("P Command Issued")
			msg := helper.Message{Sender: myID, Kind: "reqP", Timestamp: userlc}
			userlc++
			helpChan <- msg
			fmt.Println("Waiting on P")
			ts := <-okToUse
			if ts+1 > userlc {
				userlc = ts + 1
			}
			userlc++
			fmt.Println("Done Waiting on P")
		} else if cmd == "q" || cmd == "Q" {
			fmt.Println("Thank you!")
			close(helpChan)
			return
		} else {
			fmt.Println("Unrecognized Command")
		}
	}

}

// Error handling for i/o
func check(e error) {
	if e != nil {
		panic(e)
	}
}
<commit_msg>Tweaks<commit_after>package main

import (
	"UNO6401/helper"
	"fmt"
	"os"
        "time"
)

var helpChan chan helper.Message
var okToUse chan int
var userlc int
var myID int

func main() {
	helpChan = make(chan helper.Message, 20)
	okToUse = make(chan int)
	if len(os.Args) != 3 {
		fmt.Println("Usage: " + os.Args[0] + " fileToRead PortListen")
		os.Exit(1)
	}

	hosts, err := helper.ReadLines(os.Args[1])
	if err != nil {
		fmt.Println("Fatal Err:" + err.Error())
		os.Exit(1)
	}
	for pos, val := range hosts {
		if val == os.Args[2] {
			myID = pos
		}
	}

	check(err)

        var trash string
        fmt.Scanf("%s",&trash)

	go helper.Handler(helpChan, myID, hosts, okToUse)
        time.Sleep(time.Second * 3)

	userlc := 0

	for {
		helper.Prompt()
		var cmd string
		fmt.Scanf("%s", &cmd)
		if cmd == "v" || cmd == "V" {
			fmt.Println("V Command Issued")
			msg := helper.Message{Sender: myID, Kind: "reqV", Timestamp: userlc}
			helpChan <- msg
			userlc++
		} else if cmd == "p" || cmd == "P" {
			fmt.Println("P Command Issued")
			msg := helper.Message{Sender: myID, Kind: "reqP", Timestamp: userlc}
			userlc++
			helpChan <- msg
			fmt.Println("Waiting on P")
			ts := <-okToUse
			if ts+1 > userlc {
				userlc = ts + 1
			}
			userlc++
			fmt.Println("Done Waiting on P")
		} else if cmd == "q" || cmd == "Q" {
			fmt.Println("Thank you!")
			close(helpChan)
			return
		} else {
			fmt.Println("Unrecognized Command")
		}
	}

}

// Error handling for i/o
func check(e error) {
	if e != nil {
		panic(e)
	}
}
<|endoftext|>


<commit_before>package util

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

	"github.com/satori/go.uuid"
	"gopkg.in/resty.v0"
)

func (u SomaUtil) TryGetBucketByUUIDOrName(b string, r string) uuid.UUID {
	id, err := uuid.FromString(b)
	if err != nil {
		// aborts on failure
		id = u.GetBucketIdByName(b, r)
	}
	return id
}

func (u SomaUtil) GetBucketIdByName(bucket string, repoId string) uuid.UUID {
	var req somaproto.ProtoRequestBucket
	req.Filter.Name = bucket
	req.Filter.RepositoryId = repoId

	resp := u.GetRequestWithBody(req, "/buckets/")
	repoResult := u.DecodeProtoResultBucketFromResponse(resp)

	if bucket != repoResult.Buckets[0].Name {
		u.Abort("Received result set for incorrect bucket")
	}
	return repoResult.Buckets[0].Id
}

func (u SomaUtil) DecodeProtoResultBucketFromResponse(resp *resty.Response) *somaproto.ProtoResultBucket {
	decoder := json.NewDecoder(bytes.NewReader(resp.Body))
	var res somaproto.ProtoResultBucket
	err := decoder.Decode(&res)
	u.AbortOnError(err, "Error decoding server response body")
	if res.Code > 299 {
		s := fmt.Sprintf("Request failed: %d - %s", res.Code, res.Status)
		msgs := []string{s}
		msgs = append(msgs, res.Text...)
		u.Abort(msgs...)
	}
	return &res
}

// vim: ts=4 sw=4 sts=4 noet fenc=utf-8 ffs=unix
<commit_msg>Add more helpers for buckets<commit_after>package util

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

	"github.com/satori/go.uuid"
	"gopkg.in/resty.v0"
)

func (u SomaUtil) TryGetBucketByUUIDOrName(b string, r string) uuid.UUID {
	id, err := uuid.FromString(b)
	if err != nil {
		// aborts on failure
		id = u.GetBucketIdByName(b, r)
	}
	return id
}

func (u SomaUtil) BucketByUUIDOrName(b string) string {
	id, err := uuid.FromString(b)
	if err != nil {
		// aborts on failure
		id = u.BucketIdByName(b)
	}
	return id.String()
}

func (u SomaUtil) GetBucketIdByName(bucket string, repoId string) uuid.UUID {
	var req somaproto.ProtoRequestBucket
	req.Filter.Name = bucket
	req.Filter.RepositoryId = repoId

	resp := u.GetRequestWithBody(req, "/buckets/")
	repoResult := u.DecodeProtoResultBucketFromResponse(resp)

	if bucket != repoResult.Buckets[0].Name {
		u.Abort("Received result set for incorrect bucket")
	}
	return repoResult.Buckets[0].Id
}

func (u SomaUtil) BucketIdByName(bucket string) uuid.UUID {
	var req somaproto.ProtoRequestBucket
	req.Filter.Name = bucket

	resp := u.GetRequestWithBody(req, "/buckets/")
	repoResult := u.DecodeProtoResultBucketFromResponse(resp)

	if bucket != repoResult.Buckets[0].Name {
		u.Abort("Received result set for incorrect bucket")
	}
	return repoResult.Buckets[0].Id
}

func (u SomaUtil) GetRepositoryIdForBucket(bucket string) string {
	var req somaproto.ProtoRequestBucket
	receivedUuidArgument := false

	id, err := uuid.FromString(bucket)
	if err != nil {
		req.Filter.Name = bucket
	} else {
		receivedUuidArgument = true
		req.Filter.Id = id.String()
	}

	resp := u.GetRequestWithBody(req, "/buckets/")
	bucketResult := u.DecodeProtoResultBucketFromResponse(resp)

	if receivedUuidArgument {
		if bucket != bucketResult.Buckets[0].Id.String() {
			u.Abort("Received result set for incorrect bucket")
		}
	} else {
		if bucket != bucketResult.Buckets[0].Name {
			u.Abort("Received result set for incorrect bucket")
		}
	}
	return bucketResult.Buckets[0].RepositoryId
}

func (u SomaUtil) DecodeProtoResultBucketFromResponse(resp *resty.Response) *somaproto.ProtoResultBucket {
	decoder := json.NewDecoder(bytes.NewReader(resp.Body))
	var res somaproto.ProtoResultBucket
	err := decoder.Decode(&res)
	u.AbortOnError(err, "Error decoding server response body")
	if res.Code > 299 {
		s := fmt.Sprintf("Request failed: %d - %s", res.Code, res.Status)
		msgs := []string{s}
		msgs = append(msgs, res.Text...)
		u.Abort(msgs...)
	}
	return &res
}

// vim: ts=4 sw=4 sts=4 noet fenc=utf-8 ffs=unix
<|endoftext|>


<commit_before>package main

<commit_msg>Remove empty file<commit_after><|endoftext|>


<commit_before>package fst

import (
	"fmt"
	"github.com/balzaczyy/golucene/core/util"
)

type BytesStore struct {
	*util.DataOutputImpl
	blocks    [][]byte
	blockSize uint32
	blockBits uint32
	blockMask uint32
	current   []byte
	nextWrite uint32
}

func newBytesStore() *BytesStore {
	bs := &BytesStore{}
	bs.DataOutputImpl = util.NewDataOutput(bs)
	return bs
}

func newBytesStoreFromBits(blockBits uint32) *BytesStore {
	blockSize := uint32(1) << blockBits
	self := newBytesStore()
	self.blockBits = blockBits
	self.blockSize = blockSize
	self.blockMask = blockSize - 1
	self.nextWrite = blockSize
	return self
}

func newBytesStoreFromInput(in util.DataInput, numBytes int64, maxBlockSize uint32) (bs *BytesStore, err error) {
	var blockSize uint32 = 2
	var blockBits uint32 = 1
	for int64(blockSize) < numBytes && blockSize < maxBlockSize {
		blockSize *= 2
		blockBits++
	}
	self := newBytesStore()
	self.blockBits = blockBits
	self.blockSize = blockSize
	self.blockMask = blockSize - 1
	left := numBytes
	for left > 0 {
		chunk := blockSize
		if left < int64(chunk) {
			chunk = uint32(left)
		}
		block := make([]byte, chunk)
		err = in.ReadBytes(block)
		if err != nil {
			return nil, err
		}
		self.blocks = append(self.blocks, block)
		left -= int64(chunk)
	}
	// So .getPosition still works
	self.nextWrite = uint32(len(self.blocks[len(self.blocks)-1]))
	return self, nil
}

func (bs *BytesStore) WriteByte(b byte) error {
	if bs.nextWrite == bs.blockSize {
		bs.current = make([]byte, bs.blockSize)
		bs.blocks = append(bs.blocks, bs.current)
		bs.nextWrite = 0
	}
	bs.current[bs.nextWrite] = b
	bs.nextWrite++
	return nil
}

func (bs *BytesStore) WriteBytes(buf []byte) error {
	var offset uint32 = 0
	length := uint32(len(buf))
	for length > 0 {
		chunk := bs.blockSize - bs.nextWrite
		if length <= chunk {
			copy(bs.current[bs.nextWrite:], buf[offset:offset+length])
			bs.nextWrite += length
			break
		} else {
			if chunk > 0 {
				copy(bs.current[bs.nextWrite:], buf[offset:offset+chunk])
				offset += chunk
				length -= chunk
			}
			bs.current = make([]byte, bs.blockSize)
			bs.blocks = append(bs.blocks, bs.current)
			bs.nextWrite = 0
		}
	}
	return nil
}

func (s *BytesStore) writeBytesAt(dest int64, b []byte) {
	panic("niy")
}

func (s *BytesStore) copyBytesInside(src, dest int64, length int) {
	panic("niy")
}

/* Reverse from srcPos, inclusive, to destPos, inclusive. */
func (s *BytesStore) reverse(srcPos, destPos int64) {
	assert(srcPos < destPos)
	assert(destPos < s.position())
	fmt.Printf("reverse src=%v dest=%v\n", srcPos, destPos)

	srcBlockIndex := int(srcPos >> s.blockBits)
	src := int(srcPos & int64(s.blockMask))
	srcBlock := s.blocks[srcBlockIndex]

	destBlockIndex := int(destPos >> s.blockBits)
	dest := int(destPos & int64(s.blockMask))
	destBlock := s.blocks[destBlockIndex]

	fmt.Printf("  srcBlock=%v destBlock=%v\n", srcBlockIndex, destBlockIndex)

	limit := int((destPos - srcPos + 1) / 2)
	for i := 0; i < limit; i++ {
		fmt.Printf("  cycle src=%v dest=%v\n", src, dest)
		srcBlock[src], destBlock[dest] = destBlock[dest], srcBlock[src]
		if src++; src == int(s.blockSize) {
			srcBlockIndex++
			srcBlock = s.blocks[srcBlockIndex]
			fmt.Printf("  set destBlock=%v srcBlock=%v\n", destBlock, srcBlock)
			src = 0
		}

		if dest--; dest == -1 {
			destBlockIndex--
			destBlock = s.blocks[destBlockIndex]
			fmt.Printf("  set destBlock=%v srcBlock=%v\n", destBlock, srcBlock)
			dest = int(s.blockSize - 1)
		}
	}
}

func (s *BytesStore) skipBytes(length int) {
	panic("niy")
}

func (s *BytesStore) position() int64 {
	return int64(len(s.blocks)-1)*int64(s.blockSize) + int64(s.nextWrite)
}

func (s *BytesStore) finish() {
	if s.current != nil {
		lastBuffer := make([]byte, s.nextWrite)
		copy(lastBuffer, s.current[:s.nextWrite])
		s.blocks[len(s.blocks)-1] = lastBuffer
		s.current = nil
	}
}

/* Writes all of our bytes to the target DataOutput. */
func (s *BytesStore) writeTo(out util.DataOutput) error {
	for _, block := range s.blocks {
		err := out.WriteBytes(block)
		if err != nil {
			return err
		}
	}
	return nil
}

func (s *BytesStore) String() string {
	return fmt.Sprintf("%v-bits x%v bytes store", s.blockBits, len(s.blocks))
}

type BytesStoreForwardReader struct {
	*util.DataInputImpl
	owner      *BytesStore
	current    []byte
	nextBuffer uint32
	nextRead   uint32
}

func (r *BytesStoreForwardReader) ReadByte() (b byte, err error) {
	if r.nextRead == r.owner.blockSize {
		r.current = r.owner.blocks[r.nextBuffer]
		r.nextBuffer++
		r.nextRead = 0
	}
	b = r.current[r.nextRead]
	r.nextRead++
	return b, nil
}

func (r *BytesStoreForwardReader) ReadBytes(buf []byte) error {
	var offset uint32 = 0
	length := uint32(len(buf))
	for length > 0 {
		chunkLeft := r.owner.blockSize - r.nextRead
		if length <= chunkLeft {
			copy(buf[offset:], r.current[r.nextRead:r.nextRead+length])
			r.nextRead += length
			break
		} else {
			if chunkLeft > 0 {
				copy(buf[offset:], r.current[r.nextRead:r.nextRead+chunkLeft])
				offset += chunkLeft
				length -= chunkLeft
			}
			r.current = r.owner.blocks[r.nextBuffer]
			r.nextBuffer++
			r.nextRead = 0
		}
	}
	return nil
}

func (r *BytesStoreForwardReader) skipBytes(count int64) {
	r.setPosition(r.getPosition() + count)
}

func (r *BytesStoreForwardReader) getPosition() int64 {
	return (int64(r.nextBuffer)-1)*int64(r.owner.blockSize) + int64(r.nextRead)
}

func (r *BytesStoreForwardReader) setPosition(pos int64) {
	bufferIndex := pos >> r.owner.blockBits
	r.nextBuffer = uint32(bufferIndex + 1)
	r.current = r.owner.blocks[bufferIndex]
	r.nextRead = uint32(pos) & r.owner.blockMask
	// assert self.getPosition() == pos
}

func (r *BytesStoreForwardReader) reversed() bool {
	return false
}

func (bs *BytesStore) forwardReader() BytesReader {
	if len(bs.blocks) == 1 {
		return newForwardBytesReader(bs.blocks[0])
	}
	ans := &BytesStoreForwardReader{owner: bs, nextRead: bs.blockSize}
	ans.DataInputImpl = util.NewDataInput(ans)
	return ans
}

func (bs *BytesStore) reverseReader() BytesReader {
	return bs.reverseReaderAllowSingle(true)
}

type BytesStoreReverseReader struct {
	*util.DataInputImpl
	owner      *BytesStore
	current    []byte
	nextBuffer int32
	nextRead   int32
}

func newBytesStoreReverseReader(owner *BytesStore, current []byte) *BytesStoreReverseReader {
	ans := &BytesStoreReverseReader{owner: owner, current: current, nextBuffer: -1}
	ans.DataInputImpl = util.NewDataInput(ans)
	return ans
}

func (r *BytesStoreReverseReader) ReadByte() (b byte, err error) {
	if r.nextRead == -1 {
		r.current = r.owner.blocks[r.nextBuffer]
		r.nextBuffer--
		r.nextRead = int32(r.owner.blockSize - 1)
	}
	r.nextRead--
	return r.current[r.nextRead+1], nil
}

func (r *BytesStoreReverseReader) ReadBytes(buf []byte) error {
	var err error
	for i, _ := range buf {
		buf[i], err = r.ReadByte()
		if err != nil {
			return err
		}
	}
	return err
}

func (r *BytesStoreReverseReader) skipBytes(count int64) {
	r.setPosition(r.getPosition() - count)
}

func (r *BytesStoreReverseReader) getPosition() int64 {
	return (int64(r.nextBuffer)+1)*int64(r.owner.blockSize) + int64(r.nextRead)
}

func (r *BytesStoreReverseReader) setPosition(pos int64) {
	// NOTE: a little weird because if you
	// setPosition(0), the next byte you read is
	// bytes[0] ... but I would expect bytes[-1] (ie,
	// EOF)...?
	bufferIndex := int32(pos >> r.owner.blockSize)
	r.nextBuffer = bufferIndex - 1
	r.current = r.owner.blocks[bufferIndex]
	r.nextRead = int32(uint32(pos) & r.owner.blockMask)
	// assert getPosition() == pos
}

func (r *BytesStoreReverseReader) reversed() bool {
	return true
}

func (bs *BytesStore) reverseReaderAllowSingle(allowSingle bool) BytesReader {
	if allowSingle && len(bs.blocks) == 1 {
		return newReverseBytesReader(bs.blocks[0])
	}
	var current []byte = nil
	if len(bs.blocks) > 0 {
		current = bs.blocks[0]
	}
	return newBytesStoreReverseReader(bs, current)
}

type ForwardBytesReader struct {
	*util.DataInputImpl
	bytes []byte
	pos   int
}

func (r *ForwardBytesReader) ReadByte() (b byte, err error) {
	r.pos++
	return r.bytes[r.pos-1], nil
}

func (r *ForwardBytesReader) ReadBytes(buf []byte) error {
	copy(buf, r.bytes[r.pos:r.pos+len(buf)])
	r.pos += len(buf)
	return nil
}

func (r *ForwardBytesReader) skipBytes(count int64) {
	r.pos += int(count)
}

func (r *ForwardBytesReader) getPosition() int64 {
	return int64(r.pos)
}

func (r *ForwardBytesReader) setPosition(pos int64) {
	r.pos = int(pos)
}

func (r *ForwardBytesReader) reversed() bool {
	return false
}

func newForwardBytesReader(bytes []byte) BytesReader {
	ans := &ForwardBytesReader{bytes: bytes}
	ans.DataInputImpl = util.NewDataInput(ans)
	return ans
}

type ReverseBytesReader struct {
	*util.DataInputImpl
	bytes []byte
	pos   int
}

func (r *ReverseBytesReader) ReadByte() (b byte, err error) {
	r.pos--
	return r.bytes[r.pos+1], nil
}

func (r *ReverseBytesReader) ReadBytes(buf []byte) error {
	for i, _ := range buf {
		buf[i] = r.bytes[r.pos]
		r.pos--
	}
	return nil
}

func newReverseBytesReader(bytes []byte) BytesReader {
	ans := &ReverseBytesReader{bytes: bytes}
	ans.DataInputImpl = util.NewDataInput(ans)
	return ans
}

func (r *ReverseBytesReader) skipBytes(count int64) {
	r.pos -= int(count)
}

func (r *ReverseBytesReader) getPosition() int64 {
	return int64(r.pos)
}

func (r *ReverseBytesReader) setPosition(pos int64) {
	r.pos = int(pos)
}

func (r *ReverseBytesReader) reversed() bool {
	return true
}

func (r *ReverseBytesReader) String() string {
	return fmt.Sprintf("BytesReader(reversed, [%v,%v])", r.pos, len(r.bytes))
}
<commit_msg>implement BytesStore.skipBytes()<commit_after>package fst

import (
	"fmt"
	"github.com/balzaczyy/golucene/core/util"
)

type BytesStore struct {
	*util.DataOutputImpl
	blocks    [][]byte
	blockSize uint32
	blockBits uint32
	blockMask uint32
	current   []byte
	nextWrite uint32
}

func newBytesStore() *BytesStore {
	bs := &BytesStore{}
	bs.DataOutputImpl = util.NewDataOutput(bs)
	return bs
}

func newBytesStoreFromBits(blockBits uint32) *BytesStore {
	blockSize := uint32(1) << blockBits
	self := newBytesStore()
	self.blockBits = blockBits
	self.blockSize = blockSize
	self.blockMask = blockSize - 1
	self.nextWrite = blockSize
	return self
}

func newBytesStoreFromInput(in util.DataInput, numBytes int64, maxBlockSize uint32) (bs *BytesStore, err error) {
	var blockSize uint32 = 2
	var blockBits uint32 = 1
	for int64(blockSize) < numBytes && blockSize < maxBlockSize {
		blockSize *= 2
		blockBits++
	}
	self := newBytesStore()
	self.blockBits = blockBits
	self.blockSize = blockSize
	self.blockMask = blockSize - 1
	left := numBytes
	for left > 0 {
		chunk := blockSize
		if left < int64(chunk) {
			chunk = uint32(left)
		}
		block := make([]byte, chunk)
		err = in.ReadBytes(block)
		if err != nil {
			return nil, err
		}
		self.blocks = append(self.blocks, block)
		left -= int64(chunk)
	}
	// So .getPosition still works
	self.nextWrite = uint32(len(self.blocks[len(self.blocks)-1]))
	return self, nil
}

func (bs *BytesStore) WriteByte(b byte) error {
	if bs.nextWrite == bs.blockSize {
		bs.current = make([]byte, bs.blockSize)
		bs.blocks = append(bs.blocks, bs.current)
		bs.nextWrite = 0
	}
	bs.current[bs.nextWrite] = b
	bs.nextWrite++
	return nil
}

func (bs *BytesStore) WriteBytes(buf []byte) error {
	var offset uint32 = 0
	length := uint32(len(buf))
	for length > 0 {
		chunk := bs.blockSize - bs.nextWrite
		if length <= chunk {
			copy(bs.current[bs.nextWrite:], buf[offset:offset+length])
			bs.nextWrite += length
			break
		} else {
			if chunk > 0 {
				copy(bs.current[bs.nextWrite:], buf[offset:offset+chunk])
				offset += chunk
				length -= chunk
			}
			bs.current = make([]byte, bs.blockSize)
			bs.blocks = append(bs.blocks, bs.current)
			bs.nextWrite = 0
		}
	}
	return nil
}

func (s *BytesStore) writeBytesAt(dest int64, b []byte) {
	panic("niy")
}

func (s *BytesStore) copyBytesInside(src, dest int64, length int) {
	panic("niy")
}

/* Reverse from srcPos, inclusive, to destPos, inclusive. */
func (s *BytesStore) reverse(srcPos, destPos int64) {
	assert(srcPos < destPos)
	assert(destPos < s.position())
	fmt.Printf("reverse src=%v dest=%v\n", srcPos, destPos)

	srcBlockIndex := int(srcPos >> s.blockBits)
	src := int(srcPos & int64(s.blockMask))
	srcBlock := s.blocks[srcBlockIndex]

	destBlockIndex := int(destPos >> s.blockBits)
	dest := int(destPos & int64(s.blockMask))
	destBlock := s.blocks[destBlockIndex]

	fmt.Printf("  srcBlock=%v destBlock=%v\n", srcBlockIndex, destBlockIndex)

	limit := int((destPos - srcPos + 1) / 2)
	for i := 0; i < limit; i++ {
		fmt.Printf("  cycle src=%v dest=%v\n", src, dest)
		srcBlock[src], destBlock[dest] = destBlock[dest], srcBlock[src]
		if src++; src == int(s.blockSize) {
			srcBlockIndex++
			srcBlock = s.blocks[srcBlockIndex]
			fmt.Printf("  set destBlock=%v srcBlock=%v\n", destBlock, srcBlock)
			src = 0
		}

		if dest--; dest == -1 {
			destBlockIndex--
			destBlock = s.blocks[destBlockIndex]
			fmt.Printf("  set destBlock=%v srcBlock=%v\n", destBlock, srcBlock)
			dest = int(s.blockSize - 1)
		}
	}
}

func (s *BytesStore) skipBytes(length int) {
	for length > 0 {
		chunk := int(s.blockSize) - int(s.nextWrite)
		if length <= chunk {
			s.nextWrite += uint32(length)
			break
		}
		length -= chunk
		s.current = make([]byte, s.blockSize)
		s.blocks = append(s.blocks, s.current)
		s.nextWrite = 0
	}
}

func (s *BytesStore) position() int64 {
	return int64(len(s.blocks)-1)*int64(s.blockSize) + int64(s.nextWrite)
}

func (s *BytesStore) finish() {
	if s.current != nil {
		lastBuffer := make([]byte, s.nextWrite)
		copy(lastBuffer, s.current[:s.nextWrite])
		s.blocks[len(s.blocks)-1] = lastBuffer
		s.current = nil
	}
}

/* Writes all of our bytes to the target DataOutput. */
func (s *BytesStore) writeTo(out util.DataOutput) error {
	for _, block := range s.blocks {
		err := out.WriteBytes(block)
		if err != nil {
			return err
		}
	}
	return nil
}

func (s *BytesStore) String() string {
	return fmt.Sprintf("%v-bits x%v bytes store", s.blockBits, len(s.blocks))
}

type BytesStoreForwardReader struct {
	*util.DataInputImpl
	owner      *BytesStore
	current    []byte
	nextBuffer uint32
	nextRead   uint32
}

func (r *BytesStoreForwardReader) ReadByte() (b byte, err error) {
	if r.nextRead == r.owner.blockSize {
		r.current = r.owner.blocks[r.nextBuffer]
		r.nextBuffer++
		r.nextRead = 0
	}
	b = r.current[r.nextRead]
	r.nextRead++
	return b, nil
}

func (r *BytesStoreForwardReader) ReadBytes(buf []byte) error {
	var offset uint32 = 0
	length := uint32(len(buf))
	for length > 0 {
		chunkLeft := r.owner.blockSize - r.nextRead
		if length <= chunkLeft {
			copy(buf[offset:], r.current[r.nextRead:r.nextRead+length])
			r.nextRead += length
			break
		} else {
			if chunkLeft > 0 {
				copy(buf[offset:], r.current[r.nextRead:r.nextRead+chunkLeft])
				offset += chunkLeft
				length -= chunkLeft
			}
			r.current = r.owner.blocks[r.nextBuffer]
			r.nextBuffer++
			r.nextRead = 0
		}
	}
	return nil
}

func (r *BytesStoreForwardReader) skipBytes(count int64) {
	r.setPosition(r.getPosition() + count)
}

func (r *BytesStoreForwardReader) getPosition() int64 {
	return (int64(r.nextBuffer)-1)*int64(r.owner.blockSize) + int64(r.nextRead)
}

func (r *BytesStoreForwardReader) setPosition(pos int64) {
	bufferIndex := pos >> r.owner.blockBits
	r.nextBuffer = uint32(bufferIndex + 1)
	r.current = r.owner.blocks[bufferIndex]
	r.nextRead = uint32(pos) & r.owner.blockMask
	// assert self.getPosition() == pos
}

func (r *BytesStoreForwardReader) reversed() bool {
	return false
}

func (bs *BytesStore) forwardReader() BytesReader {
	if len(bs.blocks) == 1 {
		return newForwardBytesReader(bs.blocks[0])
	}
	ans := &BytesStoreForwardReader{owner: bs, nextRead: bs.blockSize}
	ans.DataInputImpl = util.NewDataInput(ans)
	return ans
}

func (bs *BytesStore) reverseReader() BytesReader {
	return bs.reverseReaderAllowSingle(true)
}

type BytesStoreReverseReader struct {
	*util.DataInputImpl
	owner      *BytesStore
	current    []byte
	nextBuffer int32
	nextRead   int32
}

func newBytesStoreReverseReader(owner *BytesStore, current []byte) *BytesStoreReverseReader {
	ans := &BytesStoreReverseReader{owner: owner, current: current, nextBuffer: -1}
	ans.DataInputImpl = util.NewDataInput(ans)
	return ans
}

func (r *BytesStoreReverseReader) ReadByte() (b byte, err error) {
	if r.nextRead == -1 {
		r.current = r.owner.blocks[r.nextBuffer]
		r.nextBuffer--
		r.nextRead = int32(r.owner.blockSize - 1)
	}
	r.nextRead--
	return r.current[r.nextRead+1], nil
}

func (r *BytesStoreReverseReader) ReadBytes(buf []byte) error {
	var err error
	for i, _ := range buf {
		buf[i], err = r.ReadByte()
		if err != nil {
			return err
		}
	}
	return err
}

func (r *BytesStoreReverseReader) skipBytes(count int64) {
	r.setPosition(r.getPosition() - count)
}

func (r *BytesStoreReverseReader) getPosition() int64 {
	return (int64(r.nextBuffer)+1)*int64(r.owner.blockSize) + int64(r.nextRead)
}

func (r *BytesStoreReverseReader) setPosition(pos int64) {
	// NOTE: a little weird because if you
	// setPosition(0), the next byte you read is
	// bytes[0] ... but I would expect bytes[-1] (ie,
	// EOF)...?
	bufferIndex := int32(pos >> r.owner.blockSize)
	r.nextBuffer = bufferIndex - 1
	r.current = r.owner.blocks[bufferIndex]
	r.nextRead = int32(uint32(pos) & r.owner.blockMask)
	// assert getPosition() == pos
}

func (r *BytesStoreReverseReader) reversed() bool {
	return true
}

func (bs *BytesStore) reverseReaderAllowSingle(allowSingle bool) BytesReader {
	if allowSingle && len(bs.blocks) == 1 {
		return newReverseBytesReader(bs.blocks[0])
	}
	var current []byte = nil
	if len(bs.blocks) > 0 {
		current = bs.blocks[0]
	}
	return newBytesStoreReverseReader(bs, current)
}

type ForwardBytesReader struct {
	*util.DataInputImpl
	bytes []byte
	pos   int
}

func (r *ForwardBytesReader) ReadByte() (b byte, err error) {
	r.pos++
	return r.bytes[r.pos-1], nil
}

func (r *ForwardBytesReader) ReadBytes(buf []byte) error {
	copy(buf, r.bytes[r.pos:r.pos+len(buf)])
	r.pos += len(buf)
	return nil
}

func (r *ForwardBytesReader) skipBytes(count int64) {
	r.pos += int(count)
}

func (r *ForwardBytesReader) getPosition() int64 {
	return int64(r.pos)
}

func (r *ForwardBytesReader) setPosition(pos int64) {
	r.pos = int(pos)
}

func (r *ForwardBytesReader) reversed() bool {
	return false
}

func newForwardBytesReader(bytes []byte) BytesReader {
	ans := &ForwardBytesReader{bytes: bytes}
	ans.DataInputImpl = util.NewDataInput(ans)
	return ans
}

type ReverseBytesReader struct {
	*util.DataInputImpl
	bytes []byte
	pos   int
}

func (r *ReverseBytesReader) ReadByte() (b byte, err error) {
	r.pos--
	return r.bytes[r.pos+1], nil
}

func (r *ReverseBytesReader) ReadBytes(buf []byte) error {
	for i, _ := range buf {
		buf[i] = r.bytes[r.pos]
		r.pos--
	}
	return nil
}

func newReverseBytesReader(bytes []byte) BytesReader {
	ans := &ReverseBytesReader{bytes: bytes}
	ans.DataInputImpl = util.NewDataInput(ans)
	return ans
}

func (r *ReverseBytesReader) skipBytes(count int64) {
	r.pos -= int(count)
}

func (r *ReverseBytesReader) getPosition() int64 {
	return int64(r.pos)
}

func (r *ReverseBytesReader) setPosition(pos int64) {
	r.pos = int(pos)
}

func (r *ReverseBytesReader) reversed() bool {
	return true
}

func (r *ReverseBytesReader) String() string {
	return fmt.Sprintf("BytesReader(reversed, [%v,%v])", r.pos, len(r.bytes))
}
<|endoftext|>


<commit_before>package swgohhelp

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/http/httputil"
	"os"
	"path"
	"strings"
)

var errNotImplemented = fmt.Errorf("swgohapi: not implemented")

// Client implements an authenticated callee to the https://api.swgoh.help service.
type Client struct {
	hc       *http.Client
	endpoint string
	token    string
	debug    bool
	cache    dataCache
}

// New initializes an instance of Client making it ready to use.
func New(ctx context.Context) *Client {
	return &Client{
		hc:       http.DefaultClient,
		endpoint: "https://api.swgoh.help",
	}
}

// SetDebug defines the debug state for the client.
func (c *Client) SetDebug(debug bool) *Client {
	c.debug = debug
	return c
}

// call internally makes and logs http requests to the API endpoints.
func (c *Client) call(method, urlPath, contentType string, body io.Reader, args ...interface{}) (resp *http.Response, err error) {
	url := fmt.Sprintf(c.endpoint+urlPath, args...)

	req, err := http.NewRequest(method, url, body)
	req.Header.Set("Content-type", contentType)
	if c.token != "" {
		req.Header.Set("Authorization", "Bearer "+c.token)
	}
	if err != nil {
		return nil, err
	}

	if c.debug {
		b, _ := httputil.DumpRequestOut(req, true)
		writeLogFile(b, "req", method, urlPath)
	}

	resp, err = c.hc.Do(req)
	if err != nil {
		return nil, err
	}

	if c.debug {
		b, _ := httputil.DumpResponse(resp, true)
		writeLogFile(b, "resp", method, urlPath)
	}

	if resp.StatusCode < 200 || resp.StatusCode > 299 {
		return nil, fmt.Errorf("swgohapi: unexpected stauts code calling %s: %d %s", url, resp.StatusCode, resp.Status)
	}

	return resp, nil
}

// SignIn authenticates the client and returns the accessToken or an error if authentication fails.
func (c *Client) SignIn(username, password string) (accessToken string, err error) {
	body := fmt.Sprintf("username=%s&password=%s&grant_type=password&client_id=goapiclient&client_secret=123456", username, password)
	resp, err := c.call("POST", "/auth/signin", "application/x-www-form-urlencoded", strings.NewReader(body))
	if err != nil {
		return "", err
	}
	var authResponse AuthResponse
	if err = json.NewDecoder(resp.Body).Decode(&authResponse); err != nil {
		return "", err
	}
	// Refresh token with the desired one
	c.token = authResponse.AccessToken
	return authResponse.AccessToken, nil
}

// Players retrieves several player profile stats and roster details.
func (c *Client) Players(allyCodes ...string) (players []Player, err error) {
	payload, err := json.Marshal(map[string]interface{}{
		"allycode": allyCodes,
		"language": "eng_us",
		"enums":    true,
		"project": map[string]int{
			"id":         1,
			"allyCode":   1,
			"name":       1,
			"level":      1,
			"stats":      1,
			"arena":      1,
			"roster":     1,
			"guildName":  1,
			"guildRefId": 1,
			"titles":     1,
			"updated":    1,
		},
	})
	if err != nil {
		return nil, err
	}
	resp, err := c.call("POST", "/swgoh/player", "application/json", bytes.NewReader(payload))
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	err = json.NewDecoder(resp.Body).Decode(&players)
	if err != nil {
		return nil, err
	}

	// Enrich result with related data from data collections
	titles, err := c.DataPlayerTitles()
	if err != nil {
		return nil, err
	}
	for i := range players {
		players[i].Titles.Selected = titles[players[i].Titles.Selected].Name
		for j := range players[i].Titles.Unlocked {
			titleKey := players[i].Titles.Unlocked[j]
			players[i].Titles.Unlocked[j] = titles[titleKey].Name
		}
	}

	return players, nil
}

// writeLogFile is a debug helper function to write log data.
func writeLogFile(b []byte, reqresp, method, urlPath string) {
	urlPath = strings.Replace(urlPath, "/", "_", -1)
	fname := path.Join(os.TempDir(), fmt.Sprintf("swgohhelp%s-%s-%s.log", urlPath, method, reqresp))
	log.Printf("swgohhelp: writing log file %s: result: %v", fname, ioutil.WriteFile(fname, b, 0644))
}
<commit_msg>Updated for swgoh.help version 2.<commit_after>package swgohhelp

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/http/httputil"
	"os"
	"path"
	"regexp"
	"strconv"
	"strings"
)

var errNotImplemented = fmt.Errorf("swgohapi: not implemented")

// DefaultEndpoint is the default target host for API calls
var DefaultEndpoint = "https://apiv2.swgoh.help"

// Client implements an authenticated callee to the https://api.swgoh.help service.
type Client struct {
	hc       *http.Client
	endpoint string
	token    string
	debug    bool
	cache    dataCache
}

// New initializes an instance of Client making it ready to use.
func New(ctx context.Context) *Client {
	return &Client{
		hc:       http.DefaultClient,
		endpoint: DefaultEndpoint,
	}
}

// SetDebug defines the debug state for the client.
func (c *Client) SetDebug(debug bool) *Client {
	c.debug = debug
	return c
}

// call internally makes and logs http requests to the API endpoints.
func (c *Client) call(method, urlPath, contentType string, body io.Reader, args ...interface{}) (resp *http.Response, err error) {
	url := fmt.Sprintf(c.endpoint+urlPath, args...)

	req, err := http.NewRequest(method, url, body)
	req.Header.Set("Content-type", contentType)
	if c.token != "" {
		req.Header.Set("Authorization", "Bearer "+c.token)
	}
	if err != nil {
		return nil, err
	}

	if c.debug {
		b, _ := httputil.DumpRequestOut(req, true)
		writeLogFile(b, "req", method, urlPath)
	}

	resp, err = c.hc.Do(req)
	if err != nil {
		return nil, err
	}

	if c.debug {
		b, _ := httputil.DumpResponse(resp, true)
		writeLogFile(b, "resp", method, urlPath)
	}

	if resp.StatusCode < 200 || resp.StatusCode > 299 {
		return nil, fmt.Errorf("swgohapi: unexpected stauts code calling %s: %d %s", url, resp.StatusCode, resp.Status)
	}

	return resp, nil
}

// SignIn authenticates the client and returns the accessToken or an error if authentication fails.
func (c *Client) SignIn(username, password string) (accessToken string, err error) {
	body := fmt.Sprintf("username=%s&password=%s&grant_type=password&client_id=goapiclient&client_secret=123456", username, password)
	resp, err := c.call("POST", "/auth/signin", "application/x-www-form-urlencoded", strings.NewReader(body))
	if err != nil {
		return "", err
	}
	var authResponse AuthResponse
	if err = json.NewDecoder(resp.Body).Decode(&authResponse); err != nil {
		return "", err
	}
	// Refresh token with the desired one
	c.token = authResponse.AccessToken
	return authResponse.AccessToken, nil
}

// Players retrieves several player profile stats and roster details.
func (c *Client) Players(allyCodes ...string) (players []Player, err error) {
	allyCodeNumbers, err := parseAllyCodes(allyCodes...)
	if err != nil {
		return nil, fmt.Errorf("swgohhelp: error parsing ally codes: %v", err)
	}
	payload, err := json.Marshal(map[string]interface{}{
		"allycodes": allyCodeNumbers,
		"language":  "eng_us",
		"enums":     true,
		"project": map[string]int{
			"id":         1,
			"allyCode":   1,
			"name":       1,
			"level":      1,
			"stats":      1,
			"arena":      1,
			"roster":     1,
			"guildName":  1,
			"guildRefId": 1,
			"titles":     1,
			"updated":    1,
		},
	})
	if err != nil {
		return nil, err
	}
	resp, err := c.call("POST", "/swgoh/player", "application/json", bytes.NewReader(payload))
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	err = json.NewDecoder(resp.Body).Decode(&players)
	if err != nil {
		return nil, err
	}

	// Enrich result with related data from data collections
	titles, err := c.DataPlayerTitles()
	if err != nil {
		return nil, err
	}
	for i := range players {
		players[i].Titles.Selected = titles[players[i].Titles.Selected].Name
		for j := range players[i].Titles.Unlocked {
			titleKey := players[i].Titles.Unlocked[j]
			players[i].Titles.Unlocked[j] = titles[titleKey].Name
		}
	}

	return players, nil
}

// writeLogFile is a debug helper function to write log data.
func writeLogFile(b []byte, reqresp, method, urlPath string) {
	urlPath = strings.Replace(urlPath, "/", "_", -1)
	fname := path.Join(os.TempDir(), fmt.Sprintf("swgohhelp%s-%s-%s.log", urlPath, method, reqresp))
	log.Printf("swgohhelp: writing log file %s: result: %v", fname, ioutil.WriteFile(fname, b, 0644))
}

var allyCodeCleanup = regexp.MustCompile("[^0-9]")

// parseAllyCodes takes several ally code as strings and returns integer equivalents.
func parseAllyCodes(allyCodes ...string) (allyCodeNumbers []int, err error) {
	for _, a := range allyCodes {
		n, err := strconv.Atoi(allyCodeCleanup.ReplaceAllString(a, ""))
		if err != nil {
			return nil, err
		}
		allyCodeNumbers = append(allyCodeNumbers, n)
	}
	return
}
<|endoftext|>


<commit_before>package template

import (
	"crypto/md5"
	"errors"
	"fmt"
	"io"
	"os"
)

// fileStat return a fileInfo describing the named file.
func fileStat(name string) (fi fileInfo, err error) {
	if isFileExist(name) {
		f, err := os.Open(name)
		defer f.Close()
		if err != nil {
			return fi, err
		}
		stats, _ := f.Stat()
		fi.Mode = stats.Mode()
		h := md5.New()
		io.Copy(h, f)
		fi.Md5 = fmt.Sprintf("%x", h.Sum(nil))
		return fi, nil
	}
	return fi, errors.New("File not found")
}
<commit_msg>fix fileStat close when open failed on windows<commit_after>package template

import (
	"crypto/md5"
	"errors"
	"fmt"
	"io"
	"os"
)

// fileStat return a fileInfo describing the named file.
func fileStat(name string) (fi fileInfo, err error) {
	if isFileExist(name) {
		f, err := os.Open(name)
		if err != nil {
			return fi, err
		}
		defer f.Close()
		stats, _ := f.Stat()
		fi.Mode = stats.Mode()
		h := md5.New()
		io.Copy(h, f)
		fi.Md5 = fmt.Sprintf("%x", h.Sum(nil))
		return fi, nil
	}
	return fi, errors.New("File not found")
}
<|endoftext|>


<commit_before>package psh

import (
	"os"
	"os/exec"
)

func Sh(cmd string) sh {
	var cmdt commandTemplate
	cmdt.cmd = cmd
	return enclose(&cmdt)
}

type sh func(args ...interface{}) sh

// private type, used exactly once to create a const nobody else can create so we can use it as a flag to trigger private behavior
type expose_t bool

const expose expose_t = true

type exposer struct{ cmdt *commandTemplate }

func closure(cmdt commandTemplate, args ...interface{}) sh {
	if len(args) == 0 {
		// an empty call is a trigger for actually starting execution.
		bareCmd := exec.Command(cmdt.cmd, cmdt.args...)
		// set up direct stdin by hack for now
		bareCmd.Stdin = os.Stdin
		bareCmd.Stdout = os.Stdout
		bareCmd.Stderr = os.Stderr
		cmd := NewRunningCommand(bareCmd)
		cmd.Start()
		cmd.Wait()
		return nil
	} else if args[0] == expose {
		// produce a function that when called with an exposer, exposes its cmdt.
		return func(x ...interface{}) sh {
			t := x[0].(*exposer)
			t.cmdt = &cmdt
			return nil
		}
	} else {
		// examine each of the arguments, modify our (already forked) cmdt, and
		//  return a new callable sh closure with the newly baked command template.
		for _, rarg := range args {
			switch arg := rarg.(type) {
			case string:
				cmdt.bakeArgs(arg)
			default:
				panic(IncomprehensibleCommandModifier{wat:&rarg})
			}
		}
		return enclose(&cmdt)
	}
}

func (f sh) expose() commandTemplate {
	var t exposer
	f(expose)(&t)
	return *t.cmdt
}

func enclose(cmdt *commandTemplate) sh {
	return func(x ...interface{}) sh {
		return closure(*cmdt, x...)
	}
}

func (f sh) BakeArgs(args ...string) sh {
	cmdt := f.expose()
	cmdt.bakeArgs(args...)
	return enclose(&cmdt)
}

func (cmdt *commandTemplate) bakeArgs(args ...string) {
	cmdt.args = append(cmdt.args, args...)
}
<commit_msg>gofmt<commit_after>package psh

import (
	"os"
	"os/exec"
)

func Sh(cmd string) sh {
	var cmdt commandTemplate
	cmdt.cmd = cmd
	return enclose(&cmdt)
}

type sh func(args ...interface{}) sh

// private type, used exactly once to create a const nobody else can create so we can use it as a flag to trigger private behavior
type expose_t bool

const expose expose_t = true

type exposer struct{ cmdt *commandTemplate }

func closure(cmdt commandTemplate, args ...interface{}) sh {
	if len(args) == 0 {
		// an empty call is a trigger for actually starting execution.
		bareCmd := exec.Command(cmdt.cmd, cmdt.args...)
		// set up direct stdin by hack for now
		bareCmd.Stdin = os.Stdin
		bareCmd.Stdout = os.Stdout
		bareCmd.Stderr = os.Stderr
		cmd := NewRunningCommand(bareCmd)
		cmd.Start()
		cmd.Wait()
		return nil
	} else if args[0] == expose {
		// produce a function that when called with an exposer, exposes its cmdt.
		return func(x ...interface{}) sh {
			t := x[0].(*exposer)
			t.cmdt = &cmdt
			return nil
		}
	} else {
		// examine each of the arguments, modify our (already forked) cmdt, and
		//  return a new callable sh closure with the newly baked command template.
		for _, rarg := range args {
			switch arg := rarg.(type) {
			case string:
				cmdt.bakeArgs(arg)
			default:
				panic(IncomprehensibleCommandModifier{wat: &rarg})
			}
		}
		return enclose(&cmdt)
	}
}

func (f sh) expose() commandTemplate {
	var t exposer
	f(expose)(&t)
	return *t.cmdt
}

func enclose(cmdt *commandTemplate) sh {
	return func(x ...interface{}) sh {
		return closure(*cmdt, x...)
	}
}

func (f sh) BakeArgs(args ...string) sh {
	cmdt := f.expose()
	cmdt.bakeArgs(args...)
	return enclose(&cmdt)
}

func (cmdt *commandTemplate) bakeArgs(args ...string) {
	cmdt.args = append(cmdt.args, args...)
}
<|endoftext|>


<commit_before>package model

// TODO: Use github.com/docker/libcompose

import (
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"regexp"
	"strings"

	"github.com/docker/libcompose/config"
	"github.com/docker/libcompose/lookup"
	"github.com/docker/libcompose/project"
	"github.com/dtan4/paus-gitreceive/receiver/util"
	"github.com/pkg/errors"
	"gopkg.in/yaml.v2"
)

const (
	portBindingRegexp = `"?\d+:(\d+)"?`
)

var (
	portBinding = regexp.MustCompile(portBindingRegexp)
)

type Compose struct {
	ComposeFilePath string
	ProjectName     string

	dockerHost string
	project    *project.Project
}

type ComposeConfig struct {
	Version  string                           `yaml:"version,omitempty"`
	Services map[string]*config.ServiceConfig `yaml:"services,omitempty"`
	Volumes  map[string]*config.VolumeConfig  `yaml:"volumes,omitempty"`
	Networks map[string]*config.NetworkConfig `yaml:"networks,omitempty"`
}

func NewCompose(dockerHost, composeFilePath, projectName string) (*Compose, error) {
	ctx := project.Context{
		ComposeFiles: []string{composeFilePath},
		ProjectName:  projectName,
	}

	ctx.ResourceLookup = &lookup.FileConfigLookup{}
	ctx.EnvironmentLookup = &lookup.ComposableEnvLookup{
		Lookups: []config.EnvironmentLookup{
			&lookup.OsEnvLookup{},
		},
	}

	prj := project.NewProject(&ctx, nil, nil)

	if err := prj.Parse(); err != nil {
		return nil, errors.Wrap(err, "Failed to parse docker-compose.yml.")
	}

	return &Compose{
		ComposeFilePath: composeFilePath,
		ProjectName:     projectName,
		dockerHost:      dockerHost,
		project:         prj,
	}, nil
}

func (c *Compose) Build() error {
	cmd := exec.Command("docker-compose", "-f", c.ComposeFilePath, "-p", c.ProjectName, "build")
	cmd.Env = append(os.Environ(), "DOCKER_HOST="+c.dockerHost)

	if err := util.RunCommand(cmd); err != nil {
		return err
	}

	return nil
}

func (c *Compose) GetContainerID(service string) (string, error) {
	cmd := exec.Command("docker-compose", "-f", c.ComposeFilePath, "-p", c.ProjectName, "ps", "-q", service)
	cmd.Env = append(os.Environ(), "DOCKER_HOST="+c.dockerHost)
	out, err := cmd.Output()

	if err != nil {
		return "", errors.Wrapf(err, "Failed to get container ID. projectName: %s, service: %s", c.ProjectName, service)
	}

	return strings.Replace(string(out), "\n", "", -1), nil
}

func (c *Compose) InjectBuildArgs(buildArgs map[string]string) {
	webService := c.webService()

	if webService == nil {
		return
	}

	if webService.Build.Args == nil {
		webService.Build.Args = map[string]string{}
	}

	for k, v := range buildArgs {
		webService.Build.Args[k] = v
	}
}

func (c *Compose) InjectEnvironmentVariables(envs map[string]string) {
	webService := c.webService()

	if webService == nil {
		return
	}

	for k, v := range envs {
		webService.Environment = append(webService.Environment, fmt.Sprintf("%s=\"%s\"", k, v))
	}
}

func (c *Compose) Pull() error {
	cmd := exec.Command("docker-compose", "-f", c.ComposeFilePath, "-p", c.ProjectName, "pull")
	cmd.Env = append(os.Environ(), "DOCKER_HOST="+c.dockerHost)

	if err := util.RunCommand(cmd); err != nil {
		return err
	}

	return nil
}

func (c *Compose) RewritePortBindings() {
	var newPorts []string

	for _, key := range c.project.ServiceConfigs.Keys() {
		if svc, ok := c.project.ServiceConfigs.Get(key); ok {
			if len(svc.Ports) == 0 {
				continue
			}

			newPorts = []string{}

			for _, port := range svc.Ports {
				matchResult := portBinding.FindStringSubmatch(port)

				if len(matchResult) == 2 {
					newPorts = append(newPorts, matchResult[1])
				} else {
					newPorts = append(newPorts, port)
				}
			}

			svc.Ports = newPorts
		}
	}
}

func (c *Compose) SaveAs(filePath string) error {
	services := map[string]*config.ServiceConfig{}

	for _, key := range c.project.ServiceConfigs.Keys() {
		if svc, ok := c.project.ServiceConfigs.Get(key); ok {
			services[key] = svc
		}
	}

	cfg := &ComposeConfig{
		Version:  "2",
		Services: services,
		Volumes:  c.project.VolumeConfigs,
		Networks: c.project.NetworkConfigs,
	}

	data, err := yaml.Marshal(cfg)

	if err != nil {
		return errors.Wrap(err, "Failed to generate YAML file.")
	}

	if err = ioutil.WriteFile(filePath, data, 0644); err != nil {
		return errors.Wrapf(err, "Failed to save as YAML file. path: %s", filePath)
	}

	c.ComposeFilePath = filePath

	return nil
}

func (c *Compose) Stop() error {
	cmd := exec.Command("docker-compose", "-f", c.ComposeFilePath, "-p", c.ProjectName, "stop")
	cmd.Env = append(os.Environ(), "DOCKER_HOST="+c.dockerHost)

	if err := util.RunCommand(cmd); err != nil {
		return err
	}

	return nil
}

func (c *Compose) Up() error {
	cmd := exec.Command("docker-compose", "-f", c.ComposeFilePath, "-p", c.ProjectName, "up", "-d")
	cmd.Env = append(os.Environ(), "DOCKER_HOST="+c.dockerHost)

	if err := util.RunCommand(cmd); err != nil {
		return err
	}

	return nil
}

func (c *Compose) webService() *config.ServiceConfig {
	if svc, ok := c.project.ServiceConfigs.Get("web"); ok {
		return svc
	}

	return nil
}
<commit_msg>Do not quote environment variable value<commit_after>package model

// TODO: Use github.com/docker/libcompose

import (
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"regexp"
	"strings"

	"github.com/docker/libcompose/config"
	"github.com/docker/libcompose/lookup"
	"github.com/docker/libcompose/project"
	"github.com/dtan4/paus-gitreceive/receiver/util"
	"github.com/pkg/errors"
	"gopkg.in/yaml.v2"
)

const (
	portBindingRegexp = `"?\d+:(\d+)"?`
)

var (
	portBinding = regexp.MustCompile(portBindingRegexp)
)

type Compose struct {
	ComposeFilePath string
	ProjectName     string

	dockerHost string
	project    *project.Project
}

type ComposeConfig struct {
	Version  string                           `yaml:"version,omitempty"`
	Services map[string]*config.ServiceConfig `yaml:"services,omitempty"`
	Volumes  map[string]*config.VolumeConfig  `yaml:"volumes,omitempty"`
	Networks map[string]*config.NetworkConfig `yaml:"networks,omitempty"`
}

func NewCompose(dockerHost, composeFilePath, projectName string) (*Compose, error) {
	ctx := project.Context{
		ComposeFiles: []string{composeFilePath},
		ProjectName:  projectName,
	}

	ctx.ResourceLookup = &lookup.FileConfigLookup{}
	ctx.EnvironmentLookup = &lookup.ComposableEnvLookup{
		Lookups: []config.EnvironmentLookup{
			&lookup.OsEnvLookup{},
		},
	}

	prj := project.NewProject(&ctx, nil, nil)

	if err := prj.Parse(); err != nil {
		return nil, errors.Wrap(err, "Failed to parse docker-compose.yml.")
	}

	return &Compose{
		ComposeFilePath: composeFilePath,
		ProjectName:     projectName,
		dockerHost:      dockerHost,
		project:         prj,
	}, nil
}

func (c *Compose) Build() error {
	cmd := exec.Command("docker-compose", "-f", c.ComposeFilePath, "-p", c.ProjectName, "build")
	cmd.Env = append(os.Environ(), "DOCKER_HOST="+c.dockerHost)

	if err := util.RunCommand(cmd); err != nil {
		return err
	}

	return nil
}

func (c *Compose) GetContainerID(service string) (string, error) {
	cmd := exec.Command("docker-compose", "-f", c.ComposeFilePath, "-p", c.ProjectName, "ps", "-q", service)
	cmd.Env = append(os.Environ(), "DOCKER_HOST="+c.dockerHost)
	out, err := cmd.Output()

	if err != nil {
		return "", errors.Wrapf(err, "Failed to get container ID. projectName: %s, service: %s", c.ProjectName, service)
	}

	return strings.Replace(string(out), "\n", "", -1), nil
}

func (c *Compose) InjectBuildArgs(buildArgs map[string]string) {
	webService := c.webService()

	if webService == nil {
		return
	}

	if webService.Build.Args == nil {
		webService.Build.Args = map[string]string{}
	}

	for k, v := range buildArgs {
		webService.Build.Args[k] = v
	}
}

func (c *Compose) InjectEnvironmentVariables(envs map[string]string) {
	webService := c.webService()

	if webService == nil {
		return
	}

	for k, v := range envs {
		webService.Environment = append(webService.Environment, fmt.Sprintf("%s=%s", k, v))
	}
}

func (c *Compose) Pull() error {
	cmd := exec.Command("docker-compose", "-f", c.ComposeFilePath, "-p", c.ProjectName, "pull")
	cmd.Env = append(os.Environ(), "DOCKER_HOST="+c.dockerHost)

	if err := util.RunCommand(cmd); err != nil {
		return err
	}

	return nil
}

func (c *Compose) RewritePortBindings() {
	var newPorts []string

	for _, key := range c.project.ServiceConfigs.Keys() {
		if svc, ok := c.project.ServiceConfigs.Get(key); ok {
			if len(svc.Ports) == 0 {
				continue
			}

			newPorts = []string{}

			for _, port := range svc.Ports {
				matchResult := portBinding.FindStringSubmatch(port)

				if len(matchResult) == 2 {
					newPorts = append(newPorts, matchResult[1])
				} else {
					newPorts = append(newPorts, port)
				}
			}

			svc.Ports = newPorts
		}
	}
}

func (c *Compose) SaveAs(filePath string) error {
	services := map[string]*config.ServiceConfig{}

	for _, key := range c.project.ServiceConfigs.Keys() {
		if svc, ok := c.project.ServiceConfigs.Get(key); ok {
			services[key] = svc
		}
	}

	cfg := &ComposeConfig{
		Version:  "2",
		Services: services,
		Volumes:  c.project.VolumeConfigs,
		Networks: c.project.NetworkConfigs,
	}

	data, err := yaml.Marshal(cfg)

	if err != nil {
		return errors.Wrap(err, "Failed to generate YAML file.")
	}

	if err = ioutil.WriteFile(filePath, data, 0644); err != nil {
		return errors.Wrapf(err, "Failed to save as YAML file. path: %s", filePath)
	}

	c.ComposeFilePath = filePath

	return nil
}

func (c *Compose) Stop() error {
	cmd := exec.Command("docker-compose", "-f", c.ComposeFilePath, "-p", c.ProjectName, "stop")
	cmd.Env = append(os.Environ(), "DOCKER_HOST="+c.dockerHost)

	if err := util.RunCommand(cmd); err != nil {
		return err
	}

	return nil
}

func (c *Compose) Up() error {
	cmd := exec.Command("docker-compose", "-f", c.ComposeFilePath, "-p", c.ProjectName, "up", "-d")
	cmd.Env = append(os.Environ(), "DOCKER_HOST="+c.dockerHost)

	if err := util.RunCommand(cmd); err != nil {
		return err
	}

	return nil
}

func (c *Compose) webService() *config.ServiceConfig {
	if svc, ok := c.project.ServiceConfigs.Get("web"); ok {
		return svc
	}

	return nil
}
<|endoftext|>