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

package helpers

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"html/template"
	"io"
	"io/ioutil"
	"math/rand"
	"os"
	"path/filepath"
	"strings"
	"syscall"
	"time"

	"github.com/cilium/cilium/test/config"
	ginkgoext "github.com/cilium/cilium/test/ginkgo-ext"

	"github.com/Jeffail/gabs"
	"github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"k8s.io/apimachinery/pkg/util/yaml"
)

// IsRunningOnJenkins detects if the currently running Ginkgo application is
// most likely running in a Jenkins environment. Returns true if certain
// environment variables that are present in Jenkins jobs are set, false
// otherwise.
func IsRunningOnJenkins() bool {
	result := true

	env := []string{"JENKINS_HOME", "NODE_NAME"}

	for _, varName := range env {
		if val := os.Getenv(varName); val == "" {
			result = false
			log.Infof("build is not running on Jenkins; environment variable '%v' is not set", varName)
		}
	}
	return result
}

// Sleep sleeps for the specified duration in seconds
func Sleep(delay time.Duration) {
	time.Sleep(delay * time.Second)
}

// CountValues returns the count of the occurrences of key in data, as well as
// the length of data.
func CountValues(key string, data []string) (int, int) {
	var result int

	for _, x := range data {
		if x == key {
			result++
		}
	}
	return result, len(data)
}

// MakeUID returns a randomly generated string.
func MakeUID() string {
	return fmt.Sprintf("%08x", rand.Uint32())
}

// RenderTemplateToFile renders a text/template string into a target filename
// with specific persmisions. Returns eturn an error if the template cannot be
// validated or the file cannot be created.
func RenderTemplateToFile(filename string, tmplt string, perm os.FileMode) error {
	t, err := template.New("").Parse(tmplt)
	if err != nil {
		return err
	}
	content := new(bytes.Buffer)
	err = t.Execute(content, nil)
	if err != nil {
		return err
	}

	err = ioutil.WriteFile(filename, content.Bytes(), perm)
	if err != nil {
		return err
	}
	return nil
}

// TimeoutConfig represents the configuration for the timeout of a command.
type TimeoutConfig struct {
	Ticker  time.Duration // Check interval in duration.
	Timeout time.Duration // Timeout definition
}

// WithTimeout executes body using the time interval specified in config until
// the timeout in config is reached. Returns an error if the timeout is
// exceeded for body to execute successfully.
func WithTimeout(body func() bool, msg string, config *TimeoutConfig) error {
	if config.Ticker == 0 {
		config.Ticker = 5
	}

	done := time.After(config.Timeout * time.Second)
	ticker := time.NewTicker(config.Ticker * time.Second)
	defer ticker.Stop()

	for {
		select {
		case <-ticker.C:
			if body() {
				return nil
			}
		case <-done:
			return fmt.Errorf("Timeout reached: %s", msg)
		}
	}
}

// WithTimeoutErr executes body using the time interval specified. The function
// f is executed until bool returns true or the given context signalizes Done.
func WithTimeoutErr(ctx context.Context, f func() (bool, error), freq time.Duration) error {
	ticker := time.NewTicker(freq)
	defer ticker.Stop()
	for {
		select {
		case <-ctx.Done():
			return ctx.Err()
		case <-ticker.C:
			exit, err := f()
			if err != nil {
				return err
			}
			if exit {
				return nil
			}
		}
	}
}

// InstallExampleCilium uses Cilium Kubernetes example from the repo,
// changes the etcd parameter and installs the stable tag from docker-hub
func InstallExampleCilium(kubectl *Kubectl) {

	var path = filepath.Join("..", "examples", "kubernetes", GetCurrentK8SEnv(), "cilium.yaml")
	var result bytes.Buffer
	timeout := time.Duration(800)

	newCiliumDSName := fmt.Sprintf("cilium_ds_%s.json", MakeUID())

	objects, err := DecodeYAMLOrJSON(path)
	Expect(err).To(BeNil())

	for _, object := range objects {
		data, err := json.Marshal(object)
		Expect(err).To(BeNil())

		jsonObj, err := gabs.ParseJSON(data)
		Expect(err).To(BeNil())

		value, _ := jsonObj.Path("kind").Data().(string)
		if value == configMap {
			jsonObj.SetP("---\nendpoints:\n- http://k8s1:9732\n", "data.etcd-config")
			jsonObj.SetP("true", "data.debug")
		}
		value, _ = jsonObj.Path("kind").Data().(string)
		if value == daemonSet {
			container := jsonObj.Path("spec.template.spec.containers").Index(0)
			container.Set(StableImage, "image")
		}
		result.WriteString(jsonObj.String())
	}

	fp, err := os.Create(newCiliumDSName)
	defer fp.Close()
	Expect(err).To(BeNil())

	fmt.Fprint(fp, result.String())

	kubectl.Apply(GetFilePath(newCiliumDSName)).ExpectSuccess(
		"cannot apply cilium example daemonset")

	err = kubectl.WaitforPods(
		KubeSystemNamespace, "-l k8s-app=cilium", timeout)
	ExpectWithOffset(1, err).Should(BeNil(), "Cilium is not ready after timeout")

	ginkgoext.By(fmt.Sprintf("Checking that installed image is %q", StableImage))

	filter := `{.items[*].status.containerStatuses[0].image}`
	data, err := kubectl.GetPods(
		KubeSystemNamespace, "-l k8s-app=cilium").Filter(filter)
	ExpectWithOffset(1, err).To(BeNil(), "Cannot get cilium pods")

	for _, val := range strings.Split(data.String(), " ") {
		ExpectWithOffset(1, val).To(Equal(StableImage), "Cilium image didn't update correctly")
	}
}

// GetAppPods fetches app pod names for a namespace.
// For Http based tests, we identify pods with format id=<pod_name>, while
// for Kafka based tests, we identify pods with the format app=<pod_name>.
func GetAppPods(apps []string, namespace string, kubectl *Kubectl, appFmt string) map[string]string {
	appPods := make(map[string]string)
	for _, v := range apps {
		res, err := kubectl.GetPodNames(namespace, fmt.Sprintf("%s=%s", appFmt, v))
		Expect(err).Should(BeNil())
		Expect(res).Should(Not(BeNil()))
		appPods[v] = res[0]
		log.Infof("GetAppPods: pod=%q assigned to %q", res[0], v)
	}
	return appPods
}

// WaitUntilEndpointUpdates checks the policy version and then iterates through
// all endpoints waiting for the endpoints to have updated policies.
func WaitUntilEndpointUpdates(pod string, eps map[string]int64, min int, kubectl *Kubectl) error {
	body := func() bool {
		updated := 0
		newEps := kubectl.CiliumEndpointPolicyVersion(pod)
		for k, v := range newEps {
			if eps[k] < v {
				log.Infof("Endpoint %s had version %d now %d updated : %d", k, eps[k], v, updated)
				updated++
			}
		}
		return updated >= min
	}
	err := WithTimeout(body, "No new version applied", &TimeoutConfig{Timeout: 100})
	return err
}

// Fail is a Ginkgo failure handler which raises a SIGSTOP for the test process
// when there is a failure, so that developers can debug the live environment.
// It is only triggered if the developer provides a commandline flag.
func Fail(description string, callerSkip ...int) {
	if len(callerSkip) > 0 {
		callerSkip[0]++
	} else {
		callerSkip = []int{1}
	}

	if config.CiliumTestConfig.HoldEnvironment {
		test := ginkgo.CurrentGinkgoTestDescription()
		pid := syscall.Getpid()

		fmt.Fprintf(os.Stdout, "\n---\n%s", test.FullTestText)
		fmt.Fprintf(os.Stdout, "\nat %s:%d", test.FileName, test.LineNumber)
		fmt.Fprintf(os.Stdout, "\n\n%s", description)
		fmt.Fprintf(os.Stdout, "\n\nPausing test for debug, use vagrant to access test setup.")
		fmt.Fprintf(os.Stdout, "\nRun \"kill -SIGCONT %d\" to continue.\n", pid)
		syscall.Kill(pid, syscall.SIGSTOP)
	}
	ginkgoext.Fail(description, callerSkip...)
}

// CreateReportDirectory creates and returns the directory path to export all report
// commands that need to be run in the case that a test has failed.
// If the directory cannot be created it'll return an error
func CreateReportDirectory() (string, error) {
	prefix := ""
	testName := ginkgoext.GetTestName()
	if strings.HasPrefix(strings.ToLower(testName), K8s) {
		prefix = fmt.Sprintf("%s-", strings.Replace(GetCurrentK8SEnv(), ".", "", -1))
	}

	testPath := filepath.Join(
		TestResultsPath,
		prefix,
		testName)
	if _, err := os.Stat(testPath); err == nil {
		return testPath, nil
	}
	err := os.MkdirAll(testPath, os.ModePerm)
	return testPath, err
}

// CreateLogFile creates the ReportDirectory if it is not present, writes the
// given data to the given filename.
func CreateLogFile(filename string, data []byte) error {
	path, err := CreateReportDirectory()
	if err != nil {
		log.WithError(err).Errorf("ReportDirectory cannot be created")
		return err
	}

	finalPath := filepath.Join(path, filename)
	err = ioutil.WriteFile(finalPath, data, LogPerm)
	return err
}

// reportMap saves the output of the given commands to the specified filename.
// Function needs a directory path where the files are going to be written and
// a *SSHMeta instance to execute the commands
func reportMap(path string, reportCmds map[string]string, node *SSHMeta) {
	if node == nil {
		log.Errorf("cannot execute reportMap due invalid node instance")
		return
	}

	for cmd, logfile := range reportCmds {
		res := node.Exec(cmd, ExecOptions{SkipLog: true})
		err := ioutil.WriteFile(
			fmt.Sprintf("%s/%s", path, logfile),
			res.CombineOutput().Bytes(),
			LogPerm)
		if err != nil {
			log.WithError(err).Errorf("cannot create test results for command '%s'", cmd)
		}
	}
}

// DecodeYAMLOrJSON reads a json or yaml file and exports all documents as an
// array of interfaces. In case of an invalid path or invalid format it returns
// an error.
func DecodeYAMLOrJSON(path string) ([]interface{}, error) {
	var result []interface{}
	content, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}
	d := yaml.NewYAMLOrJSONDecoder(bytes.NewReader(content), 4096)
	for {
		var ext interface{}
		if err := d.Decode(&ext); err != nil {
			if err == io.EOF {
				break
			}
			return nil, fmt.Errorf("cannot decode the content: %s", err)
		}
		result = append(result, ext)
	}
	return result, nil
}

// ManifestGet returns the full path of the given manifest corresponding to the
// Kubernetes version being tested, if such a manifest exists, if not it
// returns the global manifest file.
func ManifestGet(manifestFilename string) string {
	fullPath := filepath.Join(manifestsPath, GetCurrentK8SEnv(), manifestFilename)
	_, err := os.Stat(fullPath)
	if err == nil {
		return filepath.Join(BasePath, fullPath)
	}
	return filepath.Join(BasePath, "k8sT", "manifests", manifestFilename)
}
<commit_msg>Test: Delete WaitUntilEndpointUpdates helper function<commit_after>// Copyright 2017-2018 Authors of Cilium
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package helpers

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"html/template"
	"io"
	"io/ioutil"
	"math/rand"
	"os"
	"path/filepath"
	"strings"
	"syscall"
	"time"

	"github.com/cilium/cilium/test/config"
	ginkgoext "github.com/cilium/cilium/test/ginkgo-ext"

	"github.com/Jeffail/gabs"
	"github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"k8s.io/apimachinery/pkg/util/yaml"
)

// IsRunningOnJenkins detects if the currently running Ginkgo application is
// most likely running in a Jenkins environment. Returns true if certain
// environment variables that are present in Jenkins jobs are set, false
// otherwise.
func IsRunningOnJenkins() bool {
	result := true

	env := []string{"JENKINS_HOME", "NODE_NAME"}

	for _, varName := range env {
		if val := os.Getenv(varName); val == "" {
			result = false
			log.Infof("build is not running on Jenkins; environment variable '%v' is not set", varName)
		}
	}
	return result
}

// Sleep sleeps for the specified duration in seconds
func Sleep(delay time.Duration) {
	time.Sleep(delay * time.Second)
}

// CountValues returns the count of the occurrences of key in data, as well as
// the length of data.
func CountValues(key string, data []string) (int, int) {
	var result int

	for _, x := range data {
		if x == key {
			result++
		}
	}
	return result, len(data)
}

// MakeUID returns a randomly generated string.
func MakeUID() string {
	return fmt.Sprintf("%08x", rand.Uint32())
}

// RenderTemplateToFile renders a text/template string into a target filename
// with specific persmisions. Returns eturn an error if the template cannot be
// validated or the file cannot be created.
func RenderTemplateToFile(filename string, tmplt string, perm os.FileMode) error {
	t, err := template.New("").Parse(tmplt)
	if err != nil {
		return err
	}
	content := new(bytes.Buffer)
	err = t.Execute(content, nil)
	if err != nil {
		return err
	}

	err = ioutil.WriteFile(filename, content.Bytes(), perm)
	if err != nil {
		return err
	}
	return nil
}

