<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"text/tabwriter"

	"github.com/pkg/errors"
	"github.com/posener/complete"
	"github.com/spf13/cobra"
	"github.com/spf13/pflag"
	"github.com/spf13/viper"

	"github.com/grafana/tanka/pkg/cli"
	"github.com/grafana/tanka/pkg/cli/cmp"
	"github.com/grafana/tanka/pkg/kubernetes/client"
	"github.com/grafana/tanka/pkg/spec/v1alpha1"
)

func envCmd() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "env [action]",
		Short: "manipulate environments",
	}
	cmd.PersistentFlags().Bool("json", false, "output in json format")
	cmd.AddCommand(
		envAddCmd(),
		envSetCmd(),
		envListCmd(),
		envRemoveCmd(),
	)
	return cmd
}

func envSettingsFlags(env *v1alpha1.Config, fs *pflag.FlagSet) {
	fs.StringVar(&env.Spec.APIServer, "server", env.Spec.APIServer, "endpoint of the Kubernetes API")
	fs.StringVar(&env.Spec.APIServer, "server-from-context", env.Spec.APIServer, "set the server to a known one from $KUBECONFIG")
	fs.StringVar(&env.Spec.Namespace, "namespace", env.Spec.Namespace, "namespace to create objects in")
	fs.StringVar(&env.Spec.DiffStrategy, "diff-strategy", env.Spec.DiffStrategy, "specify diff-strategy. Automatically detected otherwise.")
}

func envSetCmd() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "set",
		Short: "update properties of an environment",
		Args:  cobra.ExactArgs(1),
		Annotations: map[string]string{
			"args":                      "baseDir",
			"flags/server-from-context": "kubectlContexts",
		},
	}

	// handler for server-from-context
	cmp.Handlers.Add("kubectlContexts", complete.PredictFunc(
		func(complete.Args) []string {
			c, _ := client.Contexts()
			return c
		},
	))

	// flags
	tmp := v1alpha1.Config{}
	envSettingsFlags(&tmp, cmd.Flags())

	// removed name flag
	name := cmd.Flags().String("name", "", "")
	_ = cmd.Flags().MarkHidden("name")

	cmd.Run = func(cmd *cobra.Command, args []string) {
		if *name != "" {
			log.Fatalln("It looks like you attempted to rename the environment using `--name`. However, this is not possible with Tanka, because the environments name is inferred from the directories name. To rename the environment, rename its directory instead.")
		}

		path, err := filepath.Abs(args[0])
		if err != nil {
			log.Fatalln(err)
		}

		if cmd.Flags().Changed("server-from-context") {
			server, err := client.IPFromContext(tmp.Spec.APIServer)
			if err != nil {
				log.Fatalf("Resolving IP from context: %s", err)
			}
			tmp.Spec.APIServer = server
		}

		viper.Reset()
		cfg := setupConfiguration(path)
		if cfg == nil {
			log.Fatalf("Failed to load an environment at `%s`.\nMake sure it exists and is properly configured. See https://tanka.dev/environments/ for details.", path)
		}
		if tmp.Spec.APIServer != "" && tmp.Spec.APIServer != cfg.Spec.APIServer {
			fmt.Printf("updated spec.apiServer (`%s -> `%s`)\n", cfg.Spec.APIServer, tmp.Spec.APIServer)
			cfg.Spec.APIServer = tmp.Spec.APIServer
		}
		if tmp.Spec.Namespace != "" && tmp.Spec.Namespace != cfg.Spec.Namespace {
			fmt.Printf("updated spec.namespace (`%s -> `%s`)\n", cfg.Spec.Namespace, tmp.Spec.Namespace)
			cfg.Spec.Namespace = tmp.Spec.Namespace
		}
		if tmp.Spec.DiffStrategy != "" && tmp.Spec.DiffStrategy != cfg.Spec.DiffStrategy {
			fmt.Printf("updated spec.diffStrategy (`%s -> `%s`)\n", cfg.Spec.DiffStrategy, tmp.Spec.DiffStrategy)
			cfg.Spec.DiffStrategy = tmp.Spec.DiffStrategy
		}

		if err := writeJSON(cfg, filepath.Join(path, "spec.json")); err != nil {
			log.Fatalln(err)
		}
	}
	return cmd
}

func envAddCmd() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "add <path>",
		Short: "create a new environment",
		Args:  cobra.ExactArgs(1),
		Annotations: map[string]string{
			"args": "dirs",
		},
	}
	cfg := v1alpha1.New()
	envSettingsFlags(cfg, cmd.Flags())
	cmd.Run = func(cmd *cobra.Command, args []string) {
		if err := addEnv(args[0], cfg); err != nil {
			log.Fatalln(err)
		}
	}
	return cmd
}

// used by initCmd() as well
func addEnv(dir string, cfg *v1alpha1.Config) error {
	path, err := filepath.Abs(dir)
	if err != nil {
		log.Fatalln(err)
	}
	if _, err := os.Stat(path); err != nil {
		// folder does not exist
		if os.IsNotExist(err) {
			if err := os.MkdirAll(path, os.ModePerm); err != nil {
				return errors.Wrap(err, "creating directory")
			}
		} else {
			// it exists
			if os.IsExist(err) {
				return fmt.Errorf("directory %s already exists", path)
			}
			// we have another error
			return errors.Wrap(err, "creating directory")
		}
	}

	// the other properties are already set by v1alpha1.New() and pflag.Parse()
	cfg.Metadata.Name = filepath.Base(path)

	// write spec.json
	if err := writeJSON(cfg, filepath.Join(path, "spec.json")); err != nil {
		log.Fatalln(err)
	}

	// write main.jsonnet
	if err := writeJSON(struct{}{}, filepath.Join(path, "main.jsonnet")); err != nil {
		log.Fatalln(err)
	}

	return nil
}

func envRemoveCmd() *cobra.Command {
	return &cobra.Command{
		Use:     "remove <path>",
		Aliases: []string{"rm"},
		Short:   "delete an environment",
		Annotations: map[string]string{
			"args": "baseDir",
		},
		Run: func(cmd *cobra.Command, args []string) {
			for _, arg := range args {
				path, err := filepath.Abs(arg)
				if err != nil {
					log.Fatalln("parsing environments name:", err)
				}
				if err := cli.Confirm(fmt.Sprintf("Permanently removing the environment located at '%s'.", path), "yes"); err != nil {
					log.Fatalln(err)
				}
				if err := os.RemoveAll(path); err != nil {
					log.Fatalf("Removing '%s': %s", path, err)
				}
				fmt.Println("Removed", path)
			}
		},
	}
}

func envListCmd() *cobra.Command {
	cmd := &cobra.Command{
		Use:     "list",
		Aliases: []string{"ls"},
		Short:   "list environments",
		Args:    cobra.NoArgs,
	}

	cmd.Run = func(cmd *cobra.Command, args []string) {
		envs := []v1alpha1.Config{}
		dirs := findBaseDirs()
		useJSON, err := cmd.Flags().GetBool("json")
		if err != nil {
			// this err should never occur. Panic in case
			panic(err)
		}
		for _, dir := range dirs {
			viper.Reset()
			env := setupConfiguration(dir)
			if env == nil {
				log.Printf("Could not setup configuration from %q", dir)
				continue
			}
			envs = append(envs, *env)
		}

		if useJSON {
			j, err := json.Marshal(envs)
			if err != nil {
				log.Fatalln("Formatting as json:", j)
			}
			fmt.Println(string(j))
			return
		}

		w := tabwriter.NewWriter(os.Stdout, 0, 0, 4, ' ', 0)
		f := "%s\t%s\t%s\t\n"
		fmt.Fprintf(w, f, "NAME", "NAMESPACE", "SERVER")
		for _, e := range envs {
			fmt.Fprintf(w, f, e.Metadata.Name, e.Spec.Namespace, e.Spec.APIServer)
		}
		w.Flush()
	}
	return cmd
}
<commit_msg>fix(cli): server from context on env add (#184)<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"text/tabwriter"

	"github.com/pkg/errors"
	"github.com/posener/complete"
	"github.com/spf13/cobra"
	"github.com/spf13/pflag"
	"github.com/spf13/viper"

	"github.com/grafana/tanka/pkg/cli"
	"github.com/grafana/tanka/pkg/cli/cmp"
	"github.com/grafana/tanka/pkg/kubernetes/client"
	"github.com/grafana/tanka/pkg/spec/v1alpha1"
)

func envCmd() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "env [action]",
		Short: "manipulate environments",
	}
	cmd.PersistentFlags().Bool("json", false, "output in json format")
	cmd.AddCommand(
		envAddCmd(),
		envSetCmd(),
		envListCmd(),
		envRemoveCmd(),
	)
	return cmd
}

func envSettingsFlags(env *v1alpha1.Config, fs *pflag.FlagSet) {
	fs.StringVar(&env.Spec.APIServer, "server", env.Spec.APIServer, "endpoint of the Kubernetes API")
	fs.StringVar(&env.Spec.APIServer, "server-from-context", env.Spec.APIServer, "set the server to a known one from $KUBECONFIG")
	fs.StringVar(&env.Spec.Namespace, "namespace", env.Spec.Namespace, "namespace to create objects in")
	fs.StringVar(&env.Spec.DiffStrategy, "diff-strategy", env.Spec.DiffStrategy, "specify diff-strategy. Automatically detected otherwise.")
}

func envSetCmd() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "set",
		Short: "update properties of an environment",
		Args:  cobra.ExactArgs(1),
		Annotations: map[string]string{
			"args":                      "baseDir",
			"flags/server-from-context": "kubectlContexts",
		},
	}

	// handler for server-from-context
	cmp.Handlers.Add("kubectlContexts", complete.PredictFunc(
		func(complete.Args) []string {
			c, _ := client.Contexts()
			return c
		},
	))

	// flags
	tmp := v1alpha1.Config{}
	envSettingsFlags(&tmp, cmd.Flags())

	// removed name flag
	name := cmd.Flags().String("name", "", "")
	_ = cmd.Flags().MarkHidden("name")

	cmd.Run = func(cmd *cobra.Command, args []string) {
		if *name != "" {
			log.Fatalln("It looks like you attempted to rename the environment using `--name`. However, this is not possible with Tanka, because the environments name is inferred from the directories name. To rename the environment, rename its directory instead.")
		}

		path, err := filepath.Abs(args[0])
		if err != nil {
			log.Fatalln(err)
		}

		if cmd.Flags().Changed("server-from-context") {
			server, err := client.IPFromContext(tmp.Spec.APIServer)
			if err != nil {
				log.Fatalf("Resolving IP from context: %s", err)
			}
			tmp.Spec.APIServer = server
		}

		viper.Reset()
		cfg := setupConfiguration(path)
		if cfg == nil {
			log.Fatalf("Failed to load an environment at `%s`.\nMake sure it exists and is properly configured. See https://tanka.dev/environments/ for details.", path)
		}
		if tmp.Spec.APIServer != "" && tmp.Spec.APIServer != cfg.Spec.APIServer {
			fmt.Printf("updated spec.apiServer (`%s -> `%s`)\n", cfg.Spec.APIServer, tmp.Spec.APIServer)
			cfg.Spec.APIServer = tmp.Spec.APIServer
		}
		if tmp.Spec.Namespace != "" && tmp.Spec.Namespace != cfg.Spec.Namespace {
			fmt.Printf("updated spec.namespace (`%s -> `%s`)\n", cfg.Spec.Namespace, tmp.Spec.Namespace)
			cfg.Spec.Namespace = tmp.Spec.Namespace
		}
		if tmp.Spec.DiffStrategy != "" && tmp.Spec.DiffStrategy != cfg.Spec.DiffStrategy {
			fmt.Printf("updated spec.diffStrategy (`%s -> `%s`)\n", cfg.Spec.DiffStrategy, tmp.Spec.DiffStrategy)
			cfg.Spec.DiffStrategy = tmp.Spec.DiffStrategy
		}

		if err := writeJSON(cfg, filepath.Join(path, "spec.json")); err != nil {
			log.Fatalln(err)
		}
	}
	return cmd
}

func envAddCmd() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "add <path>",
		Short: "create a new environment",
		Args:  cobra.ExactArgs(1),
		Annotations: map[string]string{
			"args": "dirs",
		},
	}
	cfg := v1alpha1.New()
	envSettingsFlags(cfg, cmd.Flags())
	cmd.Run = func(cmd *cobra.Command, args []string) {
		if cmd.Flags().Changed("server-from-context") {
			server, err := client.IPFromContext(cfg.Spec.APIServer)
			if err != nil {
				log.Fatalf("Resolving IP from context: %s", err)
			}
			cfg.Spec.APIServer = server
		}

		if err := addEnv(args[0], cfg); err != nil {
			log.Fatalln(err)
		}
	}
	return cmd
}

// used by initCmd() as well
func addEnv(dir string, cfg *v1alpha1.Config) error {
	path, err := filepath.Abs(dir)
	if err != nil {
		log.Fatalln(err)
	}
	if _, err := os.Stat(path); err != nil {
		// folder does not exist
		if os.IsNotExist(err) {
			if err := os.MkdirAll(path, os.ModePerm); err != nil {
				return errors.Wrap(err, "creating directory")
			}
		} else {
			// it exists
			if os.IsExist(err) {
				return fmt.Errorf("directory %s already exists", path)
			}
			// we have another error
			return errors.Wrap(err, "creating directory")
		}
	}

	// the other properties are already set by v1alpha1.New() and pflag.Parse()
	cfg.Metadata.Name = filepath.Base(path)

	// write spec.json
	if err := writeJSON(cfg, filepath.Join(path, "spec.json")); err != nil {
		log.Fatalln(err)
	}

	// write main.jsonnet
	if err := writeJSON(struct{}{}, filepath.Join(path, "main.jsonnet")); err != nil {
		log.Fatalln(err)
	}

	return nil
}