// TimeoutConfig represents the configuration for the timeout of a command.
type TimeoutConfig struct {
	Ticker  time.Duration // Check interval in duration.
	Timeout time.Duration // Timeout definition
}

// WithTimeout executes body using the time interval specified in config until
// the timeout in config is reached. Returns an error if the timeout is
// exceeded for body to execute successfully.
func WithTimeout(body func() bool, msg string, config *TimeoutConfig) error {
	if config.Ticker == 0 {
		config.Ticker = 5
	}

	done := time.After(config.Timeout * time.Second)
	ticker := time.NewTicker(config.Ticker * time.Second)
	defer ticker.Stop()

	for {
		select {
		case <-ticker.C:
			if body() {
				return nil
			}
		case <-done:
			return fmt.Errorf("Timeout reached: %s", msg)
		}
	}
}

// WithTimeoutErr executes body using the time interval specified. The function
// f is executed until bool returns true or the given context signalizes Done.
func WithTimeoutErr(ctx context.Context, f func() (bool, error), freq time.Duration) error {
	ticker := time.NewTicker(freq)
	defer ticker.Stop()
	for {
		select {
		case <-ctx.Done():
			return ctx.Err()
		case <-ticker.C:
			exit, err := f()
			if err != nil {
				return err
			}
			if exit {
				return nil
			}
		}
	}
}

// InstallExampleCilium uses Cilium Kubernetes example from the repo,
// changes the etcd parameter and installs the stable tag from docker-hub
func InstallExampleCilium(kubectl *Kubectl) {

	var path = filepath.Join("..", "examples", "kubernetes", GetCurrentK8SEnv(), "cilium.yaml")
	var result bytes.Buffer
	timeout := time.Duration(800)

	newCiliumDSName := fmt.Sprintf("cilium_ds_%s.json", MakeUID())

	objects, err := DecodeYAMLOrJSON(path)
	Expect(err).To(BeNil())

	for _, object := range objects {
		data, err := json.Marshal(object)
		Expect(err).To(BeNil())

		jsonObj, err := gabs.ParseJSON(data)
		Expect(err).To(BeNil())

		value, _ := jsonObj.Path("kind").Data().(string)
		if value == configMap {
			jsonObj.SetP("---\nendpoints:\n- http://k8s1:9732\n", "data.etcd-config")
			jsonObj.SetP("true", "data.debug")
		}
		value, _ = jsonObj.Path("kind").Data().(string)
		if value == daemonSet {
			container := jsonObj.Path("spec.template.spec.containers").Index(0)
			container.Set(StableImage, "image")
		}
		result.WriteString(jsonObj.String())
	}

	fp, err := os.Create(newCiliumDSName)
	defer fp.Close()
	Expect(err).To(BeNil())

	fmt.Fprint(fp, result.String())

	kubectl.Apply(GetFilePath(newCiliumDSName)).ExpectSuccess(
		"cannot apply cilium example daemonset")

	err = kubectl.WaitforPods(
		KubeSystemNamespace, "-l k8s-app=cilium", timeout)
	ExpectWithOffset(1, err).Should(BeNil(), "Cilium is not ready after timeout")

	ginkgoext.By(fmt.Sprintf("Checking that installed image is %q", StableImage))

	filter := `{.items[*].status.containerStatuses[0].image}`
	data, err := kubectl.GetPods(
		KubeSystemNamespace, "-l k8s-app=cilium").Filter(filter)
	ExpectWithOffset(1, err).To(BeNil(), "Cannot get cilium pods")

	for _, val := range strings.Split(data.String(), " ") {
		ExpectWithOffset(1, val).To(Equal(StableImage), "Cilium image didn't update correctly")
	}
}

// GetAppPods fetches app pod names for a namespace.
// For Http based tests, we identify pods with format id=<pod_name>, while
// for Kafka based tests, we identify pods with the format app=<pod_name>.
func GetAppPods(apps []string, namespace string, kubectl *Kubectl, appFmt string) map[string]string {
	appPods := make(map[string]string)
	for _, v := range apps {
		res, err := kubectl.GetPodNames(namespace, fmt.Sprintf("%s=%s", appFmt, v))
		Expect(err).Should(BeNil())
		Expect(res).Should(Not(BeNil()))
		appPods[v] = res[0]
		log.Infof("GetAppPods: pod=%q assigned to %q", res[0], v)
	}
	return appPods
}

// Fail is a Ginkgo failure handler which raises a SIGSTOP for the test process
// when there is a failure, so that developers can debug the live environment.
// It is only triggered if the developer provides a commandline flag.
func Fail(description string, callerSkip ...int) {
	if len(callerSkip) > 0 {
		callerSkip[0]++
	} else {
		callerSkip = []int{1}
	}

	if config.CiliumTestConfig.HoldEnvironment {
		test := ginkgo.CurrentGinkgoTestDescription()
		pid := syscall.Getpid()

		fmt.Fprintf(os.Stdout, "\n---\n%s", test.FullTestText)
		fmt.Fprintf(os.Stdout, "\nat %s:%d", test.FileName, test.LineNumber)
		fmt.Fprintf(os.Stdout, "\n\n%s", description)
		fmt.Fprintf(os.Stdout, "\n\nPausing test for debug, use vagrant to access test setup.")
		fmt.Fprintf(os.Stdout, "\nRun \"kill -SIGCONT %d\" to continue.\n", pid)
		syscall.Kill(pid, syscall.SIGSTOP)
	}
	ginkgoext.Fail(description, callerSkip...)
}

// CreateReportDirectory creates and returns the directory path to export all report
// commands that need to be run in the case that a test has failed.
// If the directory cannot be created it'll return an error
func CreateReportDirectory() (string, error) {
	prefix := ""
	testName := ginkgoext.GetTestName()
	if strings.HasPrefix(strings.ToLower(testName), K8s) {
		prefix = fmt.Sprintf("%s-", strings.Replace(GetCurrentK8SEnv(), ".", "", -1))
	}

	testPath := filepath.Join(
		TestResultsPath,
		prefix,
		testName)
	if _, err := os.Stat(testPath); err == nil {
		return testPath, nil
	}
	err := os.MkdirAll(testPath, os.ModePerm)
	return testPath, err
}

// CreateLogFile creates the ReportDirectory if it is not present, writes the
// given data to the given filename.
func CreateLogFile(filename string, data []byte) error {
	path, err := CreateReportDirectory()
	if err != nil {
		log.WithError(err).Errorf("ReportDirectory cannot be created")
		return err
	}

	finalPath := filepath.Join(path, filename)
	err = ioutil.WriteFile(finalPath, data, LogPerm)
	return err
}

// reportMap saves the output of the given commands to the specified filename.
// Function needs a directory path where the files are going to be written and
// a *SSHMeta instance to execute the commands
func reportMap(path string, reportCmds map[string]string, node *SSHMeta) {
	if node == nil {
		log.Errorf("cannot execute reportMap due invalid node instance")
		return
	}

	for cmd, logfile := range reportCmds {
		res := node.Exec(cmd, ExecOptions{SkipLog: true})
		err := ioutil.WriteFile(
			fmt.Sprintf("%s/%s", path, logfile),
			res.CombineOutput().Bytes(),
			LogPerm)
		if err != nil {
			log.WithError(err).Errorf("cannot create test results for command '%s'", cmd)
		}
	}
}

// DecodeYAMLOrJSON reads a json or yaml file and exports all documents as an
// array of interfaces. In case of an invalid path or invalid format it returns
// an error.
func DecodeYAMLOrJSON(path string) ([]interface{}, error) {
	var result []interface{}
	content, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}
	d := yaml.NewYAMLOrJSONDecoder(bytes.NewReader(content), 4096)
	for {
		var ext interface{}
		if err := d.Decode(&ext); err != nil {
			if err == io.EOF {
				break
			}
			return nil, fmt.Errorf("cannot decode the content: %s", err)
		}
		result = append(result, ext)
	}
	return result, nil
}

// ManifestGet returns the full path of the given manifest corresponding to the
// Kubernetes version being tested, if such a manifest exists, if not it
// returns the global manifest file.
func ManifestGet(manifestFilename string) string {
	fullPath := filepath.Join(manifestsPath, GetCurrentK8SEnv(), manifestFilename)
	_, err := os.Stat(fullPath)
	if err == nil {
		return filepath.Join(BasePath, fullPath)
	}
	return filepath.Join(BasePath, "k8sT", "manifests", manifestFilename)
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2020 mogemimi. Distributed under the MIT license.

package main

import (
	"bufio"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"

	"github.com/pkg/errors"
)

func main() {
	var options struct {
		all bool
	}

	flag.BoolVar(&options.all, "all", false, "all file")
	flag.Parse()

	files, err := getFiles(flag.Args())
	if err != nil {
		log.Fatalln(err)
	}

	if options.all {
		if s, err := os.Stat("./include/Pomdog"); err != nil {
			log.Fatalln(err)
		} else if !s.IsDir() {
			log.Fatalln("include/Pomdog is not directory")
		}

		dirs := []string{
			"examples/*/*/*.hpp",
			"examples/*/*/*.cpp",
			"examples/*/*/*.mm",
			"examples/*/*/*/*.hpp",
			"examples/*/*/*/*.cpp",
			"include/Pomdog/*.hpp",
			"include/Pomdog/*/*.hpp",
			"include/Pomdog/*/*/*.hpp",
			"include/Pomdog/*/*/*/*.hpp",
			"src/*/*.hpp",
			"src/*/*.cpp",
			"src/*/*.mm",
			"src/*/*/*.hpp",
			"src/*/*/*.cpp",
			"src/*/*/*.mm",
			"src/*/*/*/*.hpp",
			"src/*/*/*/*.cpp",
			"src/*/*/*/*.mm",
			"src/*/*/*/*/*.hpp",
			"src/*/*/*/*/*.cpp",
			"src/*/*/*/*/*.glsl",
			"src/*/*/*/*/*.hlsl",
			"src/*/*/*/*/*.metal",
			"test/*.cpp",
			"test/*/*.hpp",
			"test/*/*.cpp",
		}

		for _, dir := range dirs {
			f, err := filepath.Glob(dir)
			if err != nil {
				log.Fatalln(err)
			}
			files = append(files, f...)
		}
	}

	for _, src := range files {
		err := refactor(src, true)
		if err != nil {
			log.Fatalln(err)
		}
	}
}

func getFiles(args []string) (files []string, err error) {
	for _, src := range args {
		stat, err := os.Stat(src)
		if err != nil {
			return nil, errors.Wrapf(err, "invalid argument \"%s\"", src)
		}
		if stat.IsDir() {
			err := filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
				if err != nil {
					return errors.Wrapf(err, "failed to walk directory \"%s\"", path)
				}
				if !info.IsDir() && info.Mode().IsRegular() && isSourceFile(path) {
					files = append(files, path)
				}
				return nil
			})
			if err != nil {
				return files, errors.Wrapf(err, "failed to get file list \"%s\"", src)
			}
		} else if stat.Mode().IsRegular() {
			files = append(files, src)
		}
	}
	return files, nil
}

func isSourceFile(path string) bool {
	ext := filepath.Ext(path)
	matchers := []string{
		".cpp",
		".hpp",
		".mm",
		".m",
		".h",
		".c",
		".glsl",
		".hlsl",
		".metal",
		".inc",
		".cmake",
	}
	for _, m := range matchers {
		if m == ext {
			return true
		}
	}
	return false
}

func removeBOM(content string) string {
	return strings.TrimLeft(content, "\xef\xbb\xbf")
}

func replaceCRLFWithLF(content string) string {
	return strings.Replace(content, "\r\n", "\n", -1)
}

func replaceHardTabsWithWhiteSpaces(content string) string {
	return strings.Replace(content, "\t", "    ", -1)
}

func removeUnnecessaryWhitespace(content string) string {
	lines := strings.Split(content, "\n")
	for i, line := range lines {
		lines[i] = strings.TrimRight(line, " \t")
	}
	return strings.Join(lines, "\n")
}

func removeWhitespaceFromEOF(content string) string {
	return strings.TrimRight(content, " \n\t") + "\n"
}

func refactor(file string, inplaceEdit bool) error {
	dat, err := ioutil.ReadFile(file)
	if err != nil {
		return errors.Wrapf(err, "failed to read a file \"%s\"", file)
	}

	content := string(dat)
	content = removeBOM(content)
	content = replaceCRLFWithLF(content)
	content = replaceHardTabsWithWhiteSpaces(content)
	content = removeUnnecessaryWhitespace(content)
	content = removeWhitespaceFromEOF(content)

	if !inplaceEdit {
		fmt.Println(content)
		return nil
	}

	f, err := os.Create(file)
	if err != nil {
		return errors.Wrapf(err, "failed to create a file \"%s\"", file)
	}
	defer f.Close()

	w := bufio.NewWriter(f)
	defer w.Flush()

	if _, err := w.WriteString(content); err != nil {
		return errors.Wrapf(err, "failed to write a file \"%s\"", file)
	}

	return nil
}
<commit_msg>Minor refactor<commit_after>// Copyright (c) 2013-2020 mogemimi. Distributed under the MIT license.

package main

import (
	"bufio"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"

	"github.com/pkg/errors"
)

func main() {
	var options struct {
		all bool
	}

	flag.BoolVar(&options.all, "all", false, "all file")
	flag.Parse()

	files, err := getFiles(flag.Args())
	if err != nil {
		log.Fatalln(err)
	}

	if options.all {
		if s, err := os.Stat("./include/Pomdog"); err != nil {
			log.Fatalln(err)
		} else if !s.IsDir() {
			log.Fatalln("include/Pomdog is not directory")
		}

		dirs := []string{
			"examples/*/*/*.hpp",
			"examples/*/*/*.cpp",
			"examples/*/*/*.mm",
			"examples/*/*/*/*.hpp",
			"examples/*/*/*/*.cpp",
			"examples/FeatureShowcase/Content/Shaders/*.glsl",
			"examples/FeatureShowcase/Content/Shaders/*.hlsl",
			"examples/FeatureShowcase/Content/Shaders/*.metal",
			"examples/QuickStart/Content/*.glsl",
			"examples/QuickStart/Content/*.hlsl",
			"examples/QuickStart/Content/*.metal",
			"include/Pomdog/*.hpp",
			"include/Pomdog/*/*.hpp",
			"include/Pomdog/*/*/*.hpp",
			"include/Pomdog/*/*/*/*.hpp",
			"src/*/*.hpp",
			"src/*/*.cpp",
			"src/*/*.mm",
			"src/*/*/*.hpp",
			"src/*/*/*.cpp",
			"src/*/*/*.mm",
			"src/*/*/*/*.hpp",
			"src/*/*/*/*.cpp",
			"src/*/*/*/*.mm",
			"src/*/*/*/*/*.hpp",
			"src/*/*/*/*/*.cpp",
			"src/*/*/*/*/*.glsl",
			"src/*/*/*/*/*.hlsl",
			"src/*/*/*/*/*.metal",
			"test/*.cpp",
			"test/*/*.hpp",
			"test/*/*.cpp",
		}

		for _, dir := range dirs {
			f, err := filepath.Glob(dir)
			if err != nil {
				log.Fatalln(err)
			}
			files = append(files, f...)
		}
	}

	for _, src := range files {
		err := refactor(src, true)
		if err != nil {
			log.Fatalln(err)
		}
	}
}

func getFiles(args []string) (files []string, err error) {
	for _, src := range args {
		stat, err := os.Stat(src)
		if err != nil {
			return nil, errors.Wrapf(err, "invalid argument \"%s\"", src)
		}
		if stat.IsDir() {
			err := filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
				if err != nil {
					return errors.Wrapf(err, "failed to walk directory \"%s\"", path)
				}
				if !info.IsDir() && info.Mode().IsRegular() && isSourceFile(path) {
					files = append(files, path)
				}
				return nil
			})
			if err != nil {
				return files, errors.Wrapf(err, "failed to get file list \"%s\"", src)
			}
		} else if stat.Mode().IsRegular() {
			files = append(files, src)
		}
	}
	return files, nil
}

func isSourceFile(path string) bool {
	ext := filepath.Ext(path)
	matchers := []string{
		".cpp",
		".hpp",
		".mm",
		".m",
		".h",
		".c",
		".glsl",
		".hlsl",
		".metal",
		".inc",
		".cmake",
	}
	for _, m := range matchers {
		if m == ext {
			return true
		}
	}
	return false
}

func removeBOM(content string) string {
	return strings.TrimLeft(content, "\xef\xbb\xbf")
}

func replaceCRLFWithLF(content string) string {
	return strings.Replace(content, "\r\n", "\n", -1)
}

func replaceHardTabsWithWhiteSpaces(content string) string {
	return strings.Replace(content, "\t", "    ", -1)
}

func removeUnnecessaryWhitespace(content string) string {
	lines := strings.Split(content, "\n")
	for i, line := range lines {
		lines[i] = strings.TrimRight(line, " \t")
	}
	return strings.Join(lines, "\n")
}

func removeWhitespaceFromEOF(content string) string {
	return strings.TrimRight(content, " \n\t") + "\n"
}

func refactor(file string, inplaceEdit bool) error {
	dat, err := ioutil.ReadFile(file)
	if err != nil {
		return errors.Wrapf(err, "failed to read a file \"%s\"", file)
	}

	content := string(dat)
	content = removeBOM(content)
	content = replaceCRLFWithLF(content)
	content = replaceHardTabsWithWhiteSpaces(content)
	content = removeUnnecessaryWhitespace(content)
	content = removeWhitespaceFromEOF(content)

	if !inplaceEdit {
		fmt.Println(content)
		return nil
	}

	f, err := os.Create(file)
	if err != nil {
		return errors.Wrapf(err, "failed to create a file \"%s\"", file)
	}
	defer f.Close()

	w := bufio.NewWriter(f)
	defer w.Flush()

	if _, err := w.WriteString(content); err != nil {
		return errors.Wrapf(err, "failed to write a file \"%s\"", file)
	}

	return nil
}
<|endoftext|>


<commit_before>package rest

import (
	"encoding/json"
	"log"
	"net/http"

	"github.com/krix38/ScorchedGo/properties"
)

type connectionInfo struct {
	signedIn bool
}

func ConnectionStatus(w http.ResponseWriter, r *http.Request) {
	if r.Method == http.MethodGet {
		w.Header().Set("Content-Type", "application/json")
		/* TODO: check connection status */
		connectionInfoStruct := connectionInfo{signedIn: false}
		connInfo, err := json.Marshal(connectionInfoStruct)
		if err != nil {
			log.Fatal(properties.Messages.DebugJsonParseFail + ": connectionInfoStruct")
		}
		w.Write(connInfo)
	} else {
		http.Error(w, properties.Messages.BadMethod + ": " + r.Method, http.StatusBadRequest)
	}
}
<commit_msg>added rest handlers generating clojure<commit_after>package rest

import (
	"encoding/json"
	"log"
	"net/http"

	"github.com/krix38/ScorchedGo/properties"
)

type connectionInfo struct {
	signedIn bool
}

var ConnectionStatus = createRestHandler(connectionStatus, []string{"GET"})

func connectionStatus() interface{}{
		/* TODO: check connection status */
		return connectionInfo{signedIn: false}
}

func createRestHandler(handler func() interface{}, acceptedMethods []string) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		for _, method := range acceptedMethods {
			if r.Method == method {
				w.Header().Set("Content-Type", "application/json")
				object := handler()
				jsonObject, err := json.Marshal(object)
				if err != nil {
					log.Fatal(properties.Messages.DebugJsonParseFail)
				}
				w.Write(jsonObject)
				return
			}
		}
		http.Error(w, properties.Messages.BadMethod+": "+r.Method, http.StatusBadRequest)
	}
}
<|endoftext|>


<commit_before>package zfs

import (
	"bytes"
	"fmt"
	"io"
	"os/exec"
	"regexp"
	"strconv"
	"strings"
)

type command struct {
	Command string
	Stdin   io.Reader
	Stdout  io.Writer
}

func (c *command) Run(arg ...string) ([][]string, error) {

	cmd := exec.Command(c.Command, arg...)

	var stdout, stderr bytes.Buffer

	if c.Stdout == nil {
		cmd.Stdout = &stdout
	} else {
		cmd.Stdout = c.Stdout
	}

	if c.Stdin != nil {
		cmd.Stdin = c.Stdin

	}
	cmd.Stderr = &stderr

	debug := strings.Join([]string{cmd.Path, strings.Join(cmd.Args, " ")}, " ")
	if logger != nil {
		logger.Log(cmd.Args)
	}
	err := cmd.Run()

	if err != nil {
		return nil, &Error{
			Err:    err,
			Debug:  debug,
			Stderr: stderr.String(),
		}
	}

	// assume if you passed in something for stdout, that you know what to do with it
	if c.Stdout != nil {
		return nil, nil
	}

	lines := strings.Split(stdout.String(), "\n")

	//last line is always blank
	lines = lines[0 : len(lines)-1]
	output := make([][]string, len(lines))

	for i, l := range lines {
		output[i] = strings.Fields(l)
	}

	return output, nil
}

func setString(field *string, value string) {
	v := ""
	if value != "-" {
		v = value
	}
	*field = v
}

func setUint(field *uint64, value string) error {
	var v uint64
	if value != "-" {
		var err error
		v, err = strconv.ParseUint(value, 10, 64)
		if err != nil {
			return err
		}
	}
	*field = v
	return nil
}

func (ds *Dataset) parseLine(line []string) error {
	prop := line[1]
	val := line[2]

	var err error

	switch prop {
	case "available":
		err = setUint(&ds.Avail, val)
	case "compression":
		setString(&ds.Compression, val)
	case "mountpoint":
		setString(&ds.Mountpoint, val)
	case "quota":
		err = setUint(&ds.Quota, val)
	case "type":
		setString(&ds.Type, val)
	case "origin":
		setString(&ds.Origin, val)
	case "used":
		err = setUint(&ds.Used, val)
	case "volsize":
		err = setUint(&ds.Volsize, val)
	case "written":
		err = setUint(&ds.Written, val)
	case "logicalused":
		err = setUint(&ds.Logicalused, val)
	}
	return err
}

/*
 * from zfs diff`s escape function:
 *
 * Prints a file name out a character at a time.  If the character is
 * not in the range of what we consider "printable" ASCII, display it
 * as an escaped 3-digit octal value.  ASCII values less than a space
 * are all control characters and we declare the upper end as the
 * DELete character.  This also is the last 7-bit ASCII character.
 * We choose to treat all 8-bit ASCII as not printable for this
 * application.
 */
func unescapeFilepath(path string) (string, error) {
	buf := make([]byte, 0, len(path))
	llen := len(path)
	for i := 0; i < llen; {
		if path[i] == '\\' {
			if llen < i+4 {
				return "", fmt.Errorf("Invalid octal code: too short")
			}
			octalCode := path[(i + 1):(i + 4)]
			val, err := strconv.ParseUint(octalCode, 8, 8)
			if err != nil {
				return "", fmt.Errorf("Invalid octal code: %v", err)
			}
			buf = append(buf, byte(val))
			i += 4
		} else {
			buf = append(buf, path[i])
			i++
		}
	}
	return string(buf), nil
}

var changeTypeMap = map[string]ChangeType{
	"-": Removed,
	"+": Created,
	"M": Modified,
	"R": Renamed,
}
var inodeTypeMap = map[string]InodeType{
	"B": BlockDevice,
	"C": CharacterDevice,
	"/": Directory,
	">": Door,
	"|": NamedPipe,
	"@": SymbolicLink,
	"P": EventPort,
	"=": Socket,
	"F": File,
}

// matches (+1) or (-1)
var referenceCountRegex = regexp.MustCompile("\\(([+-]\\d+?)\\)")

func parseReferenceCount(field string) (int, error) {
	matches := referenceCountRegex.FindStringSubmatch(field)
	if matches == nil {
		return 0, fmt.Errorf("Regexp does not match")
	}
	return strconv.Atoi(matches[1])
}

func parseInodeChange(line []string) (*InodeChange, error) {
	llen := len(line)
	if llen < 1 {
		return nil, fmt.Errorf("Empty line passed")
	}

	changeType := changeTypeMap[line[0]]
	if changeType == 0 {
		return nil, fmt.Errorf("Unknown change type '%s'", line[0])
	}

	switch changeType {
	case Renamed:
		if llen != 4 {
			return nil, fmt.Errorf("Mismatching number of fields: expect 4, got: %d", llen)
		}
	case Modified:
		if llen != 4 && llen != 3 {
			return nil, fmt.Errorf("Mismatching number of fields: expect 3..4, got: %d", llen)
		}
	default:
		if llen != 3 {
			return nil, fmt.Errorf("Mismatching number of fields: expect 3, got: %d", llen)
		}
	}

	inodeType := inodeTypeMap[line[1]]
	if inodeType == 0 {
		return nil, fmt.Errorf("Unknown inode type '%s'", line[1])
	}

	path, err := unescapeFilepath(line[2])
	if err != nil {
		return nil, fmt.Errorf("Failed to parse filename: %v", err)
	}

	var newPath string
	var referenceCount int
	switch changeType {
	case Renamed:
		newPath, err = unescapeFilepath(line[3])
		if err != nil {
			return nil, fmt.Errorf("Failed to parse filename: %v", err)
		}
	case Modified:
		if llen == 4 {
			referenceCount, err = parseReferenceCount(line[3])
			if err != nil {
				return nil, fmt.Errorf("Failed to parse reference count: %v", err)
			}
		}
	default:
		newPath = ""
	}

	return &InodeChange{
		changeType,
		inodeType,
		path,
		newPath,
		referenceCount,
	}, nil
}