func envRemoveCmd() *cobra.Command {
	return &cobra.Command{
		Use:     "remove <path>",
		Aliases: []string{"rm"},
		Short:   "delete an environment",
		Annotations: map[string]string{
			"args": "baseDir",
		},
		Run: func(cmd *cobra.Command, args []string) {
			for _, arg := range args {
				path, err := filepath.Abs(arg)
				if err != nil {
					log.Fatalln("parsing environments name:", err)
				}
				if err := cli.Confirm(fmt.Sprintf("Permanently removing the environment located at '%s'.", path), "yes"); err != nil {
					log.Fatalln(err)
				}
				if err := os.RemoveAll(path); err != nil {
					log.Fatalf("Removing '%s': %s", path, err)
				}
				fmt.Println("Removed", path)
			}
		},
	}
}

func envListCmd() *cobra.Command {
	cmd := &cobra.Command{
		Use:     "list",
		Aliases: []string{"ls"},
		Short:   "list environments",
		Args:    cobra.NoArgs,
	}

	cmd.Run = func(cmd *cobra.Command, args []string) {
		envs := []v1alpha1.Config{}
		dirs := findBaseDirs()
		useJSON, err := cmd.Flags().GetBool("json")
		if err != nil {
			// this err should never occur. Panic in case
			panic(err)
		}
		for _, dir := range dirs {
			viper.Reset()
			env := setupConfiguration(dir)
			if env == nil {
				log.Printf("Could not setup configuration from %q", dir)
				continue
			}
			envs = append(envs, *env)
		}

		if useJSON {
			j, err := json.Marshal(envs)
			if err != nil {
				log.Fatalln("Formatting as json:", j)
			}
			fmt.Println(string(j))
			return
		}

		w := tabwriter.NewWriter(os.Stdout, 0, 0, 4, ' ', 0)
		f := "%s\t%s\t%s\t\n"
		fmt.Fprintf(w, f, "NAME", "NAMESPACE", "SERVER")
		for _, e := range envs {
			fmt.Fprintf(w, f, e.Metadata.Name, e.Spec.Namespace, e.Spec.APIServer)
		}
		w.Flush()
	}
	return cmd
}
<|endoftext|>


<commit_before>package config

import (
	"bufio"
	"bytes"
	"encoding/json"
	"fmt"
	"path/filepath"

	"github.com/hashicorp/hcl2/hcl"
	"github.com/zclconf/go-cty/cty"
	"github.com/zclconf/go-cty/cty/gocty"
	ctyjson "github.com/zclconf/go-cty/cty/json"

	"github.com/gruntwork-io/terragrunt/errors"
	"github.com/gruntwork-io/terragrunt/options"
	"github.com/gruntwork-io/terragrunt/util"
)

type TerragruntOutput struct {
	Name       string `hcl:",label"`
	ConfigPath string `hcl:"config_path,attr"`
}

// Decode the terragrunt_output blocks from the file, making sure to merge in those from included parents, and then
// retrieve all the outputs from the remote state. Then encode the resulting map as a cty.Value object.
func decodeAndRetrieveOutputs(
	file *hcl.File,
	filename string,
	terragruntOptions *options.TerragruntOptions,
	extensions EvalContextExtensions,
) (*cty.Value, error) {
	decodedTerragruntOutput := terragruntOutput{}
	err := decodeHcl(file, filename, &decodedTerragruntOutput, terragruntOptions, extensions)
	if err != nil {
		return nil, err
	}
	return terragruntOutputsToOutputMapCtyValue(decodedTerragruntOutput.TerragruntOutput, terragruntOptions)
}

// Convert the list of parsed TerragruntOutput blocks into a list of module dependencies. Each output block should
// become a dependency of the current config, since that module has to be applied before we can read the output.
func terragruntOutputsToModuleDependencies(decodedOutputBlocks []TerragruntOutput) *ModuleDependencies {
	paths := []string{}
	for _, decodedOutputBlock := range decodedOutputBlocks {
		configPath := decodedOutputBlock.ConfigPath
		if util.IsFile(configPath) && filepath.Base(configPath) == DefaultTerragruntConfigPath {
			// dependencies system expects the directory containing the terragrunt.hcl file
			configPath = filepath.Dir(configPath)
		}
		paths = append(paths, configPath)
	}
	return &ModuleDependencies{Paths: paths}
}

// Retrieve the output from the terraform state of each terragrunt_output block that was parsed. Encode the outputs as a
// map from the terragrunt_output block label to the corresponding output from the state. Finally, convert the map to
// cty.Value to a single cty.Value object, which is what is expected by the HCL2 decoder.
func terragruntOutputsToOutputMapCtyValue(outputConfigs []TerragruntOutput, terragruntOptions *options.TerragruntOptions) (*cty.Value, error) {
	paths := []string{}
	outputMap := map[string]cty.Value{}

	for _, outputConfig := range outputConfigs {
		paths = append(paths, outputConfig.ConfigPath)
		outputVal, err := getTerragruntOutput(outputConfig, terragruntOptions)
		if err != nil {
			return nil, err
		}
		if outputVal != nil {
			outputMap[outputConfig.Name] = *outputVal
		}
	}

	// We need to convert the value map to a single cty.Value at the end so that it can be used in the execution context
	convertedOutput, err := gocty.ToCtyValue(outputMap, generateTypeFromValuesMap(outputMap))
	if err != nil {
		err = TerragruntOutputListEncodingError{Paths: paths, Err: err}
	}
	return &convertedOutput, errors.WithStackTrace(err)
}

// Return the output from the state of another module, managed by terragrunt. This function will parse the provided
// terragrunt config and extract the desired output from the remote state. Note that this will error if the targetted
// module hasn't been applied yet.
func getTerragruntOutput(outputConfig TerragruntOutput, terragruntOptions *options.TerragruntOptions) (*cty.Value, error) {
	// target config check: make sure the target config exists
	cwd := filepath.Dir(terragruntOptions.TerragruntConfigPath)
	targetConfig := outputConfig.ConfigPath
	if !filepath.IsAbs(targetConfig) {
		targetConfig = util.JoinPath(cwd, targetConfig)
	}
	if util.IsDir(targetConfig) {
		targetConfig = util.JoinPath(targetConfig, DefaultTerragruntConfigPath)
	}
	if !util.FileExists(targetConfig) {
		return nil, errors.WithStackTrace(TerragruntOutputConfigNotFound{Path: targetConfig})
	}

	jsonBytes, err := runTerragruntOutputJson(terragruntOptions, targetConfig)
	if err != nil {
		return nil, err
	}

	outputMap, err := terraformOutputJsonToCtyValueMap(targetConfig, jsonBytes)
	if err != nil {
		return nil, err
	}

	// We need to convert the value map to a single cty.Value at the end for use in the terragrunt config.
	convertedOutput, err := gocty.ToCtyValue(outputMap, generateTypeFromValuesMap(outputMap))
	if err != nil {
		err = TerragruntOutputEncodingError{Path: targetConfig, Err: err}
	}
	return &convertedOutput, errors.WithStackTrace(err)
}

// runTerragruntOutputJson uses terragrunt running functions to extract the json output from the target config. Make a
// copy of the terragruntOptions so that we can reuse the same execution environment.
func runTerragruntOutputJson(terragruntOptions *options.TerragruntOptions, targetConfig string) ([]byte, error) {
	var stdoutBuffer bytes.Buffer
	stdoutBufferWriter := bufio.NewWriter(&stdoutBuffer)
	targetOptions := terragruntOptions.Clone(targetConfig)
	targetOptions.TerraformCliArgs = []string{"output", "-json"}
	targetOptions.Writer = stdoutBufferWriter
	err := targetOptions.RunTerragrunt(targetOptions)
	if err != nil {
		return nil, errors.WithStackTrace(err)
	}

	stdoutBufferWriter.Flush()
	jsonString := stdoutBuffer.String()
	jsonBytes := []byte(jsonString)
	util.Debugf(terragruntOptions.Logger, "Retrieved output from %s as json: %s", targetConfig, jsonString)
	return jsonBytes, nil
}

// terraformOutputJsonToCtyValueMap takes the terraform output json and converts to a mapping between output keys to the
// parsed cty.Value encoding of the json objects.
func terraformOutputJsonToCtyValueMap(targetConfig string, jsonBytes []byte) (map[string]cty.Value, error) {
	// When getting all outputs, terraform returns a json with the data containing metadata about the types, so we
	// can't quite return the data directly. Instead, we will need further processing to get the output we want.
	// To do so, we first Unmarshal the json into a simple go map to a OutputMeta struct.
	type OutputMeta struct {
		Sensitive bool            `json:"sensitive"`
		Type      json.RawMessage `json:"type"`
		Value     json.RawMessage `json:"value"`
	}
	var outputs map[string]OutputMeta
	err := json.Unmarshal(jsonBytes, &outputs)
	if err != nil {
		return nil, errors.WithStackTrace(TerragruntOutputParsingError{Path: targetConfig, Err: err})
	}
	flattenedOutput := map[string]cty.Value{}
	for k, v := range outputs {
		outputType, err := ctyjson.UnmarshalType(v.Type)
		if err != nil {
			return nil, errors.WithStackTrace(TerragruntOutputParsingError{Path: targetConfig, Err: err})
		}
		outputVal, err := ctyjson.Unmarshal(v.Value, outputType)
		if err != nil {
			return nil, errors.WithStackTrace(TerragruntOutputParsingError{Path: targetConfig, Err: err})
		}
		flattenedOutput[k] = outputVal
	}
	return flattenedOutput, nil
}

// Custom error types

type TerragruntOutputConfigNotFound struct {
	Path string
}

func (err TerragruntOutputConfigNotFound) Error() string {
	return fmt.Sprintf("%s does not exist", err.Path)
}

type TerragruntOutputParsingError struct {
	Path string
	Err  error
}

func (err TerragruntOutputParsingError) Error() string {
	return fmt.Sprintf("Could not parse output from terragrunt config %s. Underlying error: %s", err.Path, err.Err)
}

type TerragruntOutputEncodingError struct {
	Path string
	Err  error
}

func (err TerragruntOutputEncodingError) Error() string {
	return fmt.Sprintf("Could not encode output from terragrunt config %s. Underlying error: %s", err.Path, err.Err)
}

type TerragruntOutputListEncodingError struct {
	Paths []string
	Err   error
}

func (err TerragruntOutputListEncodingError) Error() string {
	return fmt.Sprintf("Could not encode output from list of terragrunt configs %v. Underlying error: %s", err.Paths, err.Err)
}
<commit_msg>Fix tests<commit_after>package config

import (
	"bufio"
	"bytes"
	"encoding/json"
	"fmt"
	"path/filepath"

	"github.com/hashicorp/hcl2/hcl"
	"github.com/zclconf/go-cty/cty"
	"github.com/zclconf/go-cty/cty/gocty"
	ctyjson "github.com/zclconf/go-cty/cty/json"

	"github.com/gruntwork-io/terragrunt/errors"
	"github.com/gruntwork-io/terragrunt/options"
	"github.com/gruntwork-io/terragrunt/util"
)

type TerragruntOutput struct {
	Name       string `hcl:",label"`
	ConfigPath string `hcl:"config_path,attr"`
}

// Decode the terragrunt_output blocks from the file, making sure to merge in those from included parents, and then
// retrieve all the outputs from the remote state. Then encode the resulting map as a cty.Value object.
func decodeAndRetrieveOutputs(
	file *hcl.File,
	filename string,
	terragruntOptions *options.TerragruntOptions,
	extensions EvalContextExtensions,
) (*cty.Value, error) {
	decodedTerragruntOutput := terragruntOutput{}
	err := decodeHcl(file, filename, &decodedTerragruntOutput, terragruntOptions, extensions)
	if err != nil {
		return nil, err
	}
	return terragruntOutputsToOutputMapCtyValue(decodedTerragruntOutput.TerragruntOutput, terragruntOptions)
}

// Convert the list of parsed TerragruntOutput blocks into a list of module dependencies. Each output block should
// become a dependency of the current config, since that module has to be applied before we can read the output.
func terragruntOutputsToModuleDependencies(decodedOutputBlocks []TerragruntOutput) *ModuleDependencies {
	if len(decodedOutputBlocks) == 0 {
		return nil
	}

	paths := []string{}
	for _, decodedOutputBlock := range decodedOutputBlocks {
		configPath := decodedOutputBlock.ConfigPath
		if util.IsFile(configPath) && filepath.Base(configPath) == DefaultTerragruntConfigPath {
			// dependencies system expects the directory containing the terragrunt.hcl file
			configPath = filepath.Dir(configPath)
		}
		paths = append(paths, configPath)
	}
	return &ModuleDependencies{Paths: paths}
}