// example input
//M       /       /testpool/bar/
//+       F       /testpool/bar/hello.txt
//M       /       /testpool/bar/hello.txt (+1)
//M       /       /testpool/bar/hello-hardlink
func parseInodeChanges(lines [][]string) ([]*InodeChange, error) {
	changes := make([]*InodeChange, len(lines))

	for i, line := range lines {
		c, err := parseInodeChange(line)
		if err != nil {
			return nil, fmt.Errorf("Failed to parse line %d of zfs diff: %v, got: '%s'", i, err, line)
		}
		changes[i] = c
	}
	return changes, nil
}

func listByType(t, filter string) ([]*Dataset, error) {
	args := []string{"get", "all", "-t", t, "-rHp"}
	if filter != "" {
		args = append(args, filter)
	}
	out, err := zfs(args...)
	if err != nil {
		return nil, err
	}

	var datasets []*Dataset

	name := ""
	var ds *Dataset
	for _, line := range out {
		if name != line[0] {
			name = line[0]
			ds = &Dataset{Name: name}
			datasets = append(datasets, ds)
		}
		if err := ds.parseLine(line); err != nil {
			return nil, err
		}
	}

	return datasets, nil
}

func propsSlice(properties map[string]string) []string {
	args := make([]string, 0, len(properties)*3)
	for k, v := range properties {
		args = append(args, "-o")
		args = append(args, fmt.Sprintf("%s=%s", k, v))
	}
	return args
}

func (z *Zpool) parseLine(line []string) error {
	prop := line[1]
	val := line[2]

	var err error

	switch prop {
	case "health":
		setString(&z.Health, val)
	case "allocated":
		err = setUint(&z.Allocated, val)
	case "size":
		err = setUint(&z.Size, val)
	case "free":
		err = setUint(&z.Free, val)
	}
	return err
}
<commit_msg>use named struct fields<commit_after>package zfs

import (
	"bytes"
	"fmt"
	"io"
	"os/exec"
	"regexp"
	"strconv"
	"strings"
)

type command struct {
	Command string
	Stdin   io.Reader
	Stdout  io.Writer
}

func (c *command) Run(arg ...string) ([][]string, error) {

	cmd := exec.Command(c.Command, arg...)

	var stdout, stderr bytes.Buffer

	if c.Stdout == nil {
		cmd.Stdout = &stdout
	} else {
		cmd.Stdout = c.Stdout
	}

	if c.Stdin != nil {
		cmd.Stdin = c.Stdin

	}
	cmd.Stderr = &stderr

	debug := strings.Join([]string{cmd.Path, strings.Join(cmd.Args, " ")}, " ")
	if logger != nil {
		logger.Log(cmd.Args)
	}
	err := cmd.Run()

	if err != nil {
		return nil, &Error{
			Err:    err,
			Debug:  debug,
			Stderr: stderr.String(),
		}
	}

	// assume if you passed in something for stdout, that you know what to do with it
	if c.Stdout != nil {
		return nil, nil
	}

	lines := strings.Split(stdout.String(), "\n")

	//last line is always blank
	lines = lines[0 : len(lines)-1]
	output := make([][]string, len(lines))

	for i, l := range lines {
		output[i] = strings.Fields(l)
	}

	return output, nil
}

func setString(field *string, value string) {
	v := ""
	if value != "-" {
		v = value
	}
	*field = v
}

func setUint(field *uint64, value string) error {
	var v uint64
	if value != "-" {
		var err error
		v, err = strconv.ParseUint(value, 10, 64)
		if err != nil {
			return err
		}
	}
	*field = v
	return nil
}

func (ds *Dataset) parseLine(line []string) error {
	prop := line[1]
	val := line[2]

	var err error

	switch prop {
	case "available":
		err = setUint(&ds.Avail, val)
	case "compression":
		setString(&ds.Compression, val)
	case "mountpoint":
		setString(&ds.Mountpoint, val)
	case "quota":
		err = setUint(&ds.Quota, val)
	case "type":
		setString(&ds.Type, val)
	case "origin":
		setString(&ds.Origin, val)
	case "used":
		err = setUint(&ds.Used, val)
	case "volsize":
		err = setUint(&ds.Volsize, val)
	case "written":
		err = setUint(&ds.Written, val)
	case "logicalused":
		err = setUint(&ds.Logicalused, val)
	}
	return err
}

/*
 * from zfs diff`s escape function:
 *
 * Prints a file name out a character at a time.  If the character is
 * not in the range of what we consider "printable" ASCII, display it
 * as an escaped 3-digit octal value.  ASCII values less than a space
 * are all control characters and we declare the upper end as the
 * DELete character.  This also is the last 7-bit ASCII character.
 * We choose to treat all 8-bit ASCII as not printable for this
 * application.
 */
func unescapeFilepath(path string) (string, error) {
	buf := make([]byte, 0, len(path))
	llen := len(path)
	for i := 0; i < llen; {
		if path[i] == '\\' {
			if llen < i+4 {
				return "", fmt.Errorf("Invalid octal code: too short")
			}
			octalCode := path[(i + 1):(i + 4)]
			val, err := strconv.ParseUint(octalCode, 8, 8)
			if err != nil {
				return "", fmt.Errorf("Invalid octal code: %v", err)
			}
			buf = append(buf, byte(val))
			i += 4
		} else {
			buf = append(buf, path[i])
			i++
		}
	}
	return string(buf), nil
}

var changeTypeMap = map[string]ChangeType{
	"-": Removed,
	"+": Created,
	"M": Modified,
	"R": Renamed,
}
var inodeTypeMap = map[string]InodeType{
	"B": BlockDevice,
	"C": CharacterDevice,
	"/": Directory,
	">": Door,
	"|": NamedPipe,
	"@": SymbolicLink,
	"P": EventPort,
	"=": Socket,
	"F": File,
}

// matches (+1) or (-1)
var referenceCountRegex = regexp.MustCompile("\\(([+-]\\d+?)\\)")

func parseReferenceCount(field string) (int, error) {
	matches := referenceCountRegex.FindStringSubmatch(field)
	if matches == nil {
		return 0, fmt.Errorf("Regexp does not match")
	}
	return strconv.Atoi(matches[1])
}

func parseInodeChange(line []string) (*InodeChange, error) {
	llen := len(line)
	if llen < 1 {
		return nil, fmt.Errorf("Empty line passed")
	}

	changeType := changeTypeMap[line[0]]
	if changeType == 0 {
		return nil, fmt.Errorf("Unknown change type '%s'", line[0])
	}

	switch changeType {
	case Renamed:
		if llen != 4 {
			return nil, fmt.Errorf("Mismatching number of fields: expect 4, got: %d", llen)
		}
	case Modified:
		if llen != 4 && llen != 3 {
			return nil, fmt.Errorf("Mismatching number of fields: expect 3..4, got: %d", llen)
		}
	default:
		if llen != 3 {
			return nil, fmt.Errorf("Mismatching number of fields: expect 3, got: %d", llen)
		}
	}

	inodeType := inodeTypeMap[line[1]]
	if inodeType == 0 {
		return nil, fmt.Errorf("Unknown inode type '%s'", line[1])
	}

	path, err := unescapeFilepath(line[2])
	if err != nil {
		return nil, fmt.Errorf("Failed to parse filename: %v", err)
	}

	var newPath string
	var referenceCount int
	switch changeType {
	case Renamed:
		newPath, err = unescapeFilepath(line[3])
		if err != nil {
			return nil, fmt.Errorf("Failed to parse filename: %v", err)
		}
	case Modified:
		if llen == 4 {
			referenceCount, err = parseReferenceCount(line[3])
			if err != nil {
				return nil, fmt.Errorf("Failed to parse reference count: %v", err)
			}
		}
	default:
		newPath = ""
	}

	return &InodeChange{
		Change:               changeType,
		Type:                 inodeType,
		Path:                 path,
		NewPath:              newPath,
		ReferenceCountChange: referenceCount,
	}, nil
}

// example input
//M       /       /testpool/bar/
//+       F       /testpool/bar/hello.txt
//M       /       /testpool/bar/hello.txt (+1)
//M       /       /testpool/bar/hello-hardlink
func parseInodeChanges(lines [][]string) ([]*InodeChange, error) {
	changes := make([]*InodeChange, len(lines))

	for i, line := range lines {
		c, err := parseInodeChange(line)
		if err != nil {
			return nil, fmt.Errorf("Failed to parse line %d of zfs diff: %v, got: '%s'", i, err, line)
		}
		changes[i] = c
	}
	return changes, nil
}

func listByType(t, filter string) ([]*Dataset, error) {
	args := []string{"get", "all", "-t", t, "-rHp"}
	if filter != "" {
		args = append(args, filter)
	}
	out, err := zfs(args...)
	if err != nil {
		return nil, err
	}

	var datasets []*Dataset

	name := ""
	var ds *Dataset
	for _, line := range out {
		if name != line[0] {
			name = line[0]
			ds = &Dataset{Name: name}
			datasets = append(datasets, ds)
		}
		if err := ds.parseLine(line); err != nil {
			return nil, err
		}
	}

	return datasets, nil
}

func propsSlice(properties map[string]string) []string {
	args := make([]string, 0, len(properties)*3)
	for k, v := range properties {
		args = append(args, "-o")
		args = append(args, fmt.Sprintf("%s=%s", k, v))
	}
	return args
}

func (z *Zpool) parseLine(line []string) error {
	prop := line[1]
	val := line[2]

	var err error

	switch prop {
	case "health":
		setString(&z.Health, val)
	case "allocated":
		err = setUint(&z.Allocated, val)
	case "size":
		err = setUint(&z.Size, val)
	case "free":
		err = setUint(&z.Free, val)
	}
	return err
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"strings"
	"text/template"
)

var funcMap = template.FuncMap{
	"ExportName":             exportName,
	"PkgName":                pkgName,
	"ToolVersion":            toolVersion,
	"MapType":                mapType,
	"MapTypeSetter":          mapTypeSetter,
	"MapTypeGetter":          mapTypeGetter,
	"TrimQuote":              trimQuote,
	"DBusName":               dbusName,
	"DBusPath":               dbusPath,
	"ConvertToDBusInterface": convertToDBusInterface,
	"GetKeyType":             getKeyType,
	"GetDefaultValue":        getDefaultValue,
	"Title":                  strings.Title,
	"Predefined":             predefined,
	"GetRangeType":           getRangeType,
	"String":                 toString,
}

func predefined() []string {
	return []string{"int16", "uint16", "int32", "uint32", "int64", "uint64", "double"}
}

func mustParse(tpl *template.Template, cont string) *template.Template {
	return template.Must(tpl.Parse(cont))
}

func normalize(id string) string {
	names := strings.Split(id, "-")
	l := len(names)
	normalizedNames := make([]string, l)
	for i, name := range names {
		normalizedNames[i] = strings.Title(name)
	}
	normalizedID := strings.Join(normalizedNames, "")
	return normalizedID
}

func exportName(id string) string {
	names := strings.Split(id, ".")
	return normalize(names[len(names)-1])
}

var (
	__VERSION__ = "v0.1.0"
)

func pkgName() string {
	return *_pkgName
}

func toolVersion() string {
	return __VERSION__
}

var TypeMap = map[string]string{
	"s":  "string",
	"o":  "dbus.ObjectPath",
	"g":  "string", // dbus.Signature
	"b":  "bool",
	"y":  "byte",
	"n":  "int16",
	"q":  "uint16",
	"i":  "int32",
	"u":  "uint32",
	"x":  "int64",
	"t":  "uint64",
	"h":  "int32",
	"d":  "double",
	"as": "[]string",
	"ao": "[]dbus.ObjectPath",
	"ag": "[]string", // dbus.Signature
	"ab": "[]bool",
	"ay": "[]byte",
	"an": "[]int16",
	"aq": "[]uint16",
	"ai": "[]int32",
	"au": "[]uint32",
	"ax": "[]int64",
	"at": "[]uint64",
	"ah": "[]int32",
	"ad": "[]double",
}

// TODO: support tuple and struct
var VariantMap = map[string]string{
	"s":  "String",
	"o":  "ObjectPath",
	"g":  "Signature", // dbus.Signature
	"b":  "Boolean",
	"y":  "Byte",
	"n":  "Int16",
	"q":  "Uint16",
	"i":  "Int32",
	"u":  "Uint32",
	"x":  "Int64",
	"t":  "Uint64",
	"h":  "Int32",
	"d":  "Double",
	"as": "Strv",
	// TODO: NOT support now.
	// "ao": "[]dbus.ObjectPath",
	// "ag": "[]string", // dbus.Signature
	// "ab": "[]bool",
	// "ay": "[]byte",
	// "an": "[]int16",
	// "aq": "[]uint16",
	// "ai": "[]int32",
	// "au": "[]uint32",
	// "ax": "[]int64",
	// "at": "[]uint64",
	// "ah": "[]int32",
	// "ad": "[]double",
}