// Retrieve the output from the terraform state of each terragrunt_output block that was parsed. Encode the outputs as a
// map from the terragrunt_output block label to the corresponding output from the state. Finally, convert the map to
// cty.Value to a single cty.Value object, which is what is expected by the HCL2 decoder.
func terragruntOutputsToOutputMapCtyValue(outputConfigs []TerragruntOutput, terragruntOptions *options.TerragruntOptions) (*cty.Value, error) {
	paths := []string{}
	outputMap := map[string]cty.Value{}

	for _, outputConfig := range outputConfigs {
		paths = append(paths, outputConfig.ConfigPath)
		outputVal, err := getTerragruntOutput(outputConfig, terragruntOptions)
		if err != nil {
			return nil, err
		}
		if outputVal != nil {
			outputMap[outputConfig.Name] = *outputVal
		}
	}

	// We need to convert the value map to a single cty.Value at the end so that it can be used in the execution context
	convertedOutput, err := gocty.ToCtyValue(outputMap, generateTypeFromValuesMap(outputMap))
	if err != nil {
		err = TerragruntOutputListEncodingError{Paths: paths, Err: err}
	}
	return &convertedOutput, errors.WithStackTrace(err)
}

// Return the output from the state of another module, managed by terragrunt. This function will parse the provided
// terragrunt config and extract the desired output from the remote state. Note that this will error if the targetted
// module hasn't been applied yet.
func getTerragruntOutput(outputConfig TerragruntOutput, terragruntOptions *options.TerragruntOptions) (*cty.Value, error) {
	// target config check: make sure the target config exists
	cwd := filepath.Dir(terragruntOptions.TerragruntConfigPath)
	targetConfig := outputConfig.ConfigPath
	if !filepath.IsAbs(targetConfig) {
		targetConfig = util.JoinPath(cwd, targetConfig)
	}
	if util.IsDir(targetConfig) {
		targetConfig = util.JoinPath(targetConfig, DefaultTerragruntConfigPath)
	}
	if !util.FileExists(targetConfig) {
		return nil, errors.WithStackTrace(TerragruntOutputConfigNotFound{Path: targetConfig})
	}

	jsonBytes, err := runTerragruntOutputJson(terragruntOptions, targetConfig)
	if err != nil {
		return nil, err
	}

	outputMap, err := terraformOutputJsonToCtyValueMap(targetConfig, jsonBytes)
	if err != nil {
		return nil, err
	}

	// We need to convert the value map to a single cty.Value at the end for use in the terragrunt config.
	convertedOutput, err := gocty.ToCtyValue(outputMap, generateTypeFromValuesMap(outputMap))
	if err != nil {
		err = TerragruntOutputEncodingError{Path: targetConfig, Err: err}
	}
	return &convertedOutput, errors.WithStackTrace(err)
}

// runTerragruntOutputJson uses terragrunt running functions to extract the json output from the target config. Make a
// copy of the terragruntOptions so that we can reuse the same execution environment.
func runTerragruntOutputJson(terragruntOptions *options.TerragruntOptions, targetConfig string) ([]byte, error) {
	var stdoutBuffer bytes.Buffer
	stdoutBufferWriter := bufio.NewWriter(&stdoutBuffer)
	targetOptions := terragruntOptions.Clone(targetConfig)
	targetOptions.TerraformCliArgs = []string{"output", "-json"}
	targetOptions.Writer = stdoutBufferWriter
	err := targetOptions.RunTerragrunt(targetOptions)
	if err != nil {
		return nil, errors.WithStackTrace(err)
	}

	stdoutBufferWriter.Flush()
	jsonString := stdoutBuffer.String()
	jsonBytes := []byte(jsonString)
	util.Debugf(terragruntOptions.Logger, "Retrieved output from %s as json: %s", targetConfig, jsonString)
	return jsonBytes, nil
}

// terraformOutputJsonToCtyValueMap takes the terraform output json and converts to a mapping between output keys to the
// parsed cty.Value encoding of the json objects.
func terraformOutputJsonToCtyValueMap(targetConfig string, jsonBytes []byte) (map[string]cty.Value, error) {
	// When getting all outputs, terraform returns a json with the data containing metadata about the types, so we
	// can't quite return the data directly. Instead, we will need further processing to get the output we want.
	// To do so, we first Unmarshal the json into a simple go map to a OutputMeta struct.
	type OutputMeta struct {
		Sensitive bool            `json:"sensitive"`
		Type      json.RawMessage `json:"type"`
		Value     json.RawMessage `json:"value"`
	}
	var outputs map[string]OutputMeta
	err := json.Unmarshal(jsonBytes, &outputs)
	if err != nil {
		return nil, errors.WithStackTrace(TerragruntOutputParsingError{Path: targetConfig, Err: err})
	}
	flattenedOutput := map[string]cty.Value{}
	for k, v := range outputs {
		outputType, err := ctyjson.UnmarshalType(v.Type)
		if err != nil {
			return nil, errors.WithStackTrace(TerragruntOutputParsingError{Path: targetConfig, Err: err})
		}
		outputVal, err := ctyjson.Unmarshal(v.Value, outputType)
		if err != nil {
			return nil, errors.WithStackTrace(TerragruntOutputParsingError{Path: targetConfig, Err: err})
		}
		flattenedOutput[k] = outputVal
	}
	return flattenedOutput, nil
}

// Custom error types

type TerragruntOutputConfigNotFound struct {
	Path string
}

func (err TerragruntOutputConfigNotFound) Error() string {
	return fmt.Sprintf("%s does not exist", err.Path)
}

type TerragruntOutputParsingError struct {
	Path string
	Err  error
}

func (err TerragruntOutputParsingError) Error() string {
	return fmt.Sprintf("Could not parse output from terragrunt config %s. Underlying error: %s", err.Path, err.Err)
}

type TerragruntOutputEncodingError struct {
	Path string
	Err  error
}

func (err TerragruntOutputEncodingError) Error() string {
	return fmt.Sprintf("Could not encode output from terragrunt config %s. Underlying error: %s", err.Path, err.Err)
}

type TerragruntOutputListEncodingError struct {
	Paths []string
	Err   error
}

func (err TerragruntOutputListEncodingError) Error() string {
	return fmt.Sprintf("Could not encode output from list of terragrunt configs %v. Underlying error: %s", err.Paths, err.Err)
}
<|endoftext|>


<commit_before>// go gen-con - Go Generic Containers
// Copyright 2016 Aurélien Rainone. All rights reserved.
// Use of this source code is governed by a MIT license
// that can be found in the LICENSE file.

package containers

const BoundedStack string = `
package {{.Package}}

// {{.Container}} represents a bounded stack of {{.Containee}}.
type {{.Container}} struct {
	top  *item
	size int
	max  int
}

// internal item structure
type item struct {
	value *{{.Containee}}
	next  *item
}

{{if .Exported}}
// New{{.Container}} initializes and returns a new bounded stack of {{.Containee}}
func New{{.Container}}(max int) *{{.Container}} {
	return &{{.Container}}{max: max}
}
{{else}}
// new{{.Container}} initializes and returns a new bounded stack of {{.Containee}}
func new{{.Container}}(max int) *{{.Container}} {
	return &{{.Container}}{max: max}
}
{{end}}

// Len returns the stack's length
func (s *{{.Container}}) Len() int {
	return s.size
}

// Max returns the stack's maximum size
func (s *{{.Container}}) Max() int {
	return s.max
}

// Push pushes a new item on top of the stack.
//
// In case this operation would make the stack size greater than its maximum,
// the bottommost element is removed before pushing the new one.
func (s *{{.Container}}) Push(value *{{.Containee}}) {
	if s.size+1 > s.max {
		if last := s.PopLast(); last == nil {
			panic("Unexpected nil in stack")
		}
	}
	s.top = &item{value, s.top}
	s.size++
}

// Pop removes the topmost item from the stack and return its value
//
// If the stack is empty, Pop returns nil
func (s *{{.Container}}) Pop() (value *{{.Containee}}) {
	if s.size > 0 {
		value, s.top = s.top.value, s.top.next
		s.size--
		return
	}
	return nil
}

// PopLast removes the bottommost item.
//
// PopLast does nothing if the stack does not contain at least 2 items.
func (s *{{.Container}}) PopLast() (value *{{.Containee}}) {
	if lastElem := s.popLast(s.top); s.size >= 2 && lastElem != nil {
		return lastElem.value
	}
	return nil
}

// Peek returns the topmost without removing it from the stack
func (s *{{.Container}}) Peek() (value *{{.Containee}}, exists bool) {
	exists = false
	if s.size > 0 {
		value = s.top.value
		exists = true
	}

	return
}

func (s *{{.Container}}) popLast(elem *item) *item {
	if elem == nil {
		return nil
	}
	// not last because it has next and a grandchild
	if elem.next != nil && elem.next.next != nil {
		return s.popLast(elem.next)
	}

	// current elem is second from bottom, as next elem has no child
	if elem.next != nil && elem.next.next == nil {
		last := elem.next
		// make current elem bottom of stack by removing its next item
		elem.next = nil
		s.size--
		return last
	}
	return nil
}
`
<commit_msg>Factor common part of (nN)ewStack<commit_after>// go gen-con - Go Generic Containers
// Copyright 2016 Aurélien Rainone. All rights reserved.
// Use of this source code is governed by a MIT license
// that can be found in the LICENSE file.

package containers

const BoundedStack string = `
package {{.Package}}

// {{.Container}} represents a bounded stack of {{.Containee}}.
type {{.Container}} struct {
	top  *item
	size int
	max  int
}

// internal item structure
type item struct {
	value *{{.Containee}}
	next  *item
}

{{if .Exported}}
// New{{.Container}} initializes and returns a new bounded stack of {{.Containee}}
func New{{.Container}}(max int) *{{.Container}} {
{{else}}
// new{{.Container}} initializes and returns a new bounded stack of {{.Containee}}
func new{{.Container}}(max int) *{{.Container}} {
{{end}}
	return &{{.Container}}{max: max}
}

// Len returns the stack's length
func (s *{{.Container}}) Len() int {
	return s.size
}

// Max returns the stack's maximum size
func (s *{{.Container}}) Max() int {
	return s.max
}

// Push pushes a new item on top of the stack.
//
// In case this operation would make the stack size greater than its maximum,
// the bottommost element is removed before pushing the new one.
func (s *{{.Container}}) Push(value *{{.Containee}}) {
	if s.size+1 > s.max {
		if last := s.PopLast(); last == nil {
			panic("Unexpected nil in stack")
		}
	}
	s.top = &item{value, s.top}
	s.size++
}

// Pop removes the topmost item from the stack and return its value
//
// If the stack is empty, Pop returns nil
func (s *{{.Container}}) Pop() (value *{{.Containee}}) {
	if s.size > 0 {
		value, s.top = s.top.value, s.top.next
		s.size--
		return
	}
	return nil
}

// PopLast removes the bottommost item.
//
// PopLast does nothing if the stack does not contain at least 2 items.
func (s *{{.Container}}) PopLast() (value *{{.Containee}}) {
	if lastElem := s.popLast(s.top); s.size >= 2 && lastElem != nil {
		return lastElem.value
	}
	return nil
}

// Peek returns the topmost without removing it from the stack
func (s *{{.Container}}) Peek() (value *{{.Containee}}, exists bool) {
	exists = false
	if s.size > 0 {
		value = s.top.value
		exists = true
	}

	return
}

func (s *{{.Container}}) popLast(elem *item) *item {
	if elem == nil {
		return nil
	}
	// not last because it has next and a grandchild
	if elem.next != nil && elem.next.next != nil {
		return s.popLast(elem.next)
	}

	// current elem is second from bottom, as next elem has no child
	if elem.next != nil && elem.next.next == nil {
		last := elem.next
		// make current elem bottom of stack by removing its next item
		elem.next = nil
		s.size--
		return last
	}
	return nil
}
`
<|endoftext|>


<commit_before>package matching

import (
	"encoding/json"
	"reflect"
)

func JsonMatch(matchingString string, toMatch string) bool {
	if matchingString == "" && toMatch == "" {
		return true
	}
	var matchingObject map[string]interface{}
	err := json.Unmarshal([]byte(matchingString), &matchingObject)
	if err != nil {
		return false
	}

	var toMatchObject map[string]interface{}
	err = json.Unmarshal([]byte(toMatch), &toMatchObject)
	if err != nil {
		return false
	}

	return reflect.DeepEqual(matchingObject, toMatchObject)
}
<commit_msg>JsonMatch should return true when two JSON are identical<commit_after>package matching

import (
	"encoding/json"
	"reflect"
)

func JsonMatch(matchingString string, toMatch string) bool {
	if matchingString == toMatch {
		return true
	}
	var matchingObject map[string]interface{}
	err := json.Unmarshal([]byte(matchingString), &matchingObject)
	if err != nil {
		return false
	}

	var toMatchObject map[string]interface{}
	err = json.Unmarshal([]byte(toMatch), &toMatchObject)
	if err != nil {
		return false
	}

	return reflect.DeepEqual(matchingObject, toMatchObject)
}
<|endoftext|>


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

package queue

import (
	"fmt"
	"sync"
	"time"

	"github.com/tsuru/tsuru/log"
	tsuruRedis "github.com/tsuru/tsuru/redis"
	"gopkg.in/redis.v3"
)

type redisPubSub struct {
	name    string
	prefix  string
	factory *redisPubSubFactory
	psc     *redis.PubSub
}

func (r *redisPubSub) Pub(msg []byte) error {
	conn, err := r.factory.getConn()
	if err != nil {
		return err
	}
	return conn.Publish(r.key(), string(msg)).Err()
}

func (r *redisPubSub) UnSub() error {
	err := r.psc.Unsubscribe()
	if err != nil {
		return err
	}
	err = r.psc.Close()
	if err != nil {
		return err
	}
	return nil
}

func (r *redisPubSub) Sub() (<-chan []byte, error) {
	conn, err := r.factory.getConn()
	if err != nil {
		return nil, err
	}
	r.psc, err = conn.Subscribe(r.key())
	if err != nil {
		return nil, err
	}
	msgChan := make(chan []byte)
	go func() {
		defer close(msgChan)
		for {
			msg, err := r.psc.ReceiveTimeout(r.factory.config.ReadTimeout)
			if err != nil {
				log.Errorf("Error receiving messages from channel %s: %s", r.key(), err)
				return
			}
			switch v := msg.(type) {
			case *redis.Message:
				msgChan <- []byte(v.Payload)
			case *redis.Subscription:
				if v.Count == 0 {
					return
				}
			}
		}
	}()
	return msgChan, nil
}

func (r *redisPubSub) key() string {
	return r.prefix + ":" + r.name
}

type redisPubSubFactory struct {
	sync.Mutex
	pool   tsuruRedis.PubSubClient
	config *tsuruRedis.CommonConfig
}

func (factory *redisPubSubFactory) Reset() {
}

func (factory *redisPubSubFactory) PubSub(name string) (PubSubQ, error) {
	return &redisPubSub{name: name, factory: factory}, nil
}

func (factory *redisPubSubFactory) getConn() (tsuruRedis.PubSubClient, error) {
	factory.Lock()
	defer factory.Unlock()
	if factory.pool != nil {
		return factory.pool, nil
	}
	factory.config = &tsuruRedis.CommonConfig{
		PoolSize:     1000,
		PoolTimeout:  2 * time.Second,
		IdleTimeout:  2 * time.Minute,
		MaxRetries:   1,
		DialTimeout:  100 * time.Millisecond,
		ReadTimeout:  30 * time.Minute,
		WriteTimeout: 500 * time.Millisecond,
		TryLegacy:    true,
	}
	client, err := tsuruRedis.NewRedisDefaultConfig("pubsub", factory.config)
	if err == tsuruRedis.ErrNoRedisConfig {
		factory.config.TryLocal = true
		client, err = tsuruRedis.NewRedisDefaultConfig("redis-queue", factory.config)
	}
	if err != nil {
		return nil, err
	}
	var ok bool
	factory.pool, ok = client.(tsuruRedis.PubSubClient)
	if !ok {
		return nil, fmt.Errorf("redis client is not a capable of pubsub: %#v", client)
	}
	return factory.pool, nil
}
<commit_msg>queue: fix data race, it's not safe to unsub while waiting for messages<commit_after>// Copyright 2016 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package queue

import (
	"fmt"
	"sync"
	"time"

	"github.com/tsuru/tsuru/log"
	tsuruRedis "github.com/tsuru/tsuru/redis"
	"gopkg.in/redis.v3"
)

type redisPubSub struct {
	name    string
	prefix  string
	factory *redisPubSubFactory
	psc     *redis.PubSub
}

func (r *redisPubSub) Pub(msg []byte) error {
	conn, err := r.factory.getConn()
	if err != nil {
		return err
	}
	return conn.Publish(r.key(), string(msg)).Err()
}

func (r *redisPubSub) UnSub() error {
	err := r.psc.Close()
	if err != nil {
		return err
	}
	return nil
}

func (r *redisPubSub) Sub() (<-chan []byte, error) {
	conn, err := r.factory.getConn()
	if err != nil {
		return nil, err
	}
	r.psc, err = conn.Subscribe(r.key())
	if err != nil {
		return nil, err
	}
	msgChan := make(chan []byte)
	go func() {
		defer close(msgChan)
		for {
			msg, err := r.psc.ReceiveTimeout(r.factory.config.ReadTimeout)
			if err != nil {
				log.Errorf("Error receiving messages from channel %s: %s", r.key(), err)
				return
			}
			switch v := msg.(type) {
			case *redis.Message:
				msgChan <- []byte(v.Payload)
			case *redis.Subscription:
				if v.Count == 0 {
					return
				}
			}
		}
	}()
	return msgChan, nil
}

func (r *redisPubSub) key() string {
	return r.prefix + ":" + r.name
}

type redisPubSubFactory struct {
	sync.Mutex
	pool   tsuruRedis.PubSubClient
	config *tsuruRedis.CommonConfig
}

func (factory *redisPubSubFactory) Reset() {
}

func (factory *redisPubSubFactory) PubSub(name string) (PubSubQ, error) {
	return &redisPubSub{name: name, factory: factory}, nil
}

func (factory *redisPubSubFactory) getConn() (tsuruRedis.PubSubClient, error) {
	factory.Lock()
	defer factory.Unlock()
	if factory.pool != nil {
		return factory.pool, nil
	}
	factory.config = &tsuruRedis.CommonConfig{
		PoolSize:     1000,
		PoolTimeout:  2 * time.Second,
		IdleTimeout:  2 * time.Minute,
		MaxRetries:   1,
		DialTimeout:  100 * time.Millisecond,
		ReadTimeout:  30 * time.Minute,
		WriteTimeout: 500 * time.Millisecond,
		TryLegacy:    true,
	}
	client, err := tsuruRedis.NewRedisDefaultConfig("pubsub", factory.config)
	if err == tsuruRedis.ErrNoRedisConfig {
		factory.config.TryLocal = true
		client, err = tsuruRedis.NewRedisDefaultConfig("redis-queue", factory.config)
	}
	if err != nil {
		return nil, err
	}
	var ok bool
	factory.pool, ok = client.(tsuruRedis.PubSubClient)
	if !ok {
		return nil, fmt.Errorf("redis client is not a capable of pubsub: %#v", client)
	}
	return factory.pool, nil
}
<|endoftext|>


<commit_before>// Copyright 2014, Joel Scoble, all rights reserved.
// Licensed under The MIT License. Please view the LICENSE file for more
// information.

// Shuffle provides math/rand based shuffling (randomization) of collections
// using the Fisher-Yates (Knuth) shuffling algorithm.  Functions for
// shuffling slices of non-composite types are provided, or you can implement
// the shuffle.Shuffler interface and shuffle using the Shuffle func.
//
// Shuffling is performed on the received slice; nothing is returned and no
// additional allocations are made.
//
// If a CSPRG based shuffle is needed, use the github.com/mohae/shuffle
// package.
package quick

import (
	"crypto/rand"
	"fmt"
	"math/big"

	pcg "github.com/dgryski/go-pcgr"
	"github.com/mohae/shuffle"
)

var rng pcg.Rand

func init() {
	err := Seed()
	if err != nil {
		panic(fmt.Sprintf("entropy read error: %s\n", err))
	}
}

// Seed seeds the rng by getting a new seed value from crypto/rand.  If
// the attempt to get a new seed value results in an error, that will be
// returned.
func Seed() error {
	bi := big.NewInt(1<<63 - 1)
	r, err := rand.Int(rand.Reader, bi)
	if err != nil {
		return err
	}
	rng.Seed(r.Int64())
	return nil
}

// Shuffle randomizes collections
func Shuffle(c shuffle.Shuffler) error {
	l := c.Len()
	for i := l - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		c.Swap(i, j)
	}
	return nil
}

// ShuffleByte randomizes a byte slice.
func ShuffleByte(c []byte) {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
}

// ShuffleComplex64 randomizes a complex64 slice.
func ShuffleComplex64(c []complex64) {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
}

// ShuffleComplex129 randomizes a complex128 slice.
func ShuffleComplex128(c []complex128) {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
}

// ShuffleFloat32 randomizes a float32 slice.
func ShuffleFloat32(c []float32) {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
}

// ShuffleFloat64 randomizes a float64 slice.
func ShuffleFloat64(c []float64) error {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
	return nil
}

// ShuffleInt randomizes an int slice.
func ShuffleInt(c []int) error {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
	return nil
}

// ShuffleInt8 randomizes an int8 slice.
func ShuffleInt8(c []int8) {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
}

// ShuffleInt16 randomizes an int16 slice.
func ShuffleInt16(c []int16) {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
}

// ShuffleInt32 randomizes an int32 slice.
func ShuffleInt32(c []int32) {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		c[j], c[i] = c[i], c[j]
	}
}

// ShuffleInt64 randomizes an int64 slice.
func ShuffleInt64(c []int64) {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
}

// ShuffleString randomizes a strings slice.
func ShuffleString(c []string) error {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
	return nil
}

// ShuffleUint randomizes an uint slice.
func ShuffleUint(c []uint) {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
}

// ShuffleUint8 randomizes an uint8 slice.
func ShuffleUint8(c []uint8) {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
}

// ShuffleUint16 randomizes an uint16 slice.
func ShuffleUint16(c []uint16) {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
}

// ShuffleUint32 randomizes an uint32 slice.
func ShuffleUint32(c []uint32) {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
}

// ShuffleUint64 randomizes an uint64 slice.
func ShuffleUint64(c []uint64) {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
}
<commit_msg>for some implementations: don't do swap if indexes are equal; add error to func quick func sigs for consistency<commit_after>// Copyright 2014, Joel Scoble, all rights reserved.
// Licensed under The MIT License. Please view the LICENSE file for more
// information.

// Shuffle provides math/rand based shuffling (randomization) of collections
// using the Fisher-Yates (Knuth) shuffling algorithm.  Functions for
// shuffling slices of non-composite types are provided, or you can implement
// the shuffle.Shuffler interface and shuffle using the Shuffle func.
//
// Shuffling is performed on the received slice; nothing is returned and no
// additional allocations are made.
//
// If a CSPRG based shuffle is needed, use the github.com/mohae/shuffle
// package.
package quick

import (
	"crypto/rand"
	"fmt"
	"math/big"

	pcg "github.com/dgryski/go-pcgr"
	"github.com/mohae/shuffle"
)

var rng pcg.Rand

func init() {
	err := Seed()
	if err != nil {
		panic(fmt.Sprintf("entropy read error: %s\n", err))
	}
}

// Seed seeds the rng by getting a new seed value from crypto/rand.  If
// the attempt to get a new seed value results in an error, that will be
// returned.
func Seed() error {
	bi := big.NewInt(1<<63 - 1)
	r, err := rand.Int(rand.Reader, bi)
	if err != nil {
		return err
	}
	rng.Seed(r.Int64())
	return nil
}

// Shuffle randomizes collections
func Shuffle(c shuffle.Shuffler) error {
	l := c.Len()
	for i := l - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c.Swap(i, j)
		}
	}
	return nil
}

// ShuffleByte randomizes a byte slice.
func ShuffleByte(c []byte) error {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
	return nil
}

// ShuffleComplex64 randomizes a complex64 slice.
func ShuffleComplex64(c []complex64) error {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
	return nil
}

// ShuffleComplex129 randomizes a complex128 slice.
func ShuffleComplex128(c []complex128) error {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
	return nil
}

// ShuffleFloat32 randomizes a float32 slice.
func ShuffleFloat32(c []float32) error {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
	return nil
}

// ShuffleFloat64 randomizes a float64 slice.
func ShuffleFloat64(c []float64) error {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
	return nil
}

// ShuffleInt randomizes an int slice.
func ShuffleInt(c []int) error {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
	return nil
}

// ShuffleInt8 randomizes an int8 slice.
func ShuffleInt8(c []int8) error {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
	return nil
}

// ShuffleInt16 randomizes an int16 slice.
func ShuffleInt16(c []int16) error {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
	return nil
}

// ShuffleInt32 randomizes an int32 slice.
func ShuffleInt32(c []int32) error {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
	return nil
}

// ShuffleInt64 randomizes an int64 slice.
func ShuffleInt64(c []int64) error {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
	return nil
}

// ShuffleString randomizes a strings slice.
func ShuffleString(c []string) error {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
	return nil
}

// ShuffleUint randomizes an uint slice.
func ShuffleUint(c []uint) error {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
	return nil
}

// ShuffleUint8 randomizes an uint8 slice.
func ShuffleUint8(c []uint8) error {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
	return nil
}

// ShuffleUint16 randomizes an uint16 slice.
func ShuffleUint16(c []uint16) error {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
	return nil
}

// ShuffleUint32 randomizes an uint32 slice.
func ShuffleUint32(c []uint32) error {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
	return nil
}

// ShuffleUint64 randomizes an uint64 slice.
func ShuffleUint64(c []uint64) error {
	for i := len(c) - 1; i >= 0; i-- {
		j := int(rng.Bound(uint32(i + 1)))
		if i != j {
			c[j], c[i] = c[i], c[j]
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"os"

	log "github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
	"github.com/mattbaird/elastigo/api"
)

func main() {
	app := cli.NewApp()
	app.Name = "vossibility-bulleting"
	app.Usage = "generate bulletins from vossibility data"
	app.Version = "0.1.0"

	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:  "debug",
			Usage: "enable debug output",
		},
		cli.StringFlag{
			Name:  "source",
			Usage: "url of the Elastic Search store",
		},
	}

	app.Before = func(c *cli.Context) error {
		if c.GlobalBool("debug") {
			log.SetLevel(log.DebugLevel)
		}
		if s := c.GlobalString("source"); s != "" {
			api.Hosts = append(api.Hosts, s)
		}
		return nil
	}
	app.Commands = []cli.Command{
		generateCommand,
	}

	app.Run(os.Args)
}
<commit_msg>Remove southern french accent<commit_after>package main

import (
	"os"

	log "github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
	"github.com/mattbaird/elastigo/api"
)