func mapType(ty string) string {
	v, ok := TypeMap[ty]
	if ok {
		return v
	}
	return ""
}

func mapTypeGetter(ty string) string {
	v, ok := VariantMap[ty]
	if ok {
		return v
	} else {
		panic(fmt.Sprintf("not support %q now", ty))
	}
	return ""
}

func mapTypeSetter(ty string) string {
	v, ok := VariantMap[ty]
	if ok {
		return v
	} else {
		panic(fmt.Sprintf("not support %q now", ty))
	}
	return ""
}

func getKeyType(k Key) string {
	if k.IsEnum() {
		return "int32"
	} else if k.IsFlags() {
		return "uint32"
	}
	return mapType(k.Type)
}

func ReadFile(filename string) string {
	c, err := ioutil.ReadFile(filename)
	if err != nil {
		panic(err)
	}
	return string(c)
}

func trimQuote(a string) string {
	return strings.Trim(a, "'")
}

func convertToDBusInterface(schemaID string) string {
	names := strings.Split(schemaID, "-")
	exportName := strings.Title(names[len(names)-1])
	names[len(names)-1] = exportName
	return strings.Join(names, "")
}

func dbusName() string {
	return *_dbusName
}

func dbusPath() string {
	return *_dbusPath
}

type Result struct {
	Value string
	Err   error
}

func getDefaultValue(schemas SchemaList, key Key) Result {
	if key.IsEnum() {
		enum := schemas.FindEnum(key.Enum)
		if enum.IsValid() {
			for _, value := range enum.Values {
				if value.Nick == trimQuote(key.Default.Value) {
					return Result{Value: exportName(enum.Id) + exportName(value.Nick)}
				}
			}
			return Result{Err: fmt.Errorf("invalid value %v", key.Default.Value)}
		}
		return Result{Err: fmt.Errorf("invalid enum id %q", key.Enum)}
	}
	return Result{Value: key.Default.Value}
}

func getRangeType(key Key) string {
	if key.IsEnum() {
		return "int32"
	} else if key.IsFlags() {
		return "uint32"
	}

	return "Range" + VariantMap[key.Type]
}

func toString(s []byte) string {
	fmt.Println(string(s))
	return string(s)
}
<commit_msg>fix wrong exported interface name.<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"strings"
	"text/template"
)

var funcMap = template.FuncMap{
	"ExportName":             exportName,
	"PkgName":                pkgName,
	"ToolVersion":            toolVersion,
	"MapType":                mapType,
	"MapTypeSetter":          mapTypeSetter,
	"MapTypeGetter":          mapTypeGetter,
	"TrimQuote":              trimQuote,
	"DBusName":               dbusName,
	"DBusPath":               dbusPath,
	"ConvertToDBusInterface": convertToDBusInterface,
	"GetKeyType":             getKeyType,
	"GetDefaultValue":        getDefaultValue,
	"Title":                  strings.Title,
	"Predefined":             predefined,
	"GetRangeType":           getRangeType,
	"String":                 toString,
}

func predefined() []string {
	return []string{"int16", "uint16", "int32", "uint32", "int64", "uint64", "double"}
}

func mustParse(tpl *template.Template, cont string) *template.Template {
	return template.Must(tpl.Parse(cont))
}

func normalize(id string) string {
	names := strings.Split(id, "-")
	l := len(names)
	normalizedNames := make([]string, l)
	for i, name := range names {
		normalizedNames[i] = strings.Title(name)
	}
	normalizedID := strings.Join(normalizedNames, "")
	return normalizedID
}

func exportName(id string) string {
	names := strings.Split(id, ".")
	return normalize(names[len(names)-1])
}

var (
	__VERSION__ = "v0.1.0"
)

func pkgName() string {
	return *_pkgName
}

func toolVersion() string {
	return __VERSION__
}

var TypeMap = map[string]string{
	"s":  "string",
	"o":  "dbus.ObjectPath",
	"g":  "string", // dbus.Signature
	"b":  "bool",
	"y":  "byte",
	"n":  "int16",
	"q":  "uint16",
	"i":  "int32",
	"u":  "uint32",
	"x":  "int64",
	"t":  "uint64",
	"h":  "int32",
	"d":  "double",
	"as": "[]string",
	"ao": "[]dbus.ObjectPath",
	"ag": "[]string", // dbus.Signature
	"ab": "[]bool",
	"ay": "[]byte",
	"an": "[]int16",
	"aq": "[]uint16",
	"ai": "[]int32",
	"au": "[]uint32",
	"ax": "[]int64",
	"at": "[]uint64",
	"ah": "[]int32",
	"ad": "[]double",
}

// TODO: support tuple and struct
var VariantMap = map[string]string{
	"s":  "String",
	"o":  "ObjectPath",
	"g":  "Signature", // dbus.Signature
	"b":  "Boolean",
	"y":  "Byte",
	"n":  "Int16",
	"q":  "Uint16",
	"i":  "Int32",
	"u":  "Uint32",
	"x":  "Int64",
	"t":  "Uint64",
	"h":  "Int32",
	"d":  "Double",
	"as": "Strv",
	// TODO: NOT support now.
	// "ao": "[]dbus.ObjectPath",
	// "ag": "[]string", // dbus.Signature
	// "ab": "[]bool",
	// "ay": "[]byte",
	// "an": "[]int16",
	// "aq": "[]uint16",
	// "ai": "[]int32",
	// "au": "[]uint32",
	// "ax": "[]int64",
	// "at": "[]uint64",
	// "ah": "[]int32",
	// "ad": "[]double",
}

func mapType(ty string) string {
	v, ok := TypeMap[ty]
	if ok {
		return v
	}
	return ""
}

func mapTypeGetter(ty string) string {
	v, ok := VariantMap[ty]
	if ok {
		return v
	} else {
		panic(fmt.Sprintf("not support %q now", ty))
	}
	return ""
}

func mapTypeSetter(ty string) string {
	v, ok := VariantMap[ty]
	if ok {
		return v
	} else {
		panic(fmt.Sprintf("not support %q now", ty))
	}
	return ""
}

func getKeyType(k Key) string {
	if k.IsEnum() {
		return "int32"
	} else if k.IsFlags() {
		return "uint32"
	}
	return mapType(k.Type)
}

func ReadFile(filename string) string {
	c, err := ioutil.ReadFile(filename)
	if err != nil {
		panic(err)
	}
	return string(c)
}

func trimQuote(a string) string {
	return strings.Trim(a, "'")
}

func convertToDBusInterface(schemaID string) string {
	names := strings.Split(schemaID, ".")
	exportName := normalize(names[len(names)-1])
	names[len(names)-1] = exportName
	return strings.Join(names, ".")
}

func dbusName() string {
	return *_dbusName
}

func dbusPath() string {
	return *_dbusPath
}

type Result struct {
	Value string
	Err   error
}

func getDefaultValue(schemas SchemaList, key Key) Result {
	if key.IsEnum() {
		enum := schemas.FindEnum(key.Enum)
		if enum.IsValid() {
			for _, value := range enum.Values {
				if value.Nick == trimQuote(key.Default.Value) {
					return Result{Value: exportName(enum.Id) + exportName(value.Nick)}
				}
			}
			return Result{Err: fmt.Errorf("invalid value %v", key.Default.Value)}
		}
		return Result{Err: fmt.Errorf("invalid enum id %q", key.Enum)}
	}
	return Result{Value: key.Default.Value}
}

func getRangeType(key Key) string {
	if key.IsEnum() {
		return "int32"
	} else if key.IsFlags() {
		return "uint32"
	}

	return "Range" + VariantMap[key.Type]
}

func toString(s []byte) string {
	fmt.Println(string(s))
	return string(s)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/freeformz/filechan"
	"log"
	"os"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"time"
)

var (
	NonWord = regexp.MustCompile("[^0-9A-Za-z_]")
)

type Slog map[string]interface{}

func (s Slog) String() string {
	var sv string
	parts := make([]string, 0, len(s))

	for k, v := range s {
		switch v.(type) {
		case time.Time: // Format times the way we want them
			sv = v.(time.Time).Format(time.RFC3339Nano)
		default: // Let Go figure out the representation
			sv = fmt.Sprintf("%v", v)
		}
		// If there is a NonWord character then need to quote the value
		if NonWord.MatchString(sv) {
			sv = fmt.Sprintf("%q", sv)
		}
		// Assemble the final part and append it to the array
		parts = append(parts, fmt.Sprintf("%s=%s", k, sv))
	}
	sort.Strings(parts)
	return strings.Join(parts, " ")
}

func (s Slog) FatalError(err error, msg interface{}) {
	s.Error(err, msg)
	os.Exit(1)
}

func (s Slog) Error(err error, msg interface{}) {
	s["at"] = time.Now()
	s["error"] = err
	s["message"] = msg
	fmt.Println(s)
	delete(s, "error")
	delete(s, "message")
}

func Fields(line string) []string {
	var insideParens = false

	return strings.FieldsFunc(line, func(s rune) bool {
		switch s {
		case '(':
			insideParens = true
		case ')':
			insideParens = false
		case ';', ':', ' ', '\n':
			return insideParens == false
		}
		return false
	})
}

func LinearSliceContainsString(ss []string, s string) bool {
	for _, v := range ss {
		if v == s {
			return true
		}
	}
	return false
}

func SliceContainsString(ss []string, s string) bool {
	if sort.StringsAreSorted(ss) {
		idx := sort.SearchStrings(ss, s)
		if idx < len(ss) && ss[idx] == s {
			return true
		}
	} else {
		return LinearSliceContainsString(ss, s)
	}
	return false
}

func Ui64toa(val uint64) string {
	return strconv.FormatUint(val, 10)
}

func Atofloat64(s string) float64 {
	val, err := strconv.ParseFloat(s, 64)
	if err != nil {
		Slog{"fn": "Atofloat64", "input": s}.FatalError(err, "converting string to float64")
	}
	return val
}

func PercentFormat(val float64) string {
	return strconv.FormatFloat(val, 'f', 2, 64)
}

func Atouint64(s string) uint64 {
	val, err := strconv.ParseUint(s, 10, 64)
	if err != nil {
		Slog{"fn": "Atouint64", "input": s}.FatalError(err, "converting string to uint64")
		log.Fatal(err)
	}
	return val
}

// Checks to see if a path exists or not
func Exists(path string) bool {
	_, err := os.Stat(path)
	return !os.IsNotExist(err)
}

// Returns the value of $env from the OS and if it's empty, returns def
func GetEnvWithDefault(env string, def string) string {
	tmp := os.Getenv(env)

	if tmp == "" {
		return def
	}

	return tmp
}

// Returns the value of $env from the OS and if it's empty, returns def
func GetEnvWithDefaultInt(env string, def int) int {
	tmp := os.Getenv(env)

	if tmp == "" {
		return def
	}

	i, err := strconv.Atoi(tmp)
	if err != nil {
		Slog{"fn": "GetEnvWithDefaultInt", "env": env, "def": def}.FatalError(err, "converting atoi")
	}
	return i
}

// Returns the value of $env from the OS and if it's empty, returns def
func GetEnvWithDefaultBool(env string, def bool) bool {
	tmp := os.Getenv(env)

	if tmp == "" {
		return def
	}

	b, err := strconv.ParseBool(tmp)
	if err != nil {
		Slog{"fn": "GetEnvWithDefaultBool", "env": env, "def": def}.FatalError(err, "converting atob")
	}
	return b
}

func GetEnvWithDefaultDuration(env string, def string) time.Duration {
	tmp := os.Getenv(env)

	if tmp == "" {
		tmp = def
	}

	d, err := time.ParseDuration(tmp)

	if err != nil {
		Slog{"fn": "GetEnvWithDefaultDuration", "env": env, "def": def}.FatalError(err, "not a valid duration")
	}

	return d
}

// Returns a slice of sorted strings from the environment or default split on ,
// So "foo,bar" returns ["bar","foo"]
func GetEnvWithDefaultStrings(env string, def string) []string {
	env = GetEnvWithDefault(env, def)
	if env == "" {
		return make([]string, 0)
	}
	tmp := strings.Split(env, ",")
	if !sort.StringsAreSorted(tmp) {
		sort.Strings(tmp)
	}
	return tmp
}

// Small wrapper to handle errors on open
func FileLineChannel(fpath string) <-chan string {
	c, err := filechan.FileLineChannel(fpath)

	if err != nil {
		Slog{"fn": "FileLineChannel", "fpath": fpath}.FatalError(err, "creating FileLineChannel")
	}

	return c
}

func FixUpName(name string) []string {
	name = strings.ToLower(name)
	name = strings.Replace(name, "(", ".", -1)
	name = strings.Replace(name, ")", "", -1)
	name = strings.Replace(name, "_", ".", -1)
	name = strings.TrimLeft(name, ".")
	return strings.Split(name, ".")
}
<commit_msg>\W == no word character<commit_after>package main