func main() {
	app := cli.NewApp()
	app.Name = "vossibility-bulletin"
	app.Usage = "generate bulletins from vossibility data"
	app.Version = "0.1.0"

	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:  "debug",
			Usage: "enable debug output",
		},
		cli.StringFlag{
			Name:  "source",
			Usage: "url of the Elastic Search store",
		},
	}

	app.Before = func(c *cli.Context) error {
		if c.GlobalBool("debug") {
			log.SetLevel(log.DebugLevel)
		}
		if s := c.GlobalString("source"); s != "" {
			api.Hosts = append(api.Hosts, s)
		}
		return nil
	}
	app.Commands = []cli.Command{
		generateCommand,
	}

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


<commit_before>package pivotaltracker

import (
	// Internal
	"github.com/salsaflow/salsaflow/modules/common"
	"github.com/salsaflow/salsaflow/version"

	// Other
	"github.com/salsita/go-pivotaltracker/v5/pivotal"
)

type issueTracker struct {
	config Config
}

func Factory() (common.IssueTracker, error) {
	config, err := LoadConfig()
	if err != nil {
		return nil, err
	}
	return &issueTracker{config}, nil
}

func (tracker *issueTracker) CurrentUser() (common.User, error) {
	me, err := fetchMe()
	if err != nil {
		return nil, err
	}
	return &user{me}, nil
}

func (tracker *issueTracker) StartableStories() (stories []common.Story, err error) {
	ptStories, err := searchStories("(type:%v OR type:%v) AND state:%v",
		pivotal.StoryTypeFeature, pivotal.StoryTypeBug, pivotal.StoryStateUnstarted)
	if err != nil {
		return nil, err
	}

	ptStories = storiesMatchingByLabel(ptStories, tracker.config.IncludeStoryLabelFilter())

	return toCommonStories(ptStories), nil
}

func (tracker *issueTracker) StoriesInDevelopment() (stories []common.Story, err error) {
	ptStories, err := searchStories(
		"(type:%v OR type:%v) AND (state:%v OR state:%v) AND -label:\"%v\" AND -label:\"%v\"",
		pivotal.StoryTypeFeature, pivotal.StoryTypeBug,
		pivotal.StoryStateStarted, pivotal.StoryStateFinished,
		tracker.config.ReviewedLabel(), tracker.config.NoReviewLabel())
	if err != nil {
		return nil, err
	}
	return toCommonStories(ptStories), nil
}

func (tracker *issueTracker) NextRelease(
	trunkVersion *version.Version,
	nextTrunkVersion *version.Version,
) (common.NextRelease, error) {

	return newNextRelease(trunkVersion, nextTrunkVersion)
}

func (tracker *issueTracker) RunningRelease(
	releaseVersion *version.Version,
) (common.RunningRelease, error) {

	return newRunningRelease(releaseVersion)
}

func (tracker *issueTracker) OpenStory(storyId string) error {
	panic("Not implemented")
}
<commit_msg>pivotaltracker: Make sure story open works<commit_after>package pivotaltracker

import (
	// Stdlib
	"fmt"

	// Internal
	"github.com/salsaflow/salsaflow/modules/common"
	"github.com/salsaflow/salsaflow/version"

	// Other
	"github.com/salsita/go-pivotaltracker/v5/pivotal"
	"github.com/toqueteos/webbrowser"
)

type issueTracker struct {
	config Config
}

func Factory() (common.IssueTracker, error) {
	config, err := LoadConfig()
	if err != nil {
		return nil, err
	}
	return &issueTracker{config}, nil
}

func (tracker *issueTracker) CurrentUser() (common.User, error) {
	me, err := fetchMe()
	if err != nil {
		return nil, err
	}
	return &user{me}, nil
}

func (tracker *issueTracker) StartableStories() (stories []common.Story, err error) {
	ptStories, err := searchStories("(type:%v OR type:%v) AND state:%v",
		pivotal.StoryTypeFeature, pivotal.StoryTypeBug, pivotal.StoryStateUnstarted)
	if err != nil {
		return nil, err
	}

	ptStories = storiesMatchingByLabel(ptStories, tracker.config.IncludeStoryLabelFilter())

	return toCommonStories(ptStories), nil
}

func (tracker *issueTracker) StoriesInDevelopment() (stories []common.Story, err error) {
	ptStories, err := searchStories(
		"(type:%v OR type:%v) AND (state:%v OR state:%v) AND -label:\"%v\" AND -label:\"%v\"",
		pivotal.StoryTypeFeature, pivotal.StoryTypeBug,
		pivotal.StoryStateStarted, pivotal.StoryStateFinished,
		tracker.config.ReviewedLabel(), tracker.config.NoReviewLabel())
	if err != nil {
		return nil, err
	}
	return toCommonStories(ptStories), nil
}

func (tracker *issueTracker) NextRelease(
	trunkVersion *version.Version,
	nextTrunkVersion *version.Version,
) (common.NextRelease, error) {

	return newNextRelease(trunkVersion, nextTrunkVersion)
}

func (tracker *issueTracker) RunningRelease(
	releaseVersion *version.Version,
) (common.RunningRelease, error) {

	return newRunningRelease(releaseVersion)
}

func (tracker *issueTracker) OpenStory(storyId string) error {
	return webbrowser.Open(fmt.Sprintf("https://pivotaltracker.com/story/show/%v", storyId))
}
<|endoftext|>


<commit_before>package command

import (
	"encoding/json"
	"io"
	"log"
	"os"
	"time"

	"github.com/aws/aws-sdk-go/service/s3"
	"github.com/nabeken/aaa/agent"
	"github.com/nabeken/aws-go-s3/bucket"
	"github.com/pkg/errors"
)

type LsCommand struct {
	Format string `long:"format" description:"Format the output" default:"json"`
}

func (c *LsCommand) Execute(args []string) error {
	s3b := bucket.New(s3.New(NewAWSSession()), Options.S3Bucket)
	return (&LsService{
		Filer: agent.NewS3Filer(s3b, Options.S3KMSKeyID),
	}).WriteTo(c.Format, os.Stdout)
}

type LsService struct {
	Filer agent.Filer
}

func (svc *LsService) WriteTo(format string, w io.Writer) error {
	output, err := svc.FetchData()
	if err != nil {
		return err
	}
	switch format {
	case "json":
		return json.NewEncoder(w).Encode(output)
	default:
		return errors.Errorf("'%s' is not implemented")
	}
}

func (svc *LsService) FetchData() ([]Domain, error) {
	data := []Domain{}

	emails, err := svc.listAccounts()
	if err != nil {
		return nil, errors.Wrap(err, "failed to list the accounts")
	}

	for _, email := range emails {
		store, err := agent.NewStore(email, svc.Filer)
		if err != nil {
			return nil, errors.Wrap(err, "failed to initialize the store")
		}

		domains, err := store.ListDomains()
		if err != nil {
			return nil, errors.Wrap(err, "failed to list the domains")
		}

		for _, dom := range domains {
			authz, err := store.LoadAuthorization(dom)
			if err != nil {
				log.Printf("failed to load authorization for %s: %s. skipping...", dom, err)
				continue
			}

			cert, err := store.LoadCert(dom)
			if err != nil {
				log.Printf("failed to load certificate for %s: %s (or new-cert is ongoing or this domain is in SAN in other certificates). skipping...", dom, err)
				continue
			}

			data = append(data, Domain{
				Email:  email,
				Domain: dom,
				Authorization: Authorization{
					Expires: authz.GetExpires(),
				},
				Certificate: Certificate{
					NotBefore: cert.NotBefore,
					NotAfter:  cert.NotAfter,
					SAN:       cert.DNSNames,
				},
			})
		}
	}

	return data, nil
}

func (svc *LsService) listAccounts() ([]string, error) {
	dirs, err := svc.Filer.ListDir(agent.StorePrefix)
	if err != nil {
		return nil, err
	}

	accounts := make([]string, 0, len(dirs))
	for _, dir := range dirs {
		elem := svc.Filer.Split(dir)

		// account (email) is in 2nd element
		if len(elem) > 1 {
			accounts = append(accounts, elem[1])
		}
	}

	return accounts, nil
}

type Domain struct {
	Email         string        `json:"email"`
	Domain        string        `json:"domain"`
	Authorization Authorization `json:"authorization"`
	Certificate   Certificate   `json:"certificate"`
}

type Authorization struct {
	Expires time.Time `json:"expires"`
}

type Certificate struct {
	NotBefore time.Time `json:"not_before"`
	NotAfter  time.Time `json:"not_after"`
	SAN       []string  `json:"san"`
}
<commit_msg>ls: strip authorization information since it's no longer relevant for us<commit_after>package command

import (
	"encoding/json"
	"io"
	"log"
	"os"
	"time"

	"github.com/aws/aws-sdk-go/service/s3"
	"github.com/nabeken/aaa/agent"
	"github.com/nabeken/aws-go-s3/bucket"
	"github.com/pkg/errors"
)

type LsCommand struct {
	Format string `long:"format" description:"Format the output" default:"json"`
}

func (c *LsCommand) Execute(args []string) error {
	s3b := bucket.New(s3.New(NewAWSSession()), Options.S3Bucket)
	return (&LsService{
		Filer: agent.NewS3Filer(s3b, Options.S3KMSKeyID),
	}).WriteTo(c.Format, os.Stdout)
}

type LsService struct {
	Filer agent.Filer
}

func (svc *LsService) WriteTo(format string, w io.Writer) error {
	output, err := svc.FetchData()
	if err != nil {
		return err
	}
	switch format {
	case "json":
		return json.NewEncoder(w).Encode(output)
	default:
		return errors.Errorf("'%s' is not implemented")
	}
}

func (svc *LsService) FetchData() ([]Domain, error) {
	data := []Domain{}

	emails, err := svc.listAccounts()
	if err != nil {
		return nil, errors.Wrap(err, "failed to list the accounts")
	}

	for _, email := range emails {
		store, err := agent.NewStore(email, svc.Filer)
		if err != nil {
			return nil, errors.Wrap(err, "failed to initialize the store")
		}

		domains, err := store.ListDomains()
		if err != nil {
			return nil, errors.Wrap(err, "failed to list the domains")
		}

		for _, dom := range domains {
			cert, err := store.LoadCert(dom)
			if err != nil {
				log.Printf("failed to load certificate for %s: %s (or new-cert is ongoing or this domain is in SAN in other certificates). skipping...", dom, err)
				continue
			}

			data = append(data, Domain{
				Email:  email,
				Domain: dom,
				Certificate: Certificate{
					NotBefore: cert.NotBefore,
					NotAfter:  cert.NotAfter,
					SAN:       cert.DNSNames,
				},
			})
		}
	}

	return data, nil
}

func (svc *LsService) listAccounts() ([]string, error) {
	dirs, err := svc.Filer.ListDir(agent.StorePrefix)
	if err != nil {
		return nil, err
	}

	accounts := make([]string, 0, len(dirs))
	for _, dir := range dirs {
		elem := svc.Filer.Split(dir)

		// account (email) is in 2nd element
		if len(elem) > 1 {
			accounts = append(accounts, elem[1])
		}
	}

	return accounts, nil
}

type Domain struct {
	Email       string      `json:"email"`
	Domain      string      `json:"domain"`
	Certificate Certificate `json:"certificate"`
}

type Certificate struct {
	NotBefore time.Time `json:"not_before"`
	NotAfter  time.Time `json:"not_after"`
	SAN       []string  `json:"san"`
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/x509"
	"fmt"
	"github.com/ogier/pflag"
	"github.com/sevenscale/remote_syslog2/papertrail"
	"github.com/sevenscale/remote_syslog2/syslog"
	"github.com/sevenscale/remote_syslog2/utils"
	"io/ioutil"
	"launchpad.net/goyaml"
	"os"
	"regexp"
	"time"
)

const (
	MinimumRefreshInterval = (time.Duration(10) * time.Second)
)

type ConfigFile struct {
	Files       []string
	Destination struct {
		Host     string
		Port     int
		Protocol string
	}
	Hostname string
	//SetYAML is only called on pointers
	RefreshInterval *RefreshInterval `yaml:"refresh"`
	ExcludeFiles    *RegexCollection `yaml:"exclude_files"`
	ExcludePatterns *RegexCollection `yaml:"exclude_patterns"`
}

type ConfigManager struct {
	Config ConfigFile
	Flags  struct {
		Hostname        string
		DestHost        string
		DestPort        int
		ConfigFile      string
		LogLevels       string
		DebugLogFile    string
		PidFile         string
		RefreshInterval RefreshInterval
		UseTCP          bool
		UseTLS          bool
		NoDaemonize     bool
		Severity        string
		Facility        string
	}
}

type RefreshInterval struct {
	Duration time.Duration
}

func (r *RefreshInterval) String() string {
	return fmt.Sprint(*r)
}

func (r *RefreshInterval) Set(value string) error {
	d, err := time.ParseDuration(value)

	if err != nil {
		return err
	}

	if d < MinimumRefreshInterval {
		return fmt.Errorf("refresh interval must be greater than %s", MinimumRefreshInterval)
	}
	r.Duration = d
	return nil
}

func (r *RefreshInterval) SetYAML(tag string, value interface{}) bool {
	err := r.Set(value.(string))
	if err != nil {
		return false
	}
	return true
}

type RegexCollection []*regexp.Regexp

func (r *RegexCollection) Set(value string) error {
	exp, err := regexp.Compile(value)
	if err != nil {
		return err
	}
	*r = append(*r, exp)
	return nil
}

func (r *RegexCollection) String() string {
	return fmt.Sprint(*r)
}

func (r *RegexCollection) SetYAML(tag string, value interface{}) bool {
	items, ok := value.([]interface{})

	if !ok {
		return false
	}

	for _, item := range items {
		s, ok := item.(string)

		if !ok {
			return false
		}

		err := r.Set(s)
		if err != nil {
			panic(fmt.Sprintf("Failed to compile regex expression \"%s\"", s))
		}
	}

	return true
}

func NewConfigManager() ConfigManager {
	cm := ConfigManager{}
	err := cm.Initialize()

	if err != nil {
		log.Criticalf("Failed to configure the application: %s", err)
		os.Exit(1)
	}

	return cm
}

func (cm *ConfigManager) Initialize() error {
	cm.Config.ExcludeFiles = &RegexCollection{}
	cm.Config.ExcludePatterns = &RegexCollection{}
	cm.parseFlags()

	err := cm.readConfig()
	if err != nil {
		return err
	}
	return nil
}

func (cm *ConfigManager) parseFlags() {
	pflag.StringVarP(&cm.Flags.ConfigFile, "configfile", "c", "/etc/log_files.yml", "Path to config")
	pflag.StringVarP(&cm.Flags.DestHost, "dest-host", "d", "", "Destination syslog hostname or IP")
	pflag.IntVarP(&cm.Flags.DestPort, "dest-port", "p", 0, "Destination syslog port")
	if utils.CanDaemonize {
		pflag.BoolVarP(&cm.Flags.NoDaemonize, "no-detach", "D", false, "Don't daemonize and detach from the terminal")
	}
	pflag.StringVarP(&cm.Flags.Facility, "facility", "f", "user", "Facility")
	pflag.StringVar(&cm.Flags.Hostname, "hostname", "", "Local hostname to send from")
	pflag.StringVar(&cm.Flags.PidFile, "pid-file", "/tmp/remote_syslog.pid", "Location of the PID file")
	// --parse-syslog
	pflag.StringVarP(&cm.Flags.Severity, "severity", "s", "notice", "Severity")
	// --strip-color
	pflag.BoolVar(&cm.Flags.UseTCP, "tcp", false, "Connect via TCP (no TLS)")
	pflag.BoolVar(&cm.Flags.UseTLS, "tls", false, "Connect via TCP with TLS")
	pflag.Var(&cm.Flags.RefreshInterval, "new-file-check-interval", "How often to check for new files")
	_ = pflag.Bool("no-eventmachine-tail", false, "No action, provided for backwards compatibility")
	_ = pflag.Bool("eventmachine-tail", false, "No action, provided for backwards compatibility")
	pflag.StringVar(&cm.Flags.DebugLogFile, "debug-log-cfg", "", "the debug log file")
	pflag.StringVar(&cm.Flags.LogLevels, "log", "<root>=INFO", "\"logging configuration <root>=INFO;first=TRACE\"")
	pflag.Parse()
}

func (cm *ConfigManager) readConfig() error {
	log.Infof("Reading configuration file %s", cm.Flags.ConfigFile)
	err := cm.loadConfigFile()
	if err != nil {
		log.Errorf("%s", err)
		return err
	}
	return nil
}

func (cm *ConfigManager) loadConfigFile() error {
	file, err := ioutil.ReadFile(cm.Flags.ConfigFile)
	if err != nil {
		return fmt.Errorf("Could not read the config file: %s", err)
	}

	err = goyaml.Unmarshal(file, &cm.Config)
	if err != nil {
		return fmt.Errorf("Could not parse the config file: %s", err)
	}
	return nil
}

func (cm *ConfigManager) Daemonize() bool {
	return !cm.Flags.NoDaemonize
}

func (cm *ConfigManager) Hostname() string {
	switch {
	case cm.Flags.Hostname != "":
		return cm.Flags.Hostname
	case cm.Config.Hostname != "":
		return cm.Config.Hostname
	default:
		hostname, _ := os.Hostname()
		return hostname
	}
}

func (cm *ConfigManager) RootCAs() *x509.CertPool {
	if cm.DestProtocol() == "tls" && cm.DestHost() == "logs.papertrailapp.com" {
		return papertrail.RootCA()
	} else {
		return nil
	}
}

func (cm *ConfigManager) DestHost() string {
	switch {
	case cm.Flags.DestHost != "":
		return cm.Flags.DestHost
	case cm.Config.Destination.Host != "":
		return cm.Config.Destination.Host
	default:
		return "logs.papertrailapp.com"
	}
}

func (cm ConfigManager) DestPort() int {
	switch {
	case cm.Flags.DestPort != 0:
		return cm.Flags.DestPort
	case cm.Config.Destination.Port != 0:
		return cm.Config.Destination.Port
	default:
		return 514
	}
}

func (cm *ConfigManager) DestProtocol() string {
	switch {
	case cm.Flags.UseTLS:
		return "tls"
	case cm.Flags.UseTCP:
		return "tcp"
	case cm.Config.Destination.Protocol != "":
		return cm.Config.Destination.Protocol
	default:
		return "udp"
	}
}

func (cm *ConfigManager) Severity() syslog.Priority {
	s, err := syslog.Severity(cm.Flags.Severity)
	if err != nil {
		log.Criticalf("%s is not a designated facility", cm.Flags.Severity)
		os.Exit(1)
	}
	return s
}

func (cm *ConfigManager) Facility() syslog.Priority {
	f, err := syslog.Facility(cm.Flags.Facility)
	if err != nil {
		log.Criticalf("%s is not a designated facility", cm.Flags.Facility)
		os.Exit(1)
	}
	return f
}

func (cm *ConfigManager) Files() []string {
	return cm.Config.Files
}

func (cm *ConfigManager) DebugLogFile() string {
	switch {
	case cm.Flags.DebugLogFile != "":
		return cm.Flags.DebugLogFile
	default:
		return "/dev/null"
	}
}

func (cm *ConfigManager) PidFile() string {
	return cm.Flags.PidFile
}

func (cm *ConfigManager) LogLevels() string {
	return cm.Flags.LogLevels
}

func (cm *ConfigManager) RefreshInterval() RefreshInterval {
	switch {
	case cm.Config.RefreshInterval != nil && cm.Flags.RefreshInterval.Duration != 0:
		return cm.Flags.RefreshInterval
	case cm.Config.RefreshInterval != nil:
		return *cm.Config.RefreshInterval
	case cm.Flags.RefreshInterval.Duration != 0:
		return cm.Flags.RefreshInterval
	}
	return RefreshInterval{Duration: MinimumRefreshInterval}
}

func (cm *ConfigManager) ExcludeFiles() []*regexp.Regexp {
	return *cm.Config.ExcludeFiles
}

func (cm *ConfigManager) ExcludePatterns() []*regexp.Regexp {
	return *cm.Config.ExcludePatterns
}
<commit_msg>Copy Ruby remote_syslog pidfile locator<commit_after>package main

import (
	"crypto/x509"
	"fmt"
	"github.com/ogier/pflag"
	"github.com/sevenscale/remote_syslog2/papertrail"
	"github.com/sevenscale/remote_syslog2/syslog"
	"github.com/sevenscale/remote_syslog2/utils"
	"io/ioutil"
	"launchpad.net/goyaml"
	"os"
	"path/filepath"
	"regexp"
	"time"
)

const (
	MinimumRefreshInterval = (time.Duration(10) * time.Second)
)

type ConfigFile struct {
	Files       []string
	Destination struct {
		Host     string
		Port     int
		Protocol string
	}
	Hostname string
	//SetYAML is only called on pointers
	RefreshInterval *RefreshInterval `yaml:"refresh"`
	ExcludeFiles    *RegexCollection `yaml:"exclude_files"`
	ExcludePatterns *RegexCollection `yaml:"exclude_patterns"`
}

type ConfigManager struct {
	Config ConfigFile
	Flags  struct {
		Hostname        string
		DestHost        string
		DestPort        int
		ConfigFile      string
		LogLevels       string
		DebugLogFile    string
		PidFile         string
		RefreshInterval RefreshInterval
		UseTCP          bool
		UseTLS          bool
		NoDaemonize     bool
		Severity        string
		Facility        string
	}
}

type RefreshInterval struct {
	Duration time.Duration
}

func (r *RefreshInterval) String() string {
	return fmt.Sprint(*r)
}

func (r *RefreshInterval) Set(value string) error {
	d, err := time.ParseDuration(value)

	if err != nil {
		return err
	}

	if d < MinimumRefreshInterval {
		return fmt.Errorf("refresh interval must be greater than %s", MinimumRefreshInterval)
	}
	r.Duration = d
	return nil
}

func (r *RefreshInterval) SetYAML(tag string, value interface{}) bool {
	err := r.Set(value.(string))
	if err != nil {
		return false
	}
	return true
}

type RegexCollection []*regexp.Regexp

func (r *RegexCollection) Set(value string) error {
	exp, err := regexp.Compile(value)
	if err != nil {
		return err
	}
	*r = append(*r, exp)
	return nil
}

func (r *RegexCollection) String() string {
	return fmt.Sprint(*r)
}

func (r *RegexCollection) SetYAML(tag string, value interface{}) bool {
	items, ok := value.([]interface{})

	if !ok {
		return false
	}

	for _, item := range items {
		s, ok := item.(string)

		if !ok {
			return false
		}

		err := r.Set(s)
		if err != nil {
			panic(fmt.Sprintf("Failed to compile regex expression \"%s\"", s))
		}
	}

	return true
}

func NewConfigManager() ConfigManager {
	cm := ConfigManager{}
	err := cm.Initialize()

	if err != nil {
		log.Criticalf("Failed to configure the application: %s", err)
		os.Exit(1)
	}

	return cm
}

func (cm *ConfigManager) Initialize() error {
	cm.Config.ExcludeFiles = &RegexCollection{}
	cm.Config.ExcludePatterns = &RegexCollection{}
	cm.parseFlags()

	err := cm.readConfig()
	if err != nil {
		return err
	}
	return nil
}

func (cm *ConfigManager) parseFlags() {
	pflag.StringVarP(&cm.Flags.ConfigFile, "configfile", "c", "/etc/log_files.yml", "Path to config")
	pflag.StringVarP(&cm.Flags.DestHost, "dest-host", "d", "", "Destination syslog hostname or IP")
	pflag.IntVarP(&cm.Flags.DestPort, "dest-port", "p", 0, "Destination syslog port")
	if utils.CanDaemonize {
		pflag.BoolVarP(&cm.Flags.NoDaemonize, "no-detach", "D", false, "Don't daemonize and detach from the terminal")
	}
	pflag.StringVarP(&cm.Flags.Facility, "facility", "f", "user", "Facility")
	pflag.StringVar(&cm.Flags.Hostname, "hostname", "", "Local hostname to send from")
	pflag.StringVar(&cm.Flags.PidFile, "pid-file", "", "Location of the PID file")
	// --parse-syslog
	pflag.StringVarP(&cm.Flags.Severity, "severity", "s", "notice", "Severity")
	// --strip-color
	pflag.BoolVar(&cm.Flags.UseTCP, "tcp", false, "Connect via TCP (no TLS)")
	pflag.BoolVar(&cm.Flags.UseTLS, "tls", false, "Connect via TCP with TLS")
	pflag.Var(&cm.Flags.RefreshInterval, "new-file-check-interval", "How often to check for new files")
	_ = pflag.Bool("no-eventmachine-tail", false, "No action, provided for backwards compatibility")
	_ = pflag.Bool("eventmachine-tail", false, "No action, provided for backwards compatibility")
	pflag.StringVar(&cm.Flags.DebugLogFile, "debug-log-cfg", "", "the debug log file")
	pflag.StringVar(&cm.Flags.LogLevels, "log", "<root>=INFO", "\"logging configuration <root>=INFO;first=TRACE\"")
	pflag.Parse()
}

func (cm *ConfigManager) readConfig() error {
	log.Infof("Reading configuration file %s", cm.Flags.ConfigFile)
	err := cm.loadConfigFile()
	if err != nil {
		log.Errorf("%s", err)
		return err
	}
	return nil
}

func (cm *ConfigManager) loadConfigFile() error {
	file, err := ioutil.ReadFile(cm.Flags.ConfigFile)
	if err != nil {
		return fmt.Errorf("Could not read the config file: %s", err)
	}

	err = goyaml.Unmarshal(file, &cm.Config)
	if err != nil {
		return fmt.Errorf("Could not parse the config file: %s", err)
	}
	return nil
}

func (cm *ConfigManager) Daemonize() bool {
	return !cm.Flags.NoDaemonize
}

func (cm *ConfigManager) Hostname() string {
	switch {
	case cm.Flags.Hostname != "":
		return cm.Flags.Hostname
	case cm.Config.Hostname != "":
		return cm.Config.Hostname
	default:
		hostname, _ := os.Hostname()
		return hostname
	}
}

func (cm *ConfigManager) RootCAs() *x509.CertPool {
	if cm.DestProtocol() == "tls" && cm.DestHost() == "logs.papertrailapp.com" {
		return papertrail.RootCA()
	} else {
		return nil
	}
}

func (cm *ConfigManager) DestHost() string {
	switch {
	case cm.Flags.DestHost != "":
		return cm.Flags.DestHost
	case cm.Config.Destination.Host != "":
		return cm.Config.Destination.Host
	default:
		return "logs.papertrailapp.com"
	}
}

func (cm ConfigManager) DestPort() int {
	switch {
	case cm.Flags.DestPort != 0:
		return cm.Flags.DestPort
	case cm.Config.Destination.Port != 0:
		return cm.Config.Destination.Port
	default:
		return 514
	}
}