import (
	"fmt"
	"github.com/freeformz/filechan"
	"log"
	"os"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"time"
)

var (
	NonWord = regexp.MustCompile("\\W")
)

type Slog map[string]interface{}

func (s Slog) String() string {
	var sv string
	parts := make([]string, 0, len(s))

	for k, v := range s {
		switch v.(type) {
		case time.Time: // Format times the way we want them
			sv = v.(time.Time).Format(time.RFC3339Nano)
		default: // Let Go figure out the representation
			sv = fmt.Sprintf("%v", v)
		}
		// If there is a NonWord character then need to quote the value
		if NonWord.MatchString(sv) {
			sv = fmt.Sprintf("%q", sv)
		}
		// Assemble the final part and append it to the array
		parts = append(parts, fmt.Sprintf("%s=%s", k, sv))
	}
	sort.Strings(parts)
	return strings.Join(parts, " ")
}

func (s Slog) FatalError(err error, msg interface{}) {
	s.Error(err, msg)
	os.Exit(1)
}

func (s Slog) Error(err error, msg interface{}) {
	s["at"] = time.Now()
	s["error"] = err
	s["message"] = msg
	fmt.Println(s)
	delete(s, "error")
	delete(s, "message")
}

func Fields(line string) []string {
	var insideParens = false

	return strings.FieldsFunc(line, func(s rune) bool {
		switch s {
		case '(':
			insideParens = true
		case ')':
			insideParens = false
		case ';', ':', ' ', '\n':
			return insideParens == false
		}
		return false
	})
}

func LinearSliceContainsString(ss []string, s string) bool {
	for _, v := range ss {
		if v == s {
			return true
		}
	}
	return false
}

func SliceContainsString(ss []string, s string) bool {
	if sort.StringsAreSorted(ss) {
		idx := sort.SearchStrings(ss, s)
		if idx < len(ss) && ss[idx] == s {
			return true
		}
	} else {
		return LinearSliceContainsString(ss, s)
	}
	return false
}

func Ui64toa(val uint64) string {
	return strconv.FormatUint(val, 10)
}

func Atofloat64(s string) float64 {
	val, err := strconv.ParseFloat(s, 64)
	if err != nil {
		Slog{"fn": "Atofloat64", "input": s}.FatalError(err, "converting string to float64")
	}
	return val
}

func PercentFormat(val float64) string {
	return strconv.FormatFloat(val, 'f', 2, 64)
}

func Atouint64(s string) uint64 {
	val, err := strconv.ParseUint(s, 10, 64)
	if err != nil {
		Slog{"fn": "Atouint64", "input": s}.FatalError(err, "converting string to uint64")
		log.Fatal(err)
	}
	return val
}

// Checks to see if a path exists or not
func Exists(path string) bool {
	_, err := os.Stat(path)
	return !os.IsNotExist(err)
}

// Returns the value of $env from the OS and if it's empty, returns def
func GetEnvWithDefault(env string, def string) string {
	tmp := os.Getenv(env)

	if tmp == "" {
		return def
	}

	return tmp
}

// Returns the value of $env from the OS and if it's empty, returns def
func GetEnvWithDefaultInt(env string, def int) int {
	tmp := os.Getenv(env)

	if tmp == "" {
		return def
	}

	i, err := strconv.Atoi(tmp)
	if err != nil {
		Slog{"fn": "GetEnvWithDefaultInt", "env": env, "def": def}.FatalError(err, "converting atoi")
	}
	return i
}

// Returns the value of $env from the OS and if it's empty, returns def
func GetEnvWithDefaultBool(env string, def bool) bool {
	tmp := os.Getenv(env)

	if tmp == "" {
		return def
	}

	b, err := strconv.ParseBool(tmp)
	if err != nil {
		Slog{"fn": "GetEnvWithDefaultBool", "env": env, "def": def}.FatalError(err, "converting atob")
	}
	return b
}

func GetEnvWithDefaultDuration(env string, def string) time.Duration {
	tmp := os.Getenv(env)

	if tmp == "" {
		tmp = def
	}

	d, err := time.ParseDuration(tmp)

	if err != nil {
		Slog{"fn": "GetEnvWithDefaultDuration", "env": env, "def": def}.FatalError(err, "not a valid duration")
	}

	return d
}

// Returns a slice of sorted strings from the environment or default split on ,
// So "foo,bar" returns ["bar","foo"]
func GetEnvWithDefaultStrings(env string, def string) []string {
	env = GetEnvWithDefault(env, def)
	if env == "" {
		return make([]string, 0)
	}
	tmp := strings.Split(env, ",")
	if !sort.StringsAreSorted(tmp) {
		sort.Strings(tmp)
	}
	return tmp
}

// Small wrapper to handle errors on open
func FileLineChannel(fpath string) <-chan string {
	c, err := filechan.FileLineChannel(fpath)

	if err != nil {
		Slog{"fn": "FileLineChannel", "fpath": fpath}.FatalError(err, "creating FileLineChannel")
	}

	return c
}

func FixUpName(name string) []string {
	name = strings.ToLower(name)
	name = strings.Replace(name, "(", ".", -1)
	name = strings.Replace(name, ")", "", -1)
	name = strings.Replace(name, "_", ".", -1)
	name = strings.TrimLeft(name, ".")
	return strings.Split(name, ".")
}
<|endoftext|>


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

package themefiles

const AutoupdateJs = `

var Autoupdate = (function () {
    function Autoupdate() { }

    var self = this;

    /**
     * Get the currently opened web route
     * @return string The currently opened web route (e.g. "documents/Sample-Document")
     */
    var getCurrentRoute = function() {
        var url = document.location.pathname;

        // remove leading slash
        var leadingSlash = /^\//;
        url = url.replace(leadingSlash, "");

        return url;
    };

    /**
     * Get the Url for the web socket connection
     * @return string The url for the web socket connection (e.g. "ws://example.com:8080/documents/Sample-Document.ws")
     */
    var getWebSocketUrl = function() {
        routeParameter = getCurrentRoute();
        host = document.location.host;
        webSocketHandler = "/ws";

        if (routeParameter === "") {
            return "ws://" + host + "/" + "ws";
        }

        return "ws://" + host + "/" + routeParameter + ".ws";
    };

    /**
     * Execute all on change callbacks
     */
    var executeOnChangeCallbacks = function() {
        if (typeof(self.changeCallbacks) !== 'object') {
            return;
        }

        for (var callbackName in self.changeCallbacks) {
            console.log("Executing on change callback: " + callbackName);
            self.changeCallbacks[callbackName]();
        }
    };

    /**
     * Connect to the server
     * @param string webSocketUrl The url of the web-socket to connect to
     */
    var connect = function(webSocketUrl) {
        var reconnectionTimeInSeconds = 3;
        var connection = new WebSocket(webSocketUrl);

        connection.onclose = function(evt) {
            console.log("Connection closed. Trying to reconnect in " + reconnectionTimeInSeconds + " seconds.");

            setTimeout(function() {

                console.log("Reconnecting");
                connect(webSocketUrl);

            }, (reconnectionTimeInSeconds * 1000));
        };

        connection.onopen = function() {
            console.log("Connection established.")
        };

        connection.onmessage = function(evt) {

            // validate event data
            if (typeof(evt) !== 'object' || typeof(evt.data) !== 'string') {
                console.log("Invalid data from server.");
                return;
            }

            // unwrap the message
            message = JSON.parse(evt.data);

            // check if all required fields are present
            if (message === null || typeof(message) !== 'object' || typeof(message.route) !== 'string' || message.model === null || typeof(message.model) !== 'object') {
                console.log("Invalid response format.", message);
                return;
            }

            // check the model structure
            var model = message.model;
            if (typeof(model.content) !== 'string' || typeof(model.description) !== 'string' || typeof(model.title) !== 'string') {
                console.log("Cannot update the view with the given model object. Missing some required fields.", model);
                return;
            }

            // update the title
            $('title').html(model.title);
            $('.title').html(model.title);

            // update the description
            $('.description').html(model.description);

            // update the content
            $('.content').html(model.content);

            // update childs (if available)
            if (model.childs === null || typeof(model.childs) !== 'object') {

                // execute the on change callbacks
                executeOnChangeCallbacks();

                return;
            }

            /**
             * Update an existing item list entry
             * @param Element entryToUpdate The node which shall be updated
             * @param Object model The model containing values to use for the update
             */
            var updateEntry = function(entryToUpdate, model) {
                // update the title text
                $(entryToUpdate).find(".child-link:first").html(model.title);

                // update the title link
                $(entryToUpdate).find(".child-link:first").attr("href", model.relativeRoute);

                // update the description
                $(entryToUpdate).find(".child-description:first").html(model.description);
            };

            var entries = model.childs;
            var numberOfNewEntries = entries.length;

            // check if the childs container exists
            if ($(".childs").length === 0) {

                // reload the page
                document.location.reload()
                return

            }

            var existingEntries = $(".childs>.list>.child");
            var numberOfExistingEntries = existingEntries.length;

            var entryTemplate = "

";

            if (numberOfExistingEntries > numberOfNewEntries) {

                for (var x = (numberOfNewEntries-1); x < numberOfNewEntries; x++) {
                    $(existingEntries[x]).remove();
                }

            }

            // update or add
            for (var i = 0; i < numberOfNewEntries; i++) {
                var index = i + 1;
                var newEntry = entries[i];

                // get the item to update
                if (index <= numberOfExistingEntries) {

                    // update the existing entry
                    updateEntry(existingEntries[i], newEntry);

                } else {

                    // append and update a new entry
                    updateEntry($(".childs>.list").append(entryTemplate).find(".child:last"), newEntry);
                }
            }

            // execute the on change callbacks
            executeOnChangeCallbacks();

        };
    };

    Autoupdate.prototype.start = function () {

        // check if websockets are supported
        if(!window["WebSocket"]) {
            console.log("Your browser does not support WebSockets.");
            return;
        }

        // establish the connection
        connect(getWebSocketUrl());
    };

    Autoupdate.prototype.onchange = function(name, callback) {
        if (typeof(self.changeCallbacks) !== 'object') {
            self.changeCallbacks = {};
        }

        self.changeCallbacks[name] = callback;
    };

    return Autoupdate;
})();

var autoupdate = new Autoupdate();
autoupdate.start();
`
<commit_msg>Theme - Autoupdate: Fixed the updateEntry function. The href must be set using the the route attribute. relativeRoute is no longer an attribute of models.<commit_after>// Copyright 2014 Andreas Koch. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package themefiles