func (cm *ConfigManager) DestProtocol() string {
	switch {
	case cm.Flags.UseTLS:
		return "tls"
	case cm.Flags.UseTCP:
		return "tcp"
	case cm.Config.Destination.Protocol != "":
		return cm.Config.Destination.Protocol
	default:
		return "udp"
	}
}

func (cm *ConfigManager) Severity() syslog.Priority {
	s, err := syslog.Severity(cm.Flags.Severity)
	if err != nil {
		log.Criticalf("%s is not a designated facility", cm.Flags.Severity)
		os.Exit(1)
	}
	return s
}

func (cm *ConfigManager) Facility() syslog.Priority {
	f, err := syslog.Facility(cm.Flags.Facility)
	if err != nil {
		log.Criticalf("%s is not a designated facility", cm.Flags.Facility)
		os.Exit(1)
	}
	return f
}

func (cm *ConfigManager) Files() []string {
	return cm.Config.Files
}

func (cm *ConfigManager) DebugLogFile() string {
	switch {
	case cm.Flags.DebugLogFile != "":
		return cm.Flags.DebugLogFile
	default:
		return "/dev/null"
	}
}

func (cm *ConfigManager) defaultPidFile() string {
	pidFiles := []string{
		"/var/run/remote_syslog.pid",
		os.Getenv("HOME") + "/run/remote_syslog.pid",
		os.Getenv("HOME") + "/tmp/remote_syslog.pid",
		os.Getenv("HOME") + "/remote_syslog.pid",
		os.TempDir() + "/remote_syslog.pid",
		os.Getenv("TMPDIR") + "/remote_syslog.pid",
	}
	for _, f := range pidFiles {
		dir := filepath.Dir(f)
		dirStat, err := os.Stat(dir)
		if err != nil || dirStat == nil || !dirStat.IsDir() {
			continue
		}
		fd, err := os.OpenFile(f, os.O_WRONLY|os.O_CREATE, 0644)
		if err != nil {
			continue
		}
		fd.Close()
		return f
	}
	return "/tmp/remote_syslog.pid"
}

func (cm *ConfigManager) PidFile() string {
	switch {
	case cm.Flags.PidFile != "":
		return cm.Flags.PidFile
	default:
		return cm.defaultPidFile()
	}
}

func (cm *ConfigManager) LogLevels() string {
	return cm.Flags.LogLevels
}

func (cm *ConfigManager) RefreshInterval() RefreshInterval {
	switch {
	case cm.Config.RefreshInterval != nil && cm.Flags.RefreshInterval.Duration != 0:
		return cm.Flags.RefreshInterval
	case cm.Config.RefreshInterval != nil:
		return *cm.Config.RefreshInterval
	case cm.Flags.RefreshInterval.Duration != 0:
		return cm.Flags.RefreshInterval
	}
	return RefreshInterval{Duration: MinimumRefreshInterval}
}

func (cm *ConfigManager) ExcludeFiles() []*regexp.Regexp {
	return *cm.Config.ExcludeFiles
}

func (cm *ConfigManager) ExcludePatterns() []*regexp.Regexp {
	return *cm.Config.ExcludePatterns
}
<|endoftext|>


<commit_before><commit_msg>public funding trade raw data mapping to data structure test coverage<commit_after><|endoftext|>


<commit_before>// socket_irix.go -- Socket handling specific to IRIX 6.

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

package syscall

const SizeofSockaddrInet4 = 16
const SizeofSockaddrInet6 = 28
const SizeofSockaddrUnix = 110

type RawSockaddrInet4 struct {
	Family uint16
	Port   uint16
	Addr   [4]byte /* in_addr */
	Zero   [8]uint8
}

func (sa *RawSockaddrInet4) setLen() Socklen_t {
	return SizeofSockaddrInet4
}

type RawSockaddrInet6 struct {
	Family   uint16
	Port     uint16
	Flowinfo uint32
	Addr     [16]byte /* in6_addr */
	Scope_id uint32
}

func (sa *RawSockaddrInet6) setLen() Socklen_t {
	return SizeofSockaddrInet6
}

type RawSockaddrUnix struct {
	Family uint16
	Path   [108]int8
}

func (sa *RawSockaddrUnix) setLen(int) {
}

func (sa *RawSockaddrUnix) getLen() (int, error) {
	if sa.Path[0] == 0 {
		// "Abstract" Unix domain socket.
		// Rewrite leading NUL as @ for textual display.
		// (This is the standard convention.)
		// Not friendly to overwrite in place,
		// but the callers below don't care.
		sa.Path[0] = '@'
	}

	// Assume path ends at NUL.
	// This is not technically the GNU/Linux semantics for
	// abstract Unix domain sockets--they are supposed
	// to be uninterpreted fixed-size binary blobs--but
	// everyone uses this convention.
	n := 0
	for n < len(sa.Path)-3 && sa.Path[n] != 0 {
		n++
	}

	return n, nil
}

type RawSockaddr struct {
	Family uint16
	Data   [14]int8
}

// BindToDevice binds the socket associated with fd to device.
func BindToDevice(fd int, device string) (err error) {
	return ENOSYS
}

// struct ip_mreg is provived in <netinet/in.h>, but protected with _SGIAPI.
// This could be enabled with -D_SGI_SOURCE, but conflicts with
// -D_XOPEN_SOURCE=500 required for msg_control etc. in struct msghgr, so
// simply provide it here.
type IPMreq struct {
	Multiaddr [4]byte
	Interface [4]byte
}

// Similarly, <netdb.h> only provides struct addrinfo, AI_* and EAI_* if
// _NO_XOPEN4 && _NO_XOPEN5.
type Addrinfo struct {
	Ai_flags int32
	Ai_family int32
	Ai_socktype int32
	Ai_protocol int32
	Ai_addrlen int32
	Ai_canonname *uint8
	Ai_addr *_sockaddr
	Ai_next *Addrinfo
}

const (
	AI_PASSIVE	= 0x00000001
	AI_CANONNAME	= 0x00000002
	AI_NUMERICHOST	= 0x00000004
	AI_NUMERICSERV	= 0x00000008
	AI_ALL		= 0x00000100
	AI_ADDRCONFIG	= 0x00000400
	AI_V4MAPPED	= 0x00000800
	AI_DEFAULT	= (AI_V4MAPPED | AI_ADDRCONFIG)
)

const (
	EAI_ADDRFAMILY	=  1
	EAI_AGAIN	=  2
	EAI_BADFLAGS	=  3
	EAI_FAIL	=  4
	EAI_FAMILY	=  5
	EAI_MEMORY	=  6
	EAI_NODATA	=  7
	EAI_NONAME	=  8
	EAI_SERVICE	=  9
	EAI_SOCKTYPE	= 10
	EAI_SYSTEM	= 11
	EAI_BADHINTS	= 12
	EAI_OVERFLOW	= 13
	EAI_MAX		= 14
)

func anyToSockaddrOS(rsa *RawSockaddrAny) (Sockaddr, error) {
	return nil, EAFNOSUPPORT
}
<commit_msg>syscall: Don't define IPMreq in socket_irix.go.<commit_after>// socket_irix.go -- Socket handling specific to IRIX 6.

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

package syscall

const SizeofSockaddrInet4 = 16
const SizeofSockaddrInet6 = 28
const SizeofSockaddrUnix = 110

type RawSockaddrInet4 struct {
	Family uint16
	Port   uint16
	Addr   [4]byte /* in_addr */
	Zero   [8]uint8
}

func (sa *RawSockaddrInet4) setLen() Socklen_t {
	return SizeofSockaddrInet4
}

type RawSockaddrInet6 struct {
	Family   uint16
	Port     uint16
	Flowinfo uint32
	Addr     [16]byte /* in6_addr */
	Scope_id uint32
}

func (sa *RawSockaddrInet6) setLen() Socklen_t {
	return SizeofSockaddrInet6
}

type RawSockaddrUnix struct {
	Family uint16
	Path   [108]int8
}

func (sa *RawSockaddrUnix) setLen(int) {
}

func (sa *RawSockaddrUnix) getLen() (int, error) {
	if sa.Path[0] == 0 {
		// "Abstract" Unix domain socket.
		// Rewrite leading NUL as @ for textual display.
		// (This is the standard convention.)
		// Not friendly to overwrite in place,
		// but the callers below don't care.
		sa.Path[0] = '@'
	}

	// Assume path ends at NUL.
	// This is not technically the GNU/Linux semantics for
	// abstract Unix domain sockets--they are supposed
	// to be uninterpreted fixed-size binary blobs--but
	// everyone uses this convention.
	n := 0
	for n < len(sa.Path)-3 && sa.Path[n] != 0 {
		n++
	}

	return n, nil
}

type RawSockaddr struct {
	Family uint16
	Data   [14]int8
}

// BindToDevice binds the socket associated with fd to device.
func BindToDevice(fd int, device string) (err error) {
	return ENOSYS
}

// <netdb.h> only provides struct addrinfo, AI_* and EAI_* if  _NO_XOPEN4
// && _NO_XOPEN5, but -D_XOPEN_SOURCE=500 is required for msg_control etc.
// in struct msghgr, so simply provide them here.
type Addrinfo struct {
	Ai_flags     int32
	Ai_family    int32
	Ai_socktype  int32
	Ai_protocol  int32
	Ai_addrlen   int32
	Ai_canonname *uint8
	Ai_addr      *_sockaddr
	Ai_next      *Addrinfo
}

const (
	AI_PASSIVE     = 0x00000001
	AI_CANONNAME   = 0x00000002
	AI_NUMERICHOST = 0x00000004
	AI_NUMERICSERV = 0x00000008
	AI_ALL         = 0x00000100
	AI_ADDRCONFIG  = 0x00000400
	AI_V4MAPPED    = 0x00000800
	AI_DEFAULT     = (AI_V4MAPPED | AI_ADDRCONFIG)
)

const (
	EAI_ADDRFAMILY = 1
	EAI_AGAIN      = 2
	EAI_BADFLAGS   = 3
	EAI_FAIL       = 4
	EAI_FAMILY     = 5
	EAI_MEMORY     = 6
	EAI_NODATA     = 7
	EAI_NONAME     = 8
	EAI_SERVICE    = 9
	EAI_SOCKTYPE   = 10
	EAI_SYSTEM     = 11
	EAI_BADHINTS   = 12
	EAI_OVERFLOW   = 13
	EAI_MAX        = 14
)

func anyToSockaddrOS(rsa *RawSockaddrAny) (Sockaddr, error) {
	return nil, EAFNOSUPPORT
}
<|endoftext|>


<commit_before>package php

import "gutscript/ast"
import "strconv"
import "strings"
import "fmt"

type Visitor struct {
	indent int
}

func (self *Visitor) IndentSpace() string {
	if self.indent == 0 {
		return ""
	}
	return strings.Repeat("    ", self.indent)
}

func (self *Visitor) Visit(n ast.Node) (out string) {
	// fmt.Printf("visit %#v\n", n)
	if stmts, ok := n.(*ast.StatementList); ok {
		for _, stmt := range *stmts {
			out += self.IndentSpace() + self.Visit(stmt)
		}
		return out
	}
	if variable, ok := n.(ast.Variable); ok {
		return "$" + variable.Identifier
	}
	if number, ok := n.(ast.Number); ok {
		return strconv.FormatInt(number.Val, 10)
	}
	if floating, ok := n.(ast.FloatingNumber); ok {
		return strconv.FormatFloat(floating.Val, 'e', -1, 64)
	}

	if expr, ok := n.(ast.UnaryExpr); ok {
		if expr.Op != 0 {
			return fmt.Sprintf("%c%s", expr.Op, self.Visit(expr.Val))
		} else {
			return self.Visit(expr.Val)
		}
	}
	if expr, ok := n.(ast.Expr); ok {
		if expr.Parenthesis {
			return fmt.Sprintf("(%s %c %s)", self.Visit(expr.Left), expr.Op, self.Visit(expr.Right))
		}
		return fmt.Sprintf("%s %c %s", self.Visit(expr.Left), expr.Op, self.Visit(expr.Right))
	}

	if stmt, ok := n.(ast.Assignment); ok {
		return self.IndentSpace() + self.Visit(stmt.Variable) + " = " + self.Visit(stmt.Expr) + ";\n"
	}

	if cls, ok := n.(ast.Class); ok {
		out = "class " + cls.Name

		if cls.Super != nil {
			out += " extends " + *cls.Super
		}

		if len(cls.Interfaces) > 0 {
			out += " implements "
			out += strings.Join(cls.Interfaces, ", ")
		}

		out += " {\n"
		if cls.Body != nil {
			self.indent++
			out += self.Visit(cls.Body)
			self.indent--
		}
		out += "}\n"
		return out
	}
	if member, ok := n.(ast.ClassMember); ok {
		out += self.IndentSpace() + "public $" + member.Name
		if member.Value != nil {
			out += " = " + self.Visit(member.Value)
		}
		out += ";\n"
		return out
	}
	if stmt, ok := n.(*ast.IfStatement); ok {
		out += self.IndentSpace() + "if ( " + self.Visit(stmt.Expr) + " ) {\n"
		self.indent++
		out += self.Visit(stmt.Body)
		self.indent--
		out += self.IndentSpace() + "}"

		if len(stmt.ElseIfList) > 0 {
			for _, elseifStmt := range stmt.ElseIfList {
				out += self.Visit(elseifStmt)
			}
		}
		if stmt.ElseBody != nil {
			out += " else {\n"
			self.indent++
			out += self.Visit(stmt.ElseBody)
			self.indent--
			out += "}"
		}
		out += "\n"
		return out
	}
	if stmt, ok := n.(ast.ElseIfStatement); ok {
		out += self.IndentSpace() + " elseif ( " + self.Visit(stmt.Expr) + " ) {\n"
		self.indent++
		out += self.Visit(stmt.Body)
		self.indent--
		out += self.IndentSpace() + "}"
		return out
	}
	if stmt, ok := n.(ast.ReturnStatement); ok {
		return self.IndentSpace() + "return " + self.Visit(stmt.Expr) + ";\n"
	}
	if stmt, ok := n.(ast.ExprStatement); ok {
		return self.IndentSpace() + self.Visit(stmt.Expr) + ";\n"
	}
	if fnc, ok := n.(ast.FunctionCall); ok {
		out = fnc.Name + "("
		fields := []string{}
		for _, param := range fnc.Params {
			fields = append(fields, self.Visit(param))
		}
		out += strings.Join(fields, ", ")
		out += ")"
		return out
	}
	if fn, ok := n.(ast.Function); ok {
		out += self.IndentSpace() + "function " + fn.Name + "("
		if len(fn.Params) > 0 {
			fields := []string{}
			for _, param := range fn.Params {
				field := "$" + param.Name
				if param.Type != "" {
					field = param.Type + " " + field
				}
				if param.Default != nil {
					field += " = " + self.Visit(param.Default)
				}
				fields = append(fields, field)
			}
			out += strings.Join(fields, ", ")
		}
		out += ") {\n"
		self.indent++
		out += self.Visit(fn.Body)
		self.indent--
		out += self.IndentSpace() + "}\n"
		return out
	}
	return ""
}
<commit_msg>Convert last ExprStatement to ReturnStatement.<commit_after>package php