const AutoupdateJs = `

var Autoupdate = (function () {
    function Autoupdate() { }

    var self = this;

    /**
     * Get the currently opened web route
     * @return string The currently opened web route (e.g. "documents/Sample-Document")
     */
    var getCurrentRoute = function() {
        var url = document.location.pathname;

        // remove leading slash
        var leadingSlash = /^\//;
        url = url.replace(leadingSlash, "");

        return url;
    };

    /**
     * Get the Url for the web socket connection
     * @return string The url for the web socket connection (e.g. "ws://example.com:8080/documents/Sample-Document.ws")
     */
    var getWebSocketUrl = function() {
        routeParameter = getCurrentRoute();
        host = document.location.host;
        webSocketHandler = "/ws";

        if (routeParameter === "") {
            return "ws://" + host + "/" + "ws";
        }

        return "ws://" + host + "/" + routeParameter + ".ws";
    };

    /**
     * Execute all on change callbacks
     */
    var executeOnChangeCallbacks = function() {
        if (typeof(self.changeCallbacks) !== 'object') {
            return;
        }

        for (var callbackName in self.changeCallbacks) {
            console.log("Executing on change callback: " + callbackName);
            self.changeCallbacks[callbackName]();
        }
    };

    /**
     * Connect to the server
     * @param string webSocketUrl The url of the web-socket to connect to
     */
    var connect = function(webSocketUrl) {
        var reconnectionTimeInSeconds = 3;
        var connection = new WebSocket(webSocketUrl);

        connection.onclose = function(evt) {
            console.log("Connection closed. Trying to reconnect in " + reconnectionTimeInSeconds + " seconds.");

            setTimeout(function() {

                console.log("Reconnecting");
                connect(webSocketUrl);

            }, (reconnectionTimeInSeconds * 1000));
        };

        connection.onopen = function() {
            console.log("Connection established.")
        };

        connection.onmessage = function(evt) {

            // validate event data
            if (typeof(evt) !== 'object' || typeof(evt.data) !== 'string') {
                console.log("Invalid data from server.");
                return;
            }

            // unwrap the message
            message = JSON.parse(evt.data);

            // check if all required fields are present
            if (message === null || typeof(message) !== 'object' || typeof(message.route) !== 'string' || message.model === null || typeof(message.model) !== 'object') {
                console.log("Invalid response format.", message);
                return;
            }

            // check the model structure
            var model = message.model;
            if (typeof(model.content) !== 'string' || typeof(model.description) !== 'string' || typeof(model.title) !== 'string') {
                console.log("Cannot update the view with the given model object. Missing some required fields.", model);
                return;
            }

            // update the title
            $('title').html(model.title);
            $('.title').html(model.title);

            // update the description
            $('.description').html(model.description);

            // update the content
            $('.content').html(model.content);

            // update childs (if available)
            if (model.childs === null || typeof(model.childs) !== 'object') {

                // execute the on change callbacks
                executeOnChangeCallbacks();

                return;
            }

            /**
             * Update an existing item list entry
             * @param Element entryToUpdate The node which shall be updated
             * @param Object model The model containing values to use for the update
             */
            var updateEntry = function(entryToUpdate, model) {
                // update the title text
                $(entryToUpdate).find(".child-link:first").html(model.title);

                // update the title link
                $(entryToUpdate).find(".child-link:first").attr("href", model.route);

                // update the description
                $(entryToUpdate).find(".child-description:first").html(model.description);
            };

            var entries = model.childs;
            var numberOfNewEntries = entries.length;

            // check if the childs container exists
            if ($(".childs").length === 0) {

                // reload the page
                document.location.reload()
                return

            }

            var existingEntries = $(".childs>.list>.child");
            var numberOfExistingEntries = existingEntries.length;

            var entryTemplate = "

";

            if (numberOfExistingEntries > numberOfNewEntries) {

                for (var x = (numberOfNewEntries-1); x < numberOfNewEntries; x++) {
                    $(existingEntries[x]).remove();
                }

            }

            // update or add
            for (var i = 0; i < numberOfNewEntries; i++) {
                var index = i + 1;
                var newEntry = entries[i];

                // get the item to update
                if (index <= numberOfExistingEntries) {

                    // update the existing entry
                    updateEntry(existingEntries[i], newEntry);

                } else {

                    // append and update a new entry
                    updateEntry($(".childs>.list").append(entryTemplate).find(".child:last"), newEntry);
                }
            }

            // execute the on change callbacks
            executeOnChangeCallbacks();

        };
    };

    Autoupdate.prototype.start = function () {

        // check if websockets are supported
        if(!window["WebSocket"]) {
            console.log("Your browser does not support WebSockets.");
            return;
        }

        // establish the connection
        connect(getWebSocketUrl());
    };

    Autoupdate.prototype.onchange = function(name, callback) {
        if (typeof(self.changeCallbacks) !== 'object') {
            self.changeCallbacks = {};
        }

        self.changeCallbacks[name] = callback;
    };

    return Autoupdate;
})();

var autoupdate = new Autoupdate();
autoupdate.start();
`
<|endoftext|>


<commit_before>package storage

import (
	"fmt"
	"os"
	"os/exec"
	"os/user"
	"path/filepath"
	"strconv"
	"strings"

	"github.com/BurntSushi/toml"
	"github.com/containers/storage/pkg/idtools"
	"github.com/containers/storage/pkg/system"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
)

// ParseIDMapping takes idmappings and subuid and subgid maps and returns a storage mapping
func ParseIDMapping(UIDMapSlice, GIDMapSlice []string, subUIDMap, subGIDMap string) (*IDMappingOptions, error) {
	options := IDMappingOptions{
		HostUIDMapping: true,
		HostGIDMapping: true,
	}
	if subGIDMap == "" && subUIDMap != "" {
		subGIDMap = subUIDMap
	}
	if subUIDMap == "" && subGIDMap != "" {
		subUIDMap = subGIDMap
	}
	if len(GIDMapSlice) == 0 && len(UIDMapSlice) != 0 {
		GIDMapSlice = UIDMapSlice
	}
	if len(UIDMapSlice) == 0 && len(GIDMapSlice) != 0 {
		UIDMapSlice = GIDMapSlice
	}
	if len(UIDMapSlice) == 0 && subUIDMap == "" && os.Getuid() != 0 {
		UIDMapSlice = []string{fmt.Sprintf("0:%d:1", os.Getuid())}
	}
	if len(GIDMapSlice) == 0 && subGIDMap == "" && os.Getuid() != 0 {
		GIDMapSlice = []string{fmt.Sprintf("0:%d:1", os.Getgid())}
	}

	if subUIDMap != "" && subGIDMap != "" {
		mappings, err := idtools.NewIDMappings(subUIDMap, subGIDMap)
		if err != nil {
			return nil, errors.Wrapf(err, "failed to create NewIDMappings for uidmap=%s gidmap=%s", subUIDMap, subGIDMap)
		}
		options.UIDMap = mappings.UIDs()
		options.GIDMap = mappings.GIDs()
	}
	parsedUIDMap, err := idtools.ParseIDMap(UIDMapSlice, "UID")
	if err != nil {
		return nil, errors.Wrapf(err, "failed to create ParseUIDMap UID=%s", UIDMapSlice)
	}
	parsedGIDMap, err := idtools.ParseIDMap(GIDMapSlice, "GID")
	if err != nil {
		return nil, errors.Wrapf(err, "failed to create ParseGIDMap GID=%s", UIDMapSlice)
	}
	options.UIDMap = append(options.UIDMap, parsedUIDMap...)
	options.GIDMap = append(options.GIDMap, parsedGIDMap...)
	if len(options.UIDMap) > 0 {
		options.HostUIDMapping = false
	}
	if len(options.GIDMap) > 0 {
		options.HostGIDMapping = false
	}
	return &options, nil
}

// GetRootlessRuntimeDir returns the runtime directory when running as non root
func GetRootlessRuntimeDir(rootlessUid int) (string, error) {
	runtimeDir := os.Getenv("XDG_RUNTIME_DIR")

	if runtimeDir != "" {
		return runtimeDir, nil
	}
	tmpDir := fmt.Sprintf("/run/user/%d", rootlessUid)
	st, err := system.Stat(tmpDir)
	if err == nil && int(st.UID()) == os.Getuid() && st.Mode()&0700 == 0700 && st.Mode()&0066 == 0000 {
		return tmpDir, nil
	}
	tmpDir = fmt.Sprintf("%s/%d", os.TempDir(), rootlessUid)
	if err := os.MkdirAll(tmpDir, 0700); err != nil {
		logrus.Errorf("failed to create %s: %v", tmpDir, err)
	} else {
		return tmpDir, nil
	}
	home, err := homeDir()
	if err != nil {
		return "", errors.Wrapf(err, "neither XDG_RUNTIME_DIR nor HOME was set non-empty")
	}
	resolvedHome, err := filepath.EvalSymlinks(home)
	if err != nil {
		return "", errors.Wrapf(err, "cannot resolve %s", home)
	}
	return filepath.Join(resolvedHome, "rundir"), nil
}

// getRootlessDirInfo returns the parent path of where the storage for containers and
// volumes will be in rootless mode
func getRootlessDirInfo(rootlessUid int) (string, string, error) {
	rootlessRuntime, err := GetRootlessRuntimeDir(rootlessUid)
	if err != nil {
		return "", "", err
	}

	dataDir := os.Getenv("XDG_DATA_HOME")
	if dataDir == "" {
		home, err := homeDir()
		if err != nil {
			return "", "", errors.Wrapf(err, "neither XDG_DATA_HOME nor HOME was set non-empty")
		}
		// runc doesn't like symlinks in the rootfs path, and at least
		// on CoreOS /home is a symlink to /var/home, so resolve any symlink.
		resolvedHome, err := filepath.EvalSymlinks(home)
		if err != nil {
			return "", "", errors.Wrapf(err, "cannot resolve %s", home)
		}
		dataDir = filepath.Join(resolvedHome, ".local", "share")
	}
	return dataDir, rootlessRuntime, nil
}

// getRootlessStorageOpts returns the storage opts for containers running as non root
func getRootlessStorageOpts(rootlessUid int) (StoreOptions, error) {
	var opts StoreOptions

	dataDir, rootlessRuntime, err := getRootlessDirInfo(rootlessUid)
	if err != nil {
		return opts, err
	}
	opts.RunRoot = rootlessRuntime
	opts.GraphRoot = filepath.Join(dataDir, "containers", "storage")
	if path, err := exec.LookPath("fuse-overlayfs"); err == nil {
		opts.GraphDriverName = "overlay"
		opts.GraphDriverOptions = []string{fmt.Sprintf("overlay.mount_program=%s", path)}
	} else {
		opts.GraphDriverName = "vfs"
	}
	return opts, nil
}

type tomlOptionsConfig struct {
	MountProgram string `toml:"mount_program"`
}

func getTomlStorage(storeOptions *StoreOptions) *tomlConfig {
	config := new(tomlConfig)

	config.Storage.Driver = storeOptions.GraphDriverName
	config.Storage.RunRoot = storeOptions.RunRoot
	config.Storage.GraphRoot = storeOptions.GraphRoot
	for _, i := range storeOptions.GraphDriverOptions {
		s := strings.Split(i, "=")
		if s[0] == "overlay.mount_program" {
			config.Storage.Options.MountProgram = s[1]
		}
	}

	return config
}

func getRootlessUID() int {
	uidEnv := os.Getenv("_CONTAINERS_ROOTLESS_UID")
	if uidEnv != "" {
		u, _ := strconv.Atoi(uidEnv)
		return u
	}
	return os.Geteuid()
}

// DefaultStoreOptionsAutoDetectUID returns the default storage ops for containers
func DefaultStoreOptionsAutoDetectUID() (StoreOptions, error) {
	uid := getRootlessUID()
	return DefaultStoreOptions(uid != 0, uid)
}