import "gutscript/ast"
import "strconv"
import "strings"
import "fmt"

type Visitor struct {
	indent int
}

func (self *Visitor) IndentSpace() string {
	if self.indent == 0 {
		return ""
	}
	return strings.Repeat("    ", self.indent)
}

func (self *Visitor) Visit(n ast.Node) (out string) {
	// fmt.Printf("visit %#v\n", n)
	if stmts, ok := n.(*ast.StatementList); ok {
		var stmtlen = len(*stmts)
		for i, stmt := range *stmts {
			if _, ok := stmt.(ast.ExprStatement); ok && i+1 == stmtlen {
				out += self.IndentSpace() + "return " + self.Visit(stmt)
			} else {
				out += self.IndentSpace() + self.Visit(stmt)
			}
		}
		return out
	}
	if variable, ok := n.(ast.Variable); ok {
		return "$" + variable.Identifier
	}
	if number, ok := n.(ast.Number); ok {
		return strconv.FormatInt(number.Val, 10)
	}
	if floating, ok := n.(ast.FloatingNumber); ok {
		return strconv.FormatFloat(floating.Val, 'e', -1, 64)
	}

	if expr, ok := n.(ast.UnaryExpr); ok {
		if expr.Op != 0 {
			return fmt.Sprintf("%c%s", expr.Op, self.Visit(expr.Val))
		} else {
			return self.Visit(expr.Val)
		}
	}
	if expr, ok := n.(ast.Expr); ok {
		if expr.Parenthesis {
			return fmt.Sprintf("(%s %c %s)", self.Visit(expr.Left), expr.Op, self.Visit(expr.Right))
		}
		return fmt.Sprintf("%s %c %s", self.Visit(expr.Left), expr.Op, self.Visit(expr.Right))
	}

	if stmt, ok := n.(ast.Assignment); ok {
		return self.IndentSpace() + self.Visit(stmt.Variable) + " = " + self.Visit(stmt.Expr) + ";\n"
	}

	if cls, ok := n.(ast.Class); ok {
		out = "class " + cls.Name

		if cls.Super != nil {
			out += " extends " + *cls.Super
		}

		if len(cls.Interfaces) > 0 {
			out += " implements "
			out += strings.Join(cls.Interfaces, ", ")
		}

		out += " {\n"
		if cls.Body != nil {
			self.indent++
			out += self.Visit(cls.Body)
			self.indent--
		}
		out += "}\n"
		return out
	}
	if member, ok := n.(ast.ClassMember); ok {
		out += self.IndentSpace() + "public $" + member.Name
		if member.Value != nil {
			out += " = " + self.Visit(member.Value)
		}
		out += ";\n"
		return out
	}
	if stmt, ok := n.(*ast.IfStatement); ok {
		out += self.IndentSpace() + "if ( " + self.Visit(stmt.Expr) + " ) {\n"
		self.indent++
		out += self.Visit(stmt.Body)
		self.indent--
		out += self.IndentSpace() + "}"

		if len(stmt.ElseIfList) > 0 {
			for _, elseifStmt := range stmt.ElseIfList {
				out += self.Visit(elseifStmt)
			}
		}
		if stmt.ElseBody != nil {
			out += " else {\n"
			self.indent++
			out += self.Visit(stmt.ElseBody)
			self.indent--
			out += "}"
		}
		out += "\n"
		return out
	}
	if stmt, ok := n.(ast.ElseIfStatement); ok {
		out += self.IndentSpace() + " elseif ( " + self.Visit(stmt.Expr) + " ) {\n"
		self.indent++
		out += self.Visit(stmt.Body)
		self.indent--
		out += self.IndentSpace() + "}"
		return out
	}
	if stmt, ok := n.(ast.ReturnStatement); ok {
		return self.IndentSpace() + "return " + self.Visit(stmt.Expr) + ";\n"
	}
	if stmt, ok := n.(ast.ExprStatement); ok {
		return self.IndentSpace() + self.Visit(stmt.Expr) + ";\n"
	}
	if fnc, ok := n.(ast.FunctionCall); ok {
		out = fnc.Name + "("
		fields := []string{}
		for _, param := range fnc.Params {
			fields = append(fields, self.Visit(param))
		}
		out += strings.Join(fields, ", ")
		out += ")"
		return out
	}
	if fn, ok := n.(ast.Function); ok {
		out += self.IndentSpace() + "function " + fn.Name + "("
		if len(fn.Params) > 0 {
			fields := []string{}
			for _, param := range fn.Params {
				field := "$" + param.Name
				if param.Type != "" {
					field = param.Type + " " + field
				}
				if param.Default != nil {
					field += " = " + self.Visit(param.Default)
				}
				fields = append(fields, field)
			}
			out += strings.Join(fields, ", ")
		}
		out += ") {\n"
		self.indent++
		out += self.Visit(fn.Body)
		self.indent--
		out += self.IndentSpace() + "}\n"
		return out
	}
	return ""
}
<|endoftext|>


<commit_before>package class

type AccessFlags struct {
    accessFlags uint16
}
<commit_msg>access flags<commit_after>package class

const (
    ACC_PUBLIC          = 0x0001
    ACC_PRIVATE         = 0x0002
    ACC_PROTECTED       = 0x0004
    ACC_STATIC          = 0x0008
    ACC_FINAL           = 0x0010
    ACC_SUPER           = 0x0020
    ACC_SYNCHRONIZED    = 0x0020
    ACC_VOLATILE        = 0x0040
    ACC_BRIDGE          = 0x0040
    ACC_TRANSIENT       = 0x0080
    ACC_VARARGS         = 0x0080
    ACC_NATIVE          = 0x0100
    ACC_INTERFACE       = 0x0200
    ACC_ABSTRACT        = 0x0400
    ACC_STRICT          = 0x0800
    ACC_SYNTHETIC       = 0x1000
    ACC_ANNOTATION      = 0x2000
    ACC_ENUM            = 0x4000
)

type AccessFlags struct {
    accessFlags uint16
}

func (self *AccessFlags) isPublic() (bool) {
    return 0 != self.accessFlags & ACC_PUBLIC
}
func (self *AccessFlags) isPrivate() (bool) {
    return 0 != self.accessFlags & ACC_PRIVATE
}
func (self *AccessFlags) isProtected() (bool) {
    return 0 != self.accessFlags & ACC_PROTECTED
}
func (self *AccessFlags) isStatic() (bool) {
    return 0 != self.accessFlags & ACC_STATIC
}
func (self *AccessFlags) isFinal() (bool) {
    return 0 != self.accessFlags & ACC_FINAL
}
func (self *AccessFlags) isSuper() (bool) {
    return 0 != self.accessFlags & ACC_SUPER
}
func (self *AccessFlags) isSynchronized() (bool) {
    return 0 != self.accessFlags & ACC_SYNCHRONIZED
}
func (self *AccessFlags) isVolatile() (bool) {
    return 0 != self.accessFlags & ACC_VOLATILE
}
func (self *AccessFlags) isBridge() (bool) {
    return 0 != self.accessFlags & ACC_BRIDGE
}
func (self *AccessFlags) isTransient() (bool) {
    return 0 != self.accessFlags & ACC_TRANSIENT
}
func (self *AccessFlags) isVarargs() (bool) {
    return 0 != self.accessFlags & ACC_VARARGS
}
func (self *AccessFlags) isNative() (bool) {
    return 0 != self.accessFlags & ACC_NATIVE
}
func (self *AccessFlags) isInterface() (bool) {
    return 0 != self.accessFlags & ACC_INTERFACE
}
func (self *AccessFlags) isAbstract() (bool) {
    return 0 != self.accessFlags & ACC_ABSTRACT
}
func (self *AccessFlags) isStrict() (bool) {
    return 0 != self.accessFlags & ACC_STRICT
}
func (self *AccessFlags) isSynthetic() (bool) {
    return 0 != self.accessFlags & ACC_SYNTHETIC
}
func (self *AccessFlags) isAnnotation() (bool) {
    return 0 != self.accessFlags & ACC_ANNOTATION
}
func (self *AccessFlags) isEnum() (bool) {
    return 0 != self.accessFlags & ACC_ENUM
}
<|endoftext|>


<commit_before>package database

import (
	"database/sql"
	"fmt"
	"log"

	_ "github.com/olt/libpq"

	"github.com/seadsystem/Backend/DB/landingzone/constants"
	"github.com/seadsystem/Backend/DB/landingzone/decoders"
)

type DB struct {
	conn *sql.DB
}

func New() (DB, error) {
	conn, err := sql.Open("postgres", fmt.Sprintf("host=%s user=%s dbname=%s password=%s port=%d sslmode=disable", constants.DB_SOCKET, constants.DB_USER, constants.DB_NAME, constants.DB_PASSWORD, constants.DB_PORT))
	return DB{conn}, err
}

func (db DB) InsertRaw(database_channel <-chan decoders.SeadPacket) {
	// Example code: https://github.com/olt/pq/blob/bulk/copy_test.go
	stmt, err := db.conn.Prepare("COPY data_raw (serial, type, data, time) FROM STDIN")
	if err != nil {
		log.Fatal(err)
	}

	for {
		log.Println("Waiting for data...")
		data := <-database_channel
		log.Println("Inserting data...")
		log.Printf("Data: %+v\n", data)
		_, err = stmt.Exec(data.Serial, data.Type, data.Data, data.Timestamp)
		if err != nil {
			log.Println(err)
			continue
		}
		_, err = stmt.Exec()
		if err != nil {
			log.Println(err)
			continue
		}
	}
}
<commit_msg>Changed bulk insert to use stock pq instead of forked pq.<commit_after>package database

import (
	"database/sql"
	"fmt"
	"log"

	_ "github.com/lib/pq"

	"github.com/seadsystem/Backend/DB/landingzone/constants"
	"github.com/seadsystem/Backend/DB/landingzone/decoders"
)

type DB struct {
	conn *sql.DB
}

var Timeout = errors.New("Action timed out.")

func New() (DB, error) {
	conn, err := sql.Open("postgres", fmt.Sprintf("host=%s user=%s dbname=%s password=%s port=%d sslmode=disable", constants.DB_SOCKET, constants.DB_USER, constants.DB_NAME, constants.DB_PASSWORD, constants.DB_PORT))
	return DB{conn}, err
}

func (db DB) InsertRaw(database_channel <-chan decoders.SeadPacket) {
	// Infinite loop with no breaks.
	for {
		log.Println("Waiting for data...")
		data := <-database_channel // Wait for first piece of data before starting transaction
		log.Println("Got data.")

		// Begin transaction
		txn, err := db.Begin()
		if err != nil {
			log.Fatal(err)
		}

		// Prepare statement
		stmt, err := txn.Prepare(pq.CopyIn("data_raw", "serial", "type", "data", "time"))
		if err != nil {
			log.Fatal(err)
		}

	Data_processing:
		for {
			// Process data
			_, err = stmt.Exec(data.Serial, data.Type, data.Data, data.Timestamp)
			if err != nil {
				log.Println(err)
			}

			log.Println("Waiting for more data...")

			// Receive result of read
			select {
			case data = <-database_channel:
				// Read resulted in data
				log.Println("Got data.")
			case <-time.After(time.Second * 30):
				log.Println("Transaction timed out.")
				break Data_processing
			}
		}

		log.Println("Closing off transaction...")

		// Flush buffer
		_, err = stmt.Exec()
		if err != nil {
			log.Fatal(err)
		}

		// Close prepared statement
		err = stmt.Close()
		if err != nil {
			log.Fatal(err)
		}

		// Commit transaction
		err = txn.Commit()
		if err != nil {
			log.Fatal(err)
		}

		log.Println("Transaction closed")
	}
}
<|endoftext|>