// DefaultStoreOptions returns the default storage ops for containers
func DefaultStoreOptions(rootless bool, rootlessUid int) (StoreOptions, error) {
	var (
		defaultRootlessRunRoot   string
		defaultRootlessGraphRoot string
		err                      error
	)
	storageOpts := defaultStoreOptions
	if rootless && rootlessUid != 0 {
		storageOpts, err = getRootlessStorageOpts(rootlessUid)
		if err != nil {
			return storageOpts, err
		}
	}

	storageConf, err := DefaultConfigFile(rootless && rootlessUid != 0)
	if err != nil {
		return storageOpts, err
	}
	_, err = os.Stat(storageConf)
	if err != nil && !os.IsNotExist(err) {
		return storageOpts, errors.Wrapf(err, "cannot stat %s", storageConf)
	}
	if err == nil {
		defaultRootlessRunRoot = storageOpts.RunRoot
		defaultRootlessGraphRoot = storageOpts.GraphRoot
		storageOpts = StoreOptions{}
		ReloadConfigurationFile(storageConf, &storageOpts)
	}

	if rootless && rootlessUid != 0 {
		if err == nil {
			// If the file did not specify a graphroot or runroot,
			// set sane defaults so we don't try and use root-owned
			// directories
			if storageOpts.RunRoot == "" {
				storageOpts.RunRoot = defaultRootlessRunRoot
			}
			if storageOpts.GraphRoot == "" {
				storageOpts.GraphRoot = defaultRootlessGraphRoot
			}
		} else {
			if err := os.MkdirAll(filepath.Dir(storageConf), 0755); err != nil {
				return storageOpts, errors.Wrapf(err, "cannot make directory %s", filepath.Dir(storageConf))
			}
			file, err := os.OpenFile(storageConf, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
			if err != nil {
				return storageOpts, errors.Wrapf(err, "cannot open %s", storageConf)
			}

			tomlConfiguration := getTomlStorage(&storageOpts)
			defer file.Close()
			enc := toml.NewEncoder(file)
			if err := enc.Encode(tomlConfiguration); err != nil {
				os.Remove(storageConf)

				return storageOpts, errors.Wrapf(err, "failed to encode %s", storageConf)
			}
		}
	}
	return storageOpts, nil
}

func homeDir() (string, error) {
	home := os.Getenv("HOME")
	if home == "" {
		usr, err := user.Current()
		if err != nil {
			return "", errors.Wrapf(err, "neither XDG_RUNTIME_DIR nor HOME was set non-empty")
		}
		home = usr.HomeDir
	}
	return home, nil
}
<commit_msg>Move runroot containers storage into containers directory<commit_after>package storage

import (
	"fmt"
	"os"
	"os/exec"
	"os/user"
	"path/filepath"
	"strconv"
	"strings"

	"github.com/BurntSushi/toml"
	"github.com/containers/storage/pkg/idtools"
	"github.com/containers/storage/pkg/system"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
)

// ParseIDMapping takes idmappings and subuid and subgid maps and returns a storage mapping
func ParseIDMapping(UIDMapSlice, GIDMapSlice []string, subUIDMap, subGIDMap string) (*IDMappingOptions, error) {
	options := IDMappingOptions{
		HostUIDMapping: true,
		HostGIDMapping: true,
	}
	if subGIDMap == "" && subUIDMap != "" {
		subGIDMap = subUIDMap
	}
	if subUIDMap == "" && subGIDMap != "" {
		subUIDMap = subGIDMap
	}
	if len(GIDMapSlice) == 0 && len(UIDMapSlice) != 0 {
		GIDMapSlice = UIDMapSlice
	}
	if len(UIDMapSlice) == 0 && len(GIDMapSlice) != 0 {
		UIDMapSlice = GIDMapSlice
	}
	if len(UIDMapSlice) == 0 && subUIDMap == "" && os.Getuid() != 0 {
		UIDMapSlice = []string{fmt.Sprintf("0:%d:1", os.Getuid())}
	}
	if len(GIDMapSlice) == 0 && subGIDMap == "" && os.Getuid() != 0 {
		GIDMapSlice = []string{fmt.Sprintf("0:%d:1", os.Getgid())}
	}

	if subUIDMap != "" && subGIDMap != "" {
		mappings, err := idtools.NewIDMappings(subUIDMap, subGIDMap)
		if err != nil {
			return nil, errors.Wrapf(err, "failed to create NewIDMappings for uidmap=%s gidmap=%s", subUIDMap, subGIDMap)
		}
		options.UIDMap = mappings.UIDs()
		options.GIDMap = mappings.GIDs()
	}
	parsedUIDMap, err := idtools.ParseIDMap(UIDMapSlice, "UID")
	if err != nil {
		return nil, errors.Wrapf(err, "failed to create ParseUIDMap UID=%s", UIDMapSlice)
	}
	parsedGIDMap, err := idtools.ParseIDMap(GIDMapSlice, "GID")
	if err != nil {
		return nil, errors.Wrapf(err, "failed to create ParseGIDMap GID=%s", UIDMapSlice)
	}
	options.UIDMap = append(options.UIDMap, parsedUIDMap...)
	options.GIDMap = append(options.GIDMap, parsedGIDMap...)
	if len(options.UIDMap) > 0 {
		options.HostUIDMapping = false
	}
	if len(options.GIDMap) > 0 {
		options.HostGIDMapping = false
	}
	return &options, nil
}

// GetRootlessRuntimeDir returns the runtime directory when running as non root
func GetRootlessRuntimeDir(rootlessUid int) (string, error) {
	path, err := getRootlessRuntimeDir(rootlessUid)
	if err != nil {
		return "", err
	}
	path = filepath.Join(path, "containers")
	if err := os.MkdirAll(path, 0700); err != nil {
		return "", errors.Wrapf(err, "unable to make rootless runtime dir %s", path)
	}
	return path, nil
}

func getRootlessRuntimeDir(rootlessUid int) (string, error) {
	runtimeDir := os.Getenv("XDG_RUNTIME_DIR")

	if runtimeDir != "" {
		return runtimeDir, nil
	}
	tmpDir := fmt.Sprintf("/run/user/%d", rootlessUid)
	st, err := system.Stat(tmpDir)
	if err == nil && int(st.UID()) == os.Getuid() && st.Mode()&0700 == 0700 && st.Mode()&0066 == 0000 {
		return tmpDir, nil
	}
	tmpDir = fmt.Sprintf("%s/%d", os.TempDir(), rootlessUid)
	if err := os.MkdirAll(tmpDir, 0700); err != nil {
		logrus.Errorf("failed to create %s: %v", tmpDir, err)
	} else {
		return tmpDir, nil
	}
	home, err := homeDir()
	if err != nil {
		return "", errors.Wrapf(err, "neither XDG_RUNTIME_DIR nor HOME was set non-empty")
	}
	resolvedHome, err := filepath.EvalSymlinks(home)
	if err != nil {
		return "", errors.Wrapf(err, "cannot resolve %s", home)
	}
	return filepath.Join(resolvedHome, "rundir"), nil
}

// getRootlessDirInfo returns the parent path of where the storage for containers and
// volumes will be in rootless mode
func getRootlessDirInfo(rootlessUid int) (string, string, error) {
	rootlessRuntime, err := GetRootlessRuntimeDir(rootlessUid)
	if err != nil {
		return "", "", err
	}

	dataDir := os.Getenv("XDG_DATA_HOME")
	if dataDir == "" {
		home, err := homeDir()
		if err != nil {
			return "", "", errors.Wrapf(err, "neither XDG_DATA_HOME nor HOME was set non-empty")
		}
		// runc doesn't like symlinks in the rootfs path, and at least
		// on CoreOS /home is a symlink to /var/home, so resolve any symlink.
		resolvedHome, err := filepath.EvalSymlinks(home)
		if err != nil {
			return "", "", errors.Wrapf(err, "cannot resolve %s", home)
		}
		dataDir = filepath.Join(resolvedHome, ".local", "share")
	}
	return dataDir, rootlessRuntime, nil
}

// getRootlessStorageOpts returns the storage opts for containers running as non root
func getRootlessStorageOpts(rootlessUid int) (StoreOptions, error) {
	var opts StoreOptions

	dataDir, rootlessRuntime, err := getRootlessDirInfo(rootlessUid)
	if err != nil {
		return opts, err
	}
	opts.RunRoot = rootlessRuntime
	opts.GraphRoot = filepath.Join(dataDir, "containers", "storage")
	if path, err := exec.LookPath("fuse-overlayfs"); err == nil {
		opts.GraphDriverName = "overlay"
		opts.GraphDriverOptions = []string{fmt.Sprintf("overlay.mount_program=%s", path)}
	} else {
		opts.GraphDriverName = "vfs"
	}
	return opts, nil
}

type tomlOptionsConfig struct {
	MountProgram string `toml:"mount_program"`
}

func getTomlStorage(storeOptions *StoreOptions) *tomlConfig {
	config := new(tomlConfig)

	config.Storage.Driver = storeOptions.GraphDriverName
	config.Storage.RunRoot = storeOptions.RunRoot
	config.Storage.GraphRoot = storeOptions.GraphRoot
	for _, i := range storeOptions.GraphDriverOptions {
		s := strings.Split(i, "=")
		if s[0] == "overlay.mount_program" {
			config.Storage.Options.MountProgram = s[1]
		}
	}

	return config
}

func getRootlessUID() int {
	uidEnv := os.Getenv("_CONTAINERS_ROOTLESS_UID")
	if uidEnv != "" {
		u, _ := strconv.Atoi(uidEnv)
		return u
	}
	return os.Geteuid()
}

// DefaultStoreOptionsAutoDetectUID returns the default storage ops for containers
func DefaultStoreOptionsAutoDetectUID() (StoreOptions, error) {
	uid := getRootlessUID()
	return DefaultStoreOptions(uid != 0, uid)
}

// DefaultStoreOptions returns the default storage ops for containers
func DefaultStoreOptions(rootless bool, rootlessUid int) (StoreOptions, error) {
	var (
		defaultRootlessRunRoot   string
		defaultRootlessGraphRoot string
		err                      error
	)
	storageOpts := defaultStoreOptions
	if rootless && rootlessUid != 0 {
		storageOpts, err = getRootlessStorageOpts(rootlessUid)
		if err != nil {
			return storageOpts, err
		}
	}

	storageConf, err := DefaultConfigFile(rootless && rootlessUid != 0)
	if err != nil {
		return storageOpts, err
	}
	_, err = os.Stat(storageConf)
	if err != nil && !os.IsNotExist(err) {
		return storageOpts, errors.Wrapf(err, "cannot stat %s", storageConf)
	}
	if err == nil {
		defaultRootlessRunRoot = storageOpts.RunRoot
		defaultRootlessGraphRoot = storageOpts.GraphRoot
		storageOpts = StoreOptions{}
		ReloadConfigurationFile(storageConf, &storageOpts)
	}

	if rootless && rootlessUid != 0 {
		if err == nil {
			// If the file did not specify a graphroot or runroot,
			// set sane defaults so we don't try and use root-owned
			// directories
			if storageOpts.RunRoot == "" {
				storageOpts.RunRoot = defaultRootlessRunRoot
			}
			if storageOpts.GraphRoot == "" {
				storageOpts.GraphRoot = defaultRootlessGraphRoot
			}
		} else {
			if err := os.MkdirAll(filepath.Dir(storageConf), 0755); err != nil {
				return storageOpts, errors.Wrapf(err, "cannot make directory %s", filepath.Dir(storageConf))
			}
			file, err := os.OpenFile(storageConf, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
			if err != nil {
				return storageOpts, errors.Wrapf(err, "cannot open %s", storageConf)
			}

			tomlConfiguration := getTomlStorage(&storageOpts)
			defer file.Close()
			enc := toml.NewEncoder(file)
			if err := enc.Encode(tomlConfiguration); err != nil {
				os.Remove(storageConf)

				return storageOpts, errors.Wrapf(err, "failed to encode %s", storageConf)
			}
		}
	}
	return storageOpts, nil
}

func homeDir() (string, error) {
	home := os.Getenv("HOME")
	if home == "" {
		usr, err := user.Current()
		if err != nil {
			return "", errors.Wrapf(err, "neither XDG_RUNTIME_DIR nor HOME was set non-empty")
		}
		home = usr.HomeDir
	}
	return home, nil
}
<|endoftext|>


<commit_before>package ytdl

import (
	"fmt"
	"io/ioutil"
	"net/http"

	"github.com/rs/zerolog/log"
)

func reverseStringSlice(s []string) {
	for i, j := 0, len(s)-1; i < len(s)/2; i, j = i+1, j-1 {
		s[i], s[j] = s[j], s[i]
	}
}

func interfaceToString(val interface{}) string {
	return fmt.Sprintf("%v", val)
}

func httpGet(url string) (*http.Response, error) {
	req, err := http.NewRequest("GET", url, nil)

	if err != nil {
		return nil, err
	}

	// Youtube responses depend on language and user agent
	req.Header.Set("Accept-Language", "en-US,en;q=0.5")
	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0")

	return http.DefaultClient.Do(req)
}

func httpGetAndCheckResponse(url string) (*http.Response, error) {
	log.Debug().Msgf("Fetching %v", url)

	resp, err := httpGet(url)
	if err != nil {
		return nil, fmt.Errorf("request failed: %w", err)
	}

	if resp.StatusCode != 200 {
		resp.Body.Close()
		return nil, fmt.Errorf("unexpected response: %w", err)
	}

	return resp, nil
}

func httpGetAndCheckResponseReadBody(url string) ([]byte, error) {
	resp, err := httpGetAndCheckResponse(url)
	if err != nil {
		return nil, err
	}

	defer resp.Body.Close()

	return ioutil.ReadAll(resp.Body)
}
<commit_msg>Fix unexpected status code error<commit_after>package ytdl

import (
	"fmt"
	"io/ioutil"
	"net/http"

	"github.com/rs/zerolog/log"
)

func reverseStringSlice(s []string) {
	for i, j := 0, len(s)-1; i < len(s)/2; i, j = i+1, j-1 {
		s[i], s[j] = s[j], s[i]
	}
}

func interfaceToString(val interface{}) string {
	return fmt.Sprintf("%v", val)
}

func httpGet(url string) (*http.Response, error) {
	req, err := http.NewRequest("GET", url, nil)

	if err != nil {
		return nil, err
	}

	// Youtube responses depend on language and user agent
	req.Header.Set("Accept-Language", "en-US,en;q=0.5")
	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0")

	return http.DefaultClient.Do(req)
}

func httpGetAndCheckResponse(url string) (*http.Response, error) {
	log.Debug().Msgf("Fetching %v", url)

	resp, err := httpGet(url)
	if err != nil {
		return nil, fmt.Errorf("request failed: %w", err)
	}

	if resp.StatusCode != 200 {
		resp.Body.Close()
		return nil, fmt.Errorf("unexpected status code: %v", resp.StatusCode)
	}

	return resp, nil
}

func httpGetAndCheckResponseReadBody(url string) ([]byte, error) {
	resp, err := httpGetAndCheckResponse(url)
	if err != nil {
		return nil, err
	}

	defer resp.Body.Close()

	return ioutil.ReadAll(resp.Body)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net/url"
)

func validateAndGetURLHost(urlSample string) (string, error) {

	parsed, err := url.ParseRequestURI(urlSample)

	if err != nil {
		fmt.Printf("Unable to parse URL '%s' to get the host\n", urlSample)
		return "", err
	}

	// return parsed.Scheme + "://" + parsed.Host
	return parsed.Host, nil
}

func printVersion() {

	fmt.Printf("%s\n", version)
}
<commit_msg>Allow hostnames to be submitted along with urls<commit_after>package main

import (
	"fmt"
	"net/url"
	"strings"
)

func validateAndGetURLHost(urlSample string) (string, error) {

	// cheat a little by checking if we have :// in the string.
	// if we dont, its probably a hostname already
	if !strings.Contains("://", urlSample) {

		s := strings.TrimSpace(urlSample)
		return s, nil
	}

	// otherwise, if there is a ://, try and extract the hostname
	parsed, err := url.ParseRequestURI(urlSample)

	if err != nil {
		fmt.Printf("Unable to parse URL '%s' to get the host\n", urlSample)
		return "", err
	}

	// return parsed.Scheme + "://" + parsed.Host
	return parsed.Host, nil
}

func printVersion() {

	fmt.Printf("%s\n", version)
}
<|endoftext|>