<commit_before>// +build !lambdabinary

package sparta

import (
	"fmt"
	"log"
	"os"
	"time"

	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
)

func platformLogSysInfo(lambdaFunc string, logger *logrus.Logger) {
	// NOP
}

// RegisterCodePipelineEnvironment is part of a CodePipeline deployment
// and defines the environments available for deployment. Environments
// are defined the `environmentName`. The values defined in the
// environmentVariables are made available to each service as
// environment variables. The environment key will be transformed into
// a configuration file for a CodePipeline CloudFormation action:
// TemplateConfiguration: !Sub "TemplateSource::${environmentName}".
func RegisterCodePipelineEnvironment(environmentName string,
	environmentVariables map[string]string) error {
	if _, exists := codePipelineEnvironments[environmentName]; exists {
		return errors.Errorf("Environment (%s) has already been defined", environmentName)
	}
	codePipelineEnvironments[environmentName] = environmentVariables
	return nil
}

// NewLoggerWithFormatter returns a logger with the given formatter. If formatter
// is nil, a TTY-aware formatter is used
func NewLoggerWithFormatter(level string, formatter logrus.Formatter) (*logrus.Logger, error) {
	logger := logrus.New()
	// If there is an environment override, use that
	envLogLevel := os.Getenv(envVarLogLevel)
	if envLogLevel != "" {
		level = envLogLevel
	}

	logLevel, err := logrus.ParseLevel(level)
	if err != nil {
		return nil, err
	}

	logger.Level = logLevel
	if nil != formatter {
		logger.Formatter = formatter
	}
	logger.Out = os.Stdout
	return logger, nil
}

// Main defines the primary handler for transforming an application into a Sparta package.  The
// serviceName is used to uniquely identify your service within a region and will
// be used for subsequent updates.  For provisioning, ensure that you've
// properly configured AWS credentials for the golang SDK.
// See http://docs.aws.amazon.com/sdk-for-go/api/aws/defaults.html#DefaultChainCredentials-constant
// for more information.
func Main(serviceName string, serviceDescription string, lambdaAWSInfos []*LambdaAWSInfo, api *API, site *S3Site) error {
	return MainEx(serviceName,
		serviceDescription,
		lambdaAWSInfos,
		api,
		site,
		nil,
		false)
}

// MainEx provides an "extended" Main that supports customizing the standard Sparta
// workflow via the `workflowHooks` parameter.
func MainEx(serviceName string,
	serviceDescription string,
	lambdaAWSInfos []*LambdaAWSInfo,
	api *API,
	site *S3Site,
	workflowHooks *WorkflowHooks,
	useCGO bool) error {
	//////////////////////////////////////////////////////////////////////////////
	// cmdRoot defines the root, non-executable command
	CommandLineOptions.Root.Short = fmt.Sprintf("%s - Sparta v.%s powered AWS Lambda Microservice",
		serviceName,
		SpartaVersion)
	CommandLineOptions.Root.Long = serviceDescription
	CommandLineOptions.Root.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
		// Save the ServiceName in case a custom command wants it
		OptionsGlobal.ServiceName = serviceName
		OptionsGlobal.ServiceDescription = serviceDescription

		validateErr := validate.Struct(OptionsGlobal)
		if nil != validateErr {
			return validateErr
		}

		// Format?
		// Running in AWS?
		disableColors := OptionsGlobal.DisableColors || isRunningInAWS()
		var formatter logrus.Formatter
		switch OptionsGlobal.LogFormat {
		case "text", "txt":
			formatter = &logrus.TextFormatter{
				DisableColors: disableColors,
				FullTimestamp: OptionsGlobal.TimeStamps,
			}
		case "json":
			formatter = &logrus.JSONFormatter{}
			disableColors = true
		}
		logger, loggerErr := NewLoggerWithFormatter(OptionsGlobal.LogLevel, formatter)
		if nil != loggerErr {
			return loggerErr
		}
		// Any hooks?
		hookErr := applyLoggerHooks(serviceName, workflowHooks, logger)
		if hookErr != nil {
			return hookErr
		}
		// This is a NOP, but makes megacheck happy b/c it doesn't know about
		// build flags
		platformLogSysInfo("", logger)
		OptionsGlobal.Logger = logger
		welcomeMessage := fmt.Sprintf("Service: %s", serviceName)

		// Header information...
		displayPrettyHeader(headerDivider, disableColors, logger)
		// Metadata about the build...
		logger.WithFields(logrus.Fields{
			"Option":    cmd.Name(),
			"UTC":       (time.Now().UTC().Format(time.RFC3339)),
			"LinkFlags": OptionsGlobal.LinkerFlags,
		}).Info(welcomeMessage)
		logger.Info(headerDivider)

		return nil
	}

	//////////////////////////////////////////////////////////////////////////////
	// Version
	CommandLineOptions.Root.AddCommand(CommandLineOptions.Version)

	//////////////////////////////////////////////////////////////////////////////
	// Provision
	CommandLineOptions.Provision.PreRunE = func(cmd *cobra.Command, args []string) error {
		validateErr := validate.Struct(optionsProvision)

		OptionsGlobal.Logger.WithFields(logrus.Fields{
			"validateErr":      validateErr,
			"optionsProvision": optionsProvision,
		}).Debug("Provision validation results")
		return validateErr
	}

	if nil == CommandLineOptions.Provision.RunE {
		CommandLineOptions.Provision.RunE = func(cmd *cobra.Command, args []string) error {
			buildID, buildIDErr := provisionBuildID(optionsProvision.BuildID, OptionsGlobal.Logger)
			if nil != buildIDErr {
				return buildIDErr
			}
			// Save the BuildID
			StampedBuildID = buildID
			return Provision(OptionsGlobal.Noop,
				serviceName,
				serviceDescription,
				lambdaAWSInfos,
				api,
				site,
				optionsProvision.S3Bucket,
				useCGO,
				optionsProvision.InPlace,
				buildID,
				optionsProvision.PipelineTrigger,
				OptionsGlobal.BuildTags,
				OptionsGlobal.LinkerFlags,
				nil,
				workflowHooks,
				OptionsGlobal.Logger)
		}
	}
	CommandLineOptions.Root.AddCommand(CommandLineOptions.Provision)

	//////////////////////////////////////////////////////////////////////////////
	// Delete
	CommandLineOptions.Delete.RunE = func(cmd *cobra.Command, args []string) error {
		return Delete(serviceName, OptionsGlobal.Logger)
	}

	CommandLineOptions.Root.AddCommand(CommandLineOptions.Delete)

	//////////////////////////////////////////////////////////////////////////////
	// Execute
	if nil == CommandLineOptions.Execute.RunE {
		CommandLineOptions.Execute.RunE = func(cmd *cobra.Command, args []string) error {

			OptionsGlobal.Logger.Formatter = new(logrus.JSONFormatter)
			// Ensure the discovery service is initialized
			initializeDiscovery(OptionsGlobal.Logger)

			return Execute(serviceName,
				lambdaAWSInfos,
				OptionsGlobal.Logger)
		}
	}
	CommandLineOptions.Root.AddCommand(CommandLineOptions.Execute)

	//////////////////////////////////////////////////////////////////////////////
	// Describe
	if nil == CommandLineOptions.Describe.RunE {
		CommandLineOptions.Describe.RunE = func(cmd *cobra.Command, args []string) error {
			validateErr := validate.Struct(optionsDescribe)
			if nil != validateErr {
				return validateErr
			}

			fileWriter, fileWriterErr := os.Create(optionsDescribe.OutputFile)
			if fileWriterErr != nil {
				return fileWriterErr
			}
			defer fileWriter.Close()
			describeErr := Describe(serviceName,
				serviceDescription,
				lambdaAWSInfos,
				api,
				site,
				optionsDescribe.S3Bucket,
				OptionsGlobal.BuildTags,
				OptionsGlobal.LinkerFlags,
				fileWriter,
				workflowHooks,
				OptionsGlobal.Logger)

			if describeErr == nil {
				describeErr = fileWriter.Sync()
			}
			return describeErr
		}
	}
	CommandLineOptions.Root.AddCommand(CommandLineOptions.Describe)

	//////////////////////////////////////////////////////////////////////////////
	// Explore
	if nil == CommandLineOptions.Explore.RunE {
		CommandLineOptions.Explore.RunE = func(cmd *cobra.Command, args []string) error {
			validateErr := validate.Struct(optionsExplore)
			if nil != validateErr {
				return validateErr
			}

			return Explore(serviceName,
				serviceDescription,
				lambdaAWSInfos,
				api,
				site,
				optionsDescribe.S3Bucket,
				OptionsGlobal.BuildTags,
				OptionsGlobal.LinkerFlags,
				OptionsGlobal.Logger)
		}
	}
	CommandLineOptions.Root.AddCommand(CommandLineOptions.Explore)

	//////////////////////////////////////////////////////////////////////////////
	// Profile
	if nil == CommandLineOptions.Profile.RunE {
		CommandLineOptions.Profile.RunE = func(cmd *cobra.Command, args []string) error {
			validateErr := validate.Struct(optionsProfile)
			if nil != validateErr {
				return validateErr
			}
			return Profile(serviceName,
				serviceDescription,
				optionsProfile.S3Bucket,
				optionsProfile.Port,
				OptionsGlobal.Logger)
		}
	}
	CommandLineOptions.Root.AddCommand(CommandLineOptions.Profile)

	//////////////////////////////////////////////////////////////////////////////
	// Status
	if nil == CommandLineOptions.Status.RunE {
		CommandLineOptions.Status.RunE = func(cmd *cobra.Command, args []string) error {
			validateErr := validate.Struct(optionsStatus)
			if nil != validateErr {
				return validateErr
			}
			return Status(serviceName,
				serviceDescription,
				optionsStatus.Redact,
				OptionsGlobal.Logger)
		}
	}
	CommandLineOptions.Root.AddCommand(CommandLineOptions.Status)

	// Run it!
	executeErr := CommandLineOptions.Root.Execute()
	if executeErr != nil {
		if OptionsGlobal.Logger == nil {
			newLogger, newLoggerErr := NewLogger("info")
			if newLoggerErr != nil {
				fmt.Printf("Failed to create new logger: %v", newLoggerErr)
				newLogger = logrus.New()
			}
			OptionsGlobal.Logger = newLogger
		}
		if OptionsGlobal.Logger != nil {
			OptionsGlobal.Logger.Error(executeErr)
		} else {
			log.Printf("ERROR: %s", executeErr)
		}
	}

	// Cleanup, if for some reason the caller wants to re-execute later...
	CommandLineOptions.Root.PersistentPreRunE = nil
	return executeErr
}
<commit_msg>Remove obsolete logger hook<commit_after>// +build !lambdabinary

package sparta

import (
	"fmt"
	"log"
	"os"
	"time"

	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
)

func platformLogSysInfo(lambdaFunc string, logger *logrus.Logger) {
	// NOP
}

// RegisterCodePipelineEnvironment is part of a CodePipeline deployment
// and defines the environments available for deployment. Environments
// are defined the `environmentName`. The values defined in the
// environmentVariables are made available to each service as
// environment variables. The environment key will be transformed into
// a configuration file for a CodePipeline CloudFormation action:
// TemplateConfiguration: !Sub "TemplateSource::${environmentName}".
func RegisterCodePipelineEnvironment(environmentName string,
	environmentVariables map[string]string) error {
	if _, exists := codePipelineEnvironments[environmentName]; exists {
		return errors.Errorf("Environment (%s) has already been defined", environmentName)
	}
	codePipelineEnvironments[environmentName] = environmentVariables
	return nil
}

// NewLoggerWithFormatter returns a logger with the given formatter. If formatter
// is nil, a TTY-aware formatter is used
func NewLoggerWithFormatter(level string, formatter logrus.Formatter) (*logrus.Logger, error) {
	logger := logrus.New()
	// If there is an environment override, use that
	envLogLevel := os.Getenv(envVarLogLevel)
	if envLogLevel != "" {
		level = envLogLevel
	}

	logLevel, err := logrus.ParseLevel(level)
	if err != nil {
		return nil, err
	}

	logger.Level = logLevel
	if nil != formatter {
		logger.Formatter = formatter
	}
	logger.Out = os.Stdout
	return logger, nil
}

// Main defines the primary handler for transforming an application into a Sparta package.  The
// serviceName is used to uniquely identify your service within a region and will
// be used for subsequent updates.  For provisioning, ensure that you've
// properly configured AWS credentials for the golang SDK.
// See http://docs.aws.amazon.com/sdk-for-go/api/aws/defaults.html#DefaultChainCredentials-constant
// for more information.
func Main(serviceName string, serviceDescription string, lambdaAWSInfos []*LambdaAWSInfo, api *API, site *S3Site) error {
	return MainEx(serviceName,
		serviceDescription,
		lambdaAWSInfos,
		api,
		site,
		nil,
		false)
}

// MainEx provides an "extended" Main that supports customizing the standard Sparta
// workflow via the `workflowHooks` parameter.
func MainEx(serviceName string,
	serviceDescription string,
	lambdaAWSInfos []*LambdaAWSInfo,
	api *API,
	site *S3Site,
	workflowHooks *WorkflowHooks,
	useCGO bool) error {
	//////////////////////////////////////////////////////////////////////////////
	// cmdRoot defines the root, non-executable command
	CommandLineOptions.Root.Short = fmt.Sprintf("%s - Sparta v.%s powered AWS Lambda Microservice",
		serviceName,
		SpartaVersion)
	CommandLineOptions.Root.Long = serviceDescription
	CommandLineOptions.Root.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
		// Save the ServiceName in case a custom command wants it
		OptionsGlobal.ServiceName = serviceName
		OptionsGlobal.ServiceDescription = serviceDescription

		validateErr := validate.Struct(OptionsGlobal)
		if nil != validateErr {
			return validateErr
		}

		// Format?
		// Running in AWS?
		disableColors := OptionsGlobal.DisableColors || isRunningInAWS()
		var formatter logrus.Formatter
		switch OptionsGlobal.LogFormat {
		case "text", "txt":
			formatter = &logrus.TextFormatter{
				DisableColors: disableColors,
				FullTimestamp: OptionsGlobal.TimeStamps,
			}
		case "json":
			formatter = &logrus.JSONFormatter{}
			disableColors = true
		}
		logger, loggerErr := NewLoggerWithFormatter(OptionsGlobal.LogLevel, formatter)
		if nil != loggerErr {
			return loggerErr
		}
		// Any hooks?
		// hookErr := applyLoggerHooks(serviceName, workflowHooks, logger)
		// if hookErr != nil {
		// 	return hookErr
		// }
		// This is a NOP, but makes megacheck happy b/c it doesn't know about
		// build flags
		platformLogSysInfo("", logger)
		OptionsGlobal.Logger = logger
		welcomeMessage := fmt.Sprintf("Service: %s", serviceName)

		// Header information...
		displayPrettyHeader(headerDivider, disableColors, logger)
		// Metadata about the build...
		logger.WithFields(logrus.Fields{
			"Option":    cmd.Name(),
			"UTC":       (time.Now().UTC().Format(time.RFC3339)),
			"LinkFlags": OptionsGlobal.LinkerFlags,
		}).Info(welcomeMessage)
		logger.Info(headerDivider)

		return nil
	}

	//////////////////////////////////////////////////////////////////////////////
	// Version
	CommandLineOptions.Root.AddCommand(CommandLineOptions.Version)

	//////////////////////////////////////////////////////////////////////////////
	// Provision
	CommandLineOptions.Provision.PreRunE = func(cmd *cobra.Command, args []string) error {
		validateErr := validate.Struct(optionsProvision)

		OptionsGlobal.Logger.WithFields(logrus.Fields{
			"validateErr":      validateErr,
			"optionsProvision": optionsProvision,
		}).Debug("Provision validation results")
		return validateErr
	}

	if nil == CommandLineOptions.Provision.RunE {
		CommandLineOptions.Provision.RunE = func(cmd *cobra.Command, args []string) error {
			buildID, buildIDErr := provisionBuildID(optionsProvision.BuildID, OptionsGlobal.Logger)
			if nil != buildIDErr {
				return buildIDErr
			}
			// Save the BuildID
			StampedBuildID = buildID
			return Provision(OptionsGlobal.Noop,
				serviceName,
				serviceDescription,
				lambdaAWSInfos,
				api,
				site,
				optionsProvision.S3Bucket,
				useCGO,
				optionsProvision.InPlace,
				buildID,
				optionsProvision.PipelineTrigger,
				OptionsGlobal.BuildTags,
				OptionsGlobal.LinkerFlags,
				nil,
				workflowHooks,
				OptionsGlobal.Logger)
		}
	}
	CommandLineOptions.Root.AddCommand(CommandLineOptions.Provision)

	//////////////////////////////////////////////////////////////////////////////
	// Delete
	CommandLineOptions.Delete.RunE = func(cmd *cobra.Command, args []string) error {
		return Delete(serviceName, OptionsGlobal.Logger)
	}

	CommandLineOptions.Root.AddCommand(CommandLineOptions.Delete)

	//////////////////////////////////////////////////////////////////////////////
	// Execute
	if nil == CommandLineOptions.Execute.RunE {
		CommandLineOptions.Execute.RunE = func(cmd *cobra.Command, args []string) error {

			OptionsGlobal.Logger.Formatter = new(logrus.JSONFormatter)
			// Ensure the discovery service is initialized
			initializeDiscovery(OptionsGlobal.Logger)

			return Execute(serviceName,
				lambdaAWSInfos,
				OptionsGlobal.Logger)
		}
	}
	CommandLineOptions.Root.AddCommand(CommandLineOptions.Execute)

	//////////////////////////////////////////////////////////////////////////////
	// Describe
	if nil == CommandLineOptions.Describe.RunE {
		CommandLineOptions.Describe.RunE = func(cmd *cobra.Command, args []string) error {
			validateErr := validate.Struct(optionsDescribe)
			if nil != validateErr {
				return validateErr
			}

			fileWriter, fileWriterErr := os.Create(optionsDescribe.OutputFile)
			if fileWriterErr != nil {
				return fileWriterErr
			}
			defer fileWriter.Close()
			describeErr := Describe(serviceName,
				serviceDescription,
				lambdaAWSInfos,
				api,
				site,
				optionsDescribe.S3Bucket,
				OptionsGlobal.BuildTags,
				OptionsGlobal.LinkerFlags,
				fileWriter,
				workflowHooks,
				OptionsGlobal.Logger)

			if describeErr == nil {
				describeErr = fileWriter.Sync()
			}
			return describeErr
		}
	}
	CommandLineOptions.Root.AddCommand(CommandLineOptions.Describe)

	//////////////////////////////////////////////////////////////////////////////
	// Explore
	if nil == CommandLineOptions.Explore.RunE {
		CommandLineOptions.Explore.RunE = func(cmd *cobra.Command, args []string) error {
			validateErr := validate.Struct(optionsExplore)
			if nil != validateErr {
				return validateErr
			}

			return Explore(serviceName,
				serviceDescription,
				lambdaAWSInfos,
				api,
				site,
				optionsDescribe.S3Bucket,
				OptionsGlobal.BuildTags,
				OptionsGlobal.LinkerFlags,
				OptionsGlobal.Logger)
		}
	}
	CommandLineOptions.Root.AddCommand(CommandLineOptions.Explore)

	//////////////////////////////////////////////////////////////////////////////
	// Profile
	if nil == CommandLineOptions.Profile.RunE {
		CommandLineOptions.Profile.RunE = func(cmd *cobra.Command, args []string) error {
			validateErr := validate.Struct(optionsProfile)
			if nil != validateErr {
				return validateErr
			}
			return Profile(serviceName,
				serviceDescription,
				optionsProfile.S3Bucket,
				optionsProfile.Port,
				OptionsGlobal.Logger)
		}
	}
	CommandLineOptions.Root.AddCommand(CommandLineOptions.Profile)

	//////////////////////////////////////////////////////////////////////////////
	// Status
	if nil == CommandLineOptions.Status.RunE {
		CommandLineOptions.Status.RunE = func(cmd *cobra.Command, args []string) error {
			validateErr := validate.Struct(optionsStatus)
			if nil != validateErr {
				return validateErr
			}
			return Status(serviceName,
				serviceDescription,
				optionsStatus.Redact,
				OptionsGlobal.Logger)
		}
	}
	CommandLineOptions.Root.AddCommand(CommandLineOptions.Status)

	// Run it!
	executeErr := CommandLineOptions.Root.Execute()
	if executeErr != nil {
		if OptionsGlobal.Logger == nil {
			newLogger, newLoggerErr := NewLogger("info")
			if newLoggerErr != nil {
				fmt.Printf("Failed to create new logger: %v", newLoggerErr)
				newLogger = logrus.New()
			}
			OptionsGlobal.Logger = newLogger
		}
		if OptionsGlobal.Logger != nil {
			OptionsGlobal.Logger.Error(executeErr)
		} else {
			log.Printf("ERROR: %s", executeErr)
		}
	}

	// Cleanup, if for some reason the caller wants to re-execute later...
	CommandLineOptions.Root.PersistentPreRunE = nil
	return executeErr
}
<|endoftext|>


<commit_before>package spdx

import (
	"bufio"
	"os"
	"strings"
)

// Should be configured accordingly.
var LicenceListFile = "licence-list.txt"

var licenceList map[string]interface{}

func InitLicenceList() error {
	reader, err := os.Open(LicenceListFile)

	if err != nil {
		return err
	}

	scanner := bufio.NewScanner(reader)

	licenceList = make(map[string]interface{})

	for scanner.Scan() {
		txt := strings.TrimSpace(scanner.Text())
		if txt != "" {
			licenceList[txt] = nil
		}
	}

	return scanner.Err()
}

func CheckLicence(lic string) bool {
	if licenceList == nil {
		err := InitLicenceList()
		if err != nil {
			panic(err)
		}
	}
	_, ok := licenceList[lic]
	return ok
}
<commit_msg>Documentation for spdx/licence_list.go<commit_after>package spdx

import (
	"bufio"
	"os"
	"strings"
)

// Should be configured by clients so that it reflects the location of a SPDX licence list.
// The file must have a licence ID per line. Empty lines and spaces are ignored.
//
// The script ../update-list.sh can be used to generate the list.
var LicenceListFile = "licence-list.txt"

// Set for looking up licence IDs. Do not use directly, use CheckLicence() instead.
var licenceList map[string]interface{}

// Initialises the licenceList map. Recommended to call before using CheckLicence as
// it returns the IO error for reading the LicenceListFile if there is any.
func InitLicenceList() error {
	licenceList = make(map[string]interface{})

	reader, err := os.Open(LicenceListFile)
	if err != nil {
		return err
	}

	scanner := bufio.NewScanner(reader)

	for scanner.Scan() {
		txt := strings.TrimSpace(scanner.Text())
		if txt != "" {
			licenceList[txt] = nil
		}
	}

	return scanner.Err()
}

// Checks whether the licence ID `lic` is in the SPDX Licence List.
// Calls InitLicenceList() if has not been called before and, if it
// returns an error, it panics with that error.
func CheckLicence(lic string) bool {
	if licenceList == nil {
		err := InitLicenceList()
		if err != nil {
			panic(err)
		}
	}
	_, ok := licenceList[lic]
	return ok
}
<|endoftext|>


<commit_before>package lang

import (
	. "github.com/zxh0/jvm.go/jvmgo/any"
	"github.com/zxh0/jvm.go/jvmgo/jvm/rtda"
	rtc "github.com/zxh0/jvm.go/jvmgo/jvm/rtda/class"
	"math"
)

func init() {
	_float(floatToRawIntBits, "floatToRawIntBits", "(F)I")
	_float(intBitsToFloat, "intBitsToFloat", "(I)F")
}

func _float(method Any, name, desc string) {
	rtc.RegisterNativeMethod("java/lang/Float", name, desc, method)
}

// public static native int floatToRawIntBits(float value);
// (F)I
func floatToRawIntBits(frame *rtda.Frame) {
	vars := frame.LocalVars()
	value := vars.GetFloat(0)
	bits := math.Float32bits(value)

	stack := frame.OperandStack()
	stack.PushInt(int32(bits)) // todo
}

// public static native float intBitsToFloat(int value);
// (I)F
func intBitsToFloat(frame *rtda.Frame) {
	vars := frame.LocalVars()
	bits := vars.GetInt(0)
	value := math.Float32frombits(uint32(bits))

	stack := frame.OperandStack()
	stack.PushFloat(value)

}
<commit_msg>correct comment<commit_after>package lang

import (
	. "github.com/zxh0/jvm.go/jvmgo/any"
	"github.com/zxh0/jvm.go/jvmgo/jvm/rtda"
	rtc "github.com/zxh0/jvm.go/jvmgo/jvm/rtda/class"
	"math"
)

func init() {
	_float(floatToRawIntBits, "floatToRawIntBits", "(F)I")
	_float(intBitsToFloat, "intBitsToFloat", "(I)F")
}

func _float(method Any, name, desc string) {
	rtc.RegisterNativeMethod("java/lang/Float", name, desc, method)
}

// public static native int floatToRawIntBits(float value);
// (F)I
func floatToRawIntBits(frame *rtda.Frame) {
	vars := frame.LocalVars()
	value := vars.GetFloat(0)
	bits := math.Float32bits(value)

	stack := frame.OperandStack()
	stack.PushInt(int32(bits)) // todo
}

// public static native float intBitsToFloat(int bits);
// (I)F
func intBitsToFloat(frame *rtda.Frame) {
	vars := frame.LocalVars()
	bits := vars.GetInt(0)
	value := math.Float32frombits(uint32(bits))

	stack := frame.OperandStack()
	stack.PushFloat(value)
}
<|endoftext|>


<commit_before>package lang

import (
	. "github.com/zxh0/jvm.go/jvmgo/any"
	"github.com/zxh0/jvm.go/jvmgo/jvm/rtda"
	rtc "github.com/zxh0/jvm.go/jvmgo/jvm/rtda/class"
	"math"
)

func init() {
	_float(floatToRawIntBits, "floatToRawIntBits", "(F)I")
}

func _float(method Any, name, desc string) {
	rtc.RegisterNativeMethod("java/lang/Float", name, desc, method)
}

// public static native int floatToRawIntBits(float value);
// (F)I
func floatToRawIntBits(frame *rtda.Frame) {
	vars := frame.LocalVars()
	value := vars.GetFloat(0)
	bits := math.Float32bits(value)

	stack := frame.OperandStack()
	stack.PushInt(int32(bits)) // todo
}
<commit_msg>native/implement native method: intBitsToFloat<commit_after>package lang

import (
	. "github.com/zxh0/jvm.go/jvmgo/any"
	"github.com/zxh0/jvm.go/jvmgo/jvm/rtda"
	rtc "github.com/zxh0/jvm.go/jvmgo/jvm/rtda/class"
	"math"
)

func init() {
	_float(floatToRawIntBits, "floatToRawIntBits", "(F)I")
	_float(intBitsToFloat, "intBitsToFloat", "(I)F")
}

func _float(method Any, name, desc string) {
	rtc.RegisterNativeMethod("java/lang/Float", name, desc, method)
}

// public static native int floatToRawIntBits(float value);
// (F)I
func floatToRawIntBits(frame *rtda.Frame) {
	vars := frame.LocalVars()
	value := vars.GetFloat(0)
	bits := math.Float32bits(value)

	stack := frame.OperandStack()
	stack.PushInt(int32(bits)) // todo
}

// public static native float intBitsToFloat(int value);
// (I)F
func intBitsToFloat(frame *rtda.Frame) {
	vars := frame.LocalVars()
	bits := vars.GetInt(0)
	value := math.Float32frombits(uint32(bits))

	stack := frame.OperandStack()
	stack.PushFloat(value)

}
<|endoftext|>


<commit_before>package cloudinit

import (
	"encoding/base64"
	"fmt"
	"launchpad.net/goyaml"
	"launchpad.net/juju-core/cloudinit"
	"launchpad.net/juju-core/environs"
	"launchpad.net/juju-core/environs/config"
	"launchpad.net/juju-core/log"
	"launchpad.net/juju-core/state"
	"launchpad.net/juju-core/trivial"
	"launchpad.net/juju-core/upstart"
	"path"
	"strings"
)

// TODO(dfc) duplicated from environs/ec2

const mgoPort = 37017

var mgoPortSuffix = fmt.Sprintf(":%d", mgoPort)

// MachineConfig represents initialization information for a new juju machine.
// Creation of cloudinit data from this struct is largely provider-independent,
// but we'll keep it internal until we need to factor it out.
type MachineConfig struct {
	// StateServer specifies whether the new machine will run a ZooKeeper
	// or MongoDB instance.
	StateServer bool

	// InstanceIdAccessor holds bash code that evaluates to the current instance id.
	InstanceIdAccessor string

	// ProviderType identifies the provider type so the host
	// knows which kind of provider to use.
	ProviderType string

	// StateInfo holds the means for the new instance to communicate with the
	// juju state. Unless the new machine is running a state server (StateServer is
	// set), there must be at least one state server address supplied.
	// The entity name must match that of the machine being started,
	// or be empty when starting a state server.
	StateInfo *state.Info

	// Tools is juju tools to be used on the new machine.
	Tools *state.Tools

	// DataDir holds the directory that juju state will be put in the new
	// machine.
	DataDir string

	// MachineId identifies the new machine. It must be non-negative.
	MachineId int

	// AuthorizedKeys specifies the keys that are allowed to
	// connect to the machine (see cloudinit.SSHAddAuthorizedKeys)
	// If no keys are supplied, there can be no ssh access to the node.
	// On a bootstrap machine, that is fatal. On other
	// machines it will mean that the ssh, scp and debug-hooks
	// commands cannot work.
	AuthorizedKeys string

	// Config holds the initial environment configuration.
	Config *config.Config
}

func addScripts(c *cloudinit.Config, scripts ...string) {
	for _, s := range scripts {
		c.AddRunCmd(s)
	}
}

func base64yaml(m *config.Config) string {
	data, err := goyaml.Marshal(m.AllAttrs())
	if err != nil {
		// can't happen, these values have been validated a number of times
		panic(err)
	}
	return base64.StdEncoding.EncodeToString(data)
}

func New(cfg *MachineConfig) (*cloudinit.Config, error) {
	if err := verifyConfig(cfg); err != nil {
		return nil, err
	}
	c := cloudinit.New()

	c.AddSSHAuthorizedKeys(cfg.AuthorizedKeys)
	c.AddPackage("git")

	addScripts(c,
		fmt.Sprintf("sudo mkdir -p %s", cfg.DataDir),
		"sudo mkdir -p /var/log/juju")

	// Make a directory for the tools to live in, then fetch the
	// tools and unarchive them into it.
	addScripts(c,
		"bin="+shquote(cfg.jujuTools()),
		"mkdir -p $bin",
		fmt.Sprintf("wget --no-verbose -O - %s | tar xz -C $bin", shquote(cfg.Tools.URL)),
		fmt.Sprintf("echo -n %s > $bin/downloaded-url.txt", shquote(cfg.Tools.URL)),
	)

	debugFlag := ""
	// TODO: disable debug mode by default when the system is stable.
	if true || log.Debug {
		debugFlag = " --debug"
	}

	if cfg.StateServer {
		// TODO The public bucket must come from the environment configuration.
		b := cfg.Tools.Binary
		url := fmt.Sprintf("http://juju-dist.s3.amazonaws.com/tools/mongo-2.2.0-%s-%s.tgz", b.Series, b.Arch)
		addScripts(c,
			"mkdir -p /opt",
			fmt.Sprintf("wget --no-verbose -O - %s | tar xz -C /opt", shquote(url)),
		)
		if err := addMongoToBoot(c); err != nil {
			return nil, err
		}
		addScripts(c, cfg.jujuTools()+"/jujud bootstrap-state"+
			" --instance-id "+cfg.InstanceIdAccessor+
			" --env-config "+shquote(base64yaml(cfg.Config))+
			" --state-servers localhost"+mgoPortSuffix+
			" --initial-password "+shquote(cfg.StateInfo.Password)+
			debugFlag,
		)

	}

	if err := addAgentToBoot(c, cfg, "machine",
		fmt.Sprintf("machine-%d", cfg.MachineId),
		fmt.Sprintf("--machine-id %d "+debugFlag, cfg.MachineId)); err != nil {
		return nil, err
	}

	// general options
	c.SetAptUpgrade(true)
	c.SetAptUpdate(true)
	c.SetOutput(cloudinit.OutAll, "| tee -a /var/log/cloud-init-output.log", "")
	return c, nil
}

func addAgentToBoot(c *cloudinit.Config, cfg *MachineConfig, kind, name, args string) error {
	// Make the agent run via a symbolic link to the actual tools
	// directory, so it can upgrade itself without needing to change
	// the upstart script.
	toolsDir := environs.AgentToolsDir(cfg.DataDir, name)
	// TODO(dfc) ln -nfs, so it doesn't fail if for some reason that the target already exists
	addScripts(c, fmt.Sprintf("ln -s %v %s", cfg.Tools.Binary, toolsDir))
	svc := upstart.NewService("jujud-" + name)
	cmd := fmt.Sprintf(
		"%s/jujud %s"+
			" --state-servers '%s'"+
			" --log-file /var/log/juju/%s-agent.log"+
			" --data-dir '%s'"+
			" --initial-password '%s'"+
			" %s",
		toolsDir, kind,
		cfg.stateHostAddrs(),
		name,
		cfg.DataDir,
		cfg.StateInfo.Password,
		args,
	)
	conf := &upstart.Conf{
		Service: *svc,
		Desc:    fmt.Sprintf("juju %s agent", name),
		Cmd:     cmd,
	}
	cmds, err := conf.InstallCommands()
	if err != nil {
		return fmt.Errorf("cannot make cloud-init upstart script for the %s agent: %v", name, err)
	}
	addScripts(c, cmds...)
	return nil
}

func addMongoToBoot(c *cloudinit.Config) error {
	addScripts(c,
		"mkdir -p /var/lib/juju/db/journal",
		// Otherwise we get three files with 100M+ each, which takes time.
		"dd bs=1M count=1 if=/dev/zero of=/var/lib/juju/db/journal/prealloc.0",
		"dd bs=1M count=1 if=/dev/zero of=/var/lib/juju/db/journal/prealloc.1",
		"dd bs=1M count=1 if=/dev/zero of=/var/lib/juju/db/journal/prealloc.2",
	)
	svc := upstart.NewService("juju-db")
	conf := &upstart.Conf{
		Service: *svc,
		Desc:    "juju state database",
		Cmd: "/opt/mongo/bin/mongod" +
			"--auth",
			" --dbpath=/var/lib/juju/db" +
			" --bind_ip 0.0.0.0" +
			" --port " + fmt.Sprint(mgoPort) +
			" --noprealloc" +
			" --smallfiles",
	}
	cmds, err := conf.InstallCommands()
	if err != nil {
		return fmt.Errorf("cannot make cloud-init upstart script for the state database: %v", err)
	}
	addScripts(c, cmds...)
	return nil
}

// versionDir converts a tools URL into a name
// to use as a directory for storing the tools executables in
// by using the last element stripped of its extension.
func versionDir(toolsURL string) string {
	name := path.Base(toolsURL)
	ext := path.Ext(name)
	return name[:len(name)-len(ext)]
}

func (cfg *MachineConfig) jujuTools() string {
	return environs.ToolsDir(cfg.DataDir, cfg.Tools.Binary)
}

func (cfg *MachineConfig) stateHostAddrs() string {
	var hosts []string
	if cfg.StateServer {
		hosts = append(hosts, "localhost"+mgoPortSuffix)
	}
	if cfg.StateInfo != nil {
		hosts = append(hosts, cfg.StateInfo.Addrs...)
	}
	return strings.Join(hosts, ",")
}

// shquote quotes s so that when read by bash, no metacharacters
// within s will be interpreted as such.
func shquote(s string) string {
	// single-quote becomes single-quote, double-quote, single-quote, double-quote, single-quote
	return `'` + strings.Replace(s, `'`, `'"'"'`, -1) + `'`
}

type requiresError string

func (e requiresError) Error() string {
	return "invalid machine configuration: missing " + string(e)
}

func verifyConfig(cfg *MachineConfig) (err error) {
	defer trivial.ErrorContextf(&err, "invalid machine configuration")
	if cfg.MachineId < 0 {
		return fmt.Errorf("negative machine id")
	}
	if cfg.ProviderType == "" {
		return fmt.Errorf("missing provider type")
	}
	if cfg.DataDir == "" {
		return fmt.Errorf("missing var directory")
	}
	if cfg.Tools == nil {
		return fmt.Errorf("missing tools")
	}
	if cfg.Tools.URL == "" {
		return fmt.Errorf("missing tools URL")
	}
	if cfg.StateInfo == nil {
		return fmt.Errorf("missing state info")
	}
	if cfg.StateServer {
		if cfg.InstanceIdAccessor == "" {
			return fmt.Errorf("missing instance id accessor")
		}
		if cfg.Config == nil {
			return fmt.Errorf("missing environment configuration")
		}
		if cfg.StateInfo.EntityName != "" {
			return fmt.Errorf("entity name must be blank when starting a state server")
		}
	} else {
		if len(cfg.StateInfo.Addrs) == 0 {
			return fmt.Errorf("missing state hosts")
		}
		if cfg.StateInfo.EntityName != fmt.Sprintf("machine-%d", cfg.MachineId) {
			return fmt.Errorf("entity name must match started machine")
		}
	}
	for _, r := range cfg.StateInfo.Password {
		if r == '\'' || r == '\\' || r < 32 {
			return fmt.Errorf("password has disallowed characters")
		}
	}
	return nil
}
<commit_msg>environs/cloudinit: fix --auth flag<commit_after>package cloudinit

import (
	"encoding/base64"
	"fmt"
	"launchpad.net/goyaml"
	"launchpad.net/juju-core/cloudinit"
	"launchpad.net/juju-core/environs"
	"launchpad.net/juju-core/environs/config"
	"launchpad.net/juju-core/log"
	"launchpad.net/juju-core/state"
	"launchpad.net/juju-core/trivial"
	"launchpad.net/juju-core/upstart"
	"path"
	"strings"
)

// TODO(dfc) duplicated from environs/ec2

const mgoPort = 37017

var mgoPortSuffix = fmt.Sprintf(":%d", mgoPort)

// MachineConfig represents initialization information for a new juju machine.
// Creation of cloudinit data from this struct is largely provider-independent,
// but we'll keep it internal until we need to factor it out.
type MachineConfig struct {
	// StateServer specifies whether the new machine will run a ZooKeeper
	// or MongoDB instance.
	StateServer bool

	// InstanceIdAccessor holds bash code that evaluates to the current instance id.
	InstanceIdAccessor string

	// ProviderType identifies the provider type so the host
	// knows which kind of provider to use.
	ProviderType string

	// StateInfo holds the means for the new instance to communicate with the
	// juju state. Unless the new machine is running a state server (StateServer is
	// set), there must be at least one state server address supplied.
	// The entity name must match that of the machine being started,
	// or be empty when starting a state server.
	StateInfo *state.Info

	// Tools is juju tools to be used on the new machine.
	Tools *state.Tools

	// DataDir holds the directory that juju state will be put in the new
	// machine.
	DataDir string

	// MachineId identifies the new machine. It must be non-negative.
	MachineId int

	// AuthorizedKeys specifies the keys that are allowed to
	// connect to the machine (see cloudinit.SSHAddAuthorizedKeys)
	// If no keys are supplied, there can be no ssh access to the node.
	// On a bootstrap machine, that is fatal. On other
	// machines it will mean that the ssh, scp and debug-hooks
	// commands cannot work.
	AuthorizedKeys string

	// Config holds the initial environment configuration.
	Config *config.Config
}

func addScripts(c *cloudinit.Config, scripts ...string) {
	for _, s := range scripts {
		c.AddRunCmd(s)
	}
}

func base64yaml(m *config.Config) string {
	data, err := goyaml.Marshal(m.AllAttrs())
	if err != nil {
		// can't happen, these values have been validated a number of times
		panic(err)
	}
	return base64.StdEncoding.EncodeToString(data)
}

func New(cfg *MachineConfig) (*cloudinit.Config, error) {
	if err := verifyConfig(cfg); err != nil {
		return nil, err
	}
	c := cloudinit.New()

	c.AddSSHAuthorizedKeys(cfg.AuthorizedKeys)
	c.AddPackage("git")

	addScripts(c,
		fmt.Sprintf("sudo mkdir -p %s", cfg.DataDir),
		"sudo mkdir -p /var/log/juju")

	// Make a directory for the tools to live in, then fetch the
	// tools and unarchive them into it.
	addScripts(c,
		"bin="+shquote(cfg.jujuTools()),
		"mkdir -p $bin",
		fmt.Sprintf("wget --no-verbose -O - %s | tar xz -C $bin", shquote(cfg.Tools.URL)),
		fmt.Sprintf("echo -n %s > $bin/downloaded-url.txt", shquote(cfg.Tools.URL)),
	)

	debugFlag := ""
	// TODO: disable debug mode by default when the system is stable.
	if true || log.Debug {
		debugFlag = " --debug"
	}

	if cfg.StateServer {
		// TODO The public bucket must come from the environment configuration.
		b := cfg.Tools.Binary
		url := fmt.Sprintf("http://juju-dist.s3.amazonaws.com/tools/mongo-2.2.0-%s-%s.tgz", b.Series, b.Arch)
		addScripts(c,
			"mkdir -p /opt",
			fmt.Sprintf("wget --no-verbose -O - %s | tar xz -C /opt", shquote(url)),
		)
		if err := addMongoToBoot(c); err != nil {
			return nil, err
		}
		addScripts(c, cfg.jujuTools()+"/jujud bootstrap-state"+
			" --instance-id "+cfg.InstanceIdAccessor+
			" --env-config "+shquote(base64yaml(cfg.Config))+
			" --state-servers localhost"+mgoPortSuffix+
			" --initial-password "+shquote(cfg.StateInfo.Password)+
			debugFlag,
		)

	}

	if err := addAgentToBoot(c, cfg, "machine",
		fmt.Sprintf("machine-%d", cfg.MachineId),
		fmt.Sprintf("--machine-id %d "+debugFlag, cfg.MachineId)); err != nil {
		return nil, err
	}

	// general options
	c.SetAptUpgrade(true)
	c.SetAptUpdate(true)
	c.SetOutput(cloudinit.OutAll, "| tee -a /var/log/cloud-init-output.log", "")
	return c, nil
}

func addAgentToBoot(c *cloudinit.Config, cfg *MachineConfig, kind, name, args string) error {
	// Make the agent run via a symbolic link to the actual tools
	// directory, so it can upgrade itself without needing to change
	// the upstart script.
	toolsDir := environs.AgentToolsDir(cfg.DataDir, name)
	// TODO(dfc) ln -nfs, so it doesn't fail if for some reason that the target already exists
	addScripts(c, fmt.Sprintf("ln -s %v %s", cfg.Tools.Binary, toolsDir))
	svc := upstart.NewService("jujud-" + name)
	cmd := fmt.Sprintf(
		"%s/jujud %s"+
			" --state-servers '%s'"+
			" --log-file /var/log/juju/%s-agent.log"+
			" --data-dir '%s'"+
			" --initial-password '%s'"+
			" %s",
		toolsDir, kind,
		cfg.stateHostAddrs(),
		name,
		cfg.DataDir,
		cfg.StateInfo.Password,
		args,
	)
	conf := &upstart.Conf{
		Service: *svc,
		Desc:    fmt.Sprintf("juju %s agent", name),
		Cmd:     cmd,
	}
	cmds, err := conf.InstallCommands()
	if err != nil {
		return fmt.Errorf("cannot make cloud-init upstart script for the %s agent: %v", name, err)
	}
	addScripts(c, cmds...)
	return nil
}

func addMongoToBoot(c *cloudinit.Config) error {
	addScripts(c,
		"mkdir -p /var/lib/juju/db/journal",
		// Otherwise we get three files with 100M+ each, which takes time.
		"dd bs=1M count=1 if=/dev/zero of=/var/lib/juju/db/journal/prealloc.0",
		"dd bs=1M count=1 if=/dev/zero of=/var/lib/juju/db/journal/prealloc.1",
		"dd bs=1M count=1 if=/dev/zero of=/var/lib/juju/db/journal/prealloc.2",
	)
	svc := upstart.NewService("juju-db")
	conf := &upstart.Conf{
		Service: *svc,
		Desc:    "juju state database",
		Cmd: "/opt/mongo/bin/mongod" +
			" --auth" +
			" --dbpath=/var/lib/juju/db" +
			" --bind_ip 0.0.0.0" +
			" --port " + fmt.Sprint(mgoPort) +
			" --noprealloc" +
			" --smallfiles",
	}
	cmds, err := conf.InstallCommands()
	if err != nil {
		return fmt.Errorf("cannot make cloud-init upstart script for the state database: %v", err)
	}
	addScripts(c, cmds...)
	return nil
}

// versionDir converts a tools URL into a name
// to use as a directory for storing the tools executables in
// by using the last element stripped of its extension.
func versionDir(toolsURL string) string {
	name := path.Base(toolsURL)
	ext := path.Ext(name)
	return name[:len(name)-len(ext)]
}

func (cfg *MachineConfig) jujuTools() string {
	return environs.ToolsDir(cfg.DataDir, cfg.Tools.Binary)
}

func (cfg *MachineConfig) stateHostAddrs() string {
	var hosts []string
	if cfg.StateServer {
		hosts = append(hosts, "localhost"+mgoPortSuffix)
	}
	if cfg.StateInfo != nil {
		hosts = append(hosts, cfg.StateInfo.Addrs...)
	}
	return strings.Join(hosts, ",")
}

// shquote quotes s so that when read by bash, no metacharacters
// within s will be interpreted as such.
func shquote(s string) string {
	// single-quote becomes single-quote, double-quote, single-quote, double-quote, single-quote
	return `'` + strings.Replace(s, `'`, `'"'"'`, -1) + `'`
}

type requiresError string

func (e requiresError) Error() string {
	return "invalid machine configuration: missing " + string(e)
}

func verifyConfig(cfg *MachineConfig) (err error) {
	defer trivial.ErrorContextf(&err, "invalid machine configuration")
	if cfg.MachineId < 0 {
		return fmt.Errorf("negative machine id")
	}
	if cfg.ProviderType == "" {
		return fmt.Errorf("missing provider type")
	}
	if cfg.DataDir == "" {
		return fmt.Errorf("missing var directory")
	}
	if cfg.Tools == nil {
		return fmt.Errorf("missing tools")
	}
	if cfg.Tools.URL == "" {
		return fmt.Errorf("missing tools URL")
	}
	if cfg.StateInfo == nil {
		return fmt.Errorf("missing state info")
	}
	if cfg.StateServer {
		if cfg.InstanceIdAccessor == "" {
			return fmt.Errorf("missing instance id accessor")
		}
		if cfg.Config == nil {
			return fmt.Errorf("missing environment configuration")
		}
		if cfg.StateInfo.EntityName != "" {
			return fmt.Errorf("entity name must be blank when starting a state server")
		}
	} else {
		if len(cfg.StateInfo.Addrs) == 0 {
			return fmt.Errorf("missing state hosts")
		}
		if cfg.StateInfo.EntityName != fmt.Sprintf("machine-%d", cfg.MachineId) {
			return fmt.Errorf("entity name must match started machine")
		}
	}
	for _, r := range cfg.StateInfo.Password {
		if r == '\'' || r == '\\' || r < 32 {
			return fmt.Errorf("password has disallowed characters")
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"net/url"
	"os"
	"path"
	"path/filepath"
	"strings"
	"time"
)

var (
	flag_host     = flag.String("h", "", "Set host to upload to")
	flag_port     = flag.String("p", "", "Set port or interface of remote server to upload to")
	flag_addr     = flag.String("a", "", "Set whole address of server to upload to")
	flag_name     = flag.String("f", "", "Specify a different filename to use. If stdin is used, it names the stdin stream")
	flag_inclname = flag.Bool("n", false, "Include filename in returned URL")
	flag_stdin    = flag.Bool("s", false, "Read from stdin")
	flag_nocopy   = flag.Bool("C", false, "Do not copy link to clipboard")
	flag_noprog   = flag.Bool("P", false, "Do not show progress bar")
	dotfilePath   string
)

func init() {
	log.SetFlags(log.Lshortfile)
	flag.Usage = func() {
		fmt.Fprintln(os.Stderr, `usage: lift [options] <filename>
Options:`)

		flag.PrintDefaults()

		fmt.Fprintln(os.Stderr, `Optional parameters specify the connection details to the remote server. -a
sets the entire URL, including scheme (and optional port), and overrides -h and
-p.

If options are specified, they will be saved in the configuration file.
The location of this file is system-dependent:
	$HOME/.airlift on POSIX;
	%LOCALAPPDATA%\airlift\airlift_config on Windows.`)
		os.Exit(1)
	}
	flag.Parse()
}

func main() {
	conf, err := loadConfig()
	if err != nil {
		log.Fatalln(err)
	}

	configured := config(conf)

	if flag.NArg() == 0 {
		if configured {
			os.Exit(0)
		}
		if !*flag_stdin {
			flag.Usage()
		}
	}

	uploads := make([]FileUpload, 0, flag.NArg()+1)

	if *flag_stdin {
		tmp, err := ioutil.TempFile("", "airlift-upload")
		if err != nil {
			log.Fatal("Failed to buffer stdin:", tmp)
		}
		io.Copy(tmp, os.Stdin)
		tmp.Seek(0, os.SEEK_SET)
		s := FileUpload{"stdin", tmp}
		if *flag_name != "" {
			s.Name = *flag_name
			*flag_name = ""
		}
		uploads = append(uploads, s)
	}

	for _, arg := range flag.Args() {
		file, err := os.Open(arg)
		if err != nil {
			log.Fatalln(err)
		}
		name := filepath.Base(file.Name())
		uploads = append(uploads, FileUpload{name, file})
	}

	urls := make([]string, 0, flag.NArg()+1)
	for _, upload := range uploads {
		u := tryPost(conf, upload)
		if u == "" {
			return
		}
		urls = append(urls, u)
	}

	if !*flag_nocopy {
		str := strings.Join(urls, "\n")
		if err := copyString(str); err != nil {
			if err != errNotCopying {
				fmt.Fprintf(os.Stderr, "(Error copying to clipboard: %v)\n", err)
			}
		} else {
			fmt.Fprintln(os.Stderr, "(Copied to clipboard)")
		}
	}
}

type NotAnError int

func (err NotAnError) Error() string {
	return "this is not an error"
}

const (
	errPassNotFound NotAnError = iota // password not found for host
	errNotCopying                     // not copying anything on this system (no clipboard)
)

func (c *Config) UploadURL() string {
	return c.Scheme + "://" + c.Host + ":" + c.Port + "/upload/file"
}

func loadConfig() (*Config, error) {
	file, err := os.Open(dotfilePath)
	if err != nil {
		if os.IsNotExist(err) {
			conf := &Config{
				Scheme: "http",
				Port:   "80",
			}
			return conf, writeConfig(conf)
		}
		return nil, err
	}
	defer file.Close()
	conf := new(Config)
	b := new(bytes.Buffer)
	io.Copy(b, file)
	if err := json.Unmarshal(b.Bytes(), conf); err != nil {
		return nil, fmt.Errorf("Error reading config: %v", err)
	}
	return conf, nil
}

func writeConfig(conf *Config) error {
	dir := filepath.Dir(dotfilePath)
	os.MkdirAll(dir, os.FileMode(0755))
	file, err := os.OpenFile(dotfilePath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, os.FileMode(0600))
	if err != nil {
		return err
	}
	b, err := json.MarshalIndent(conf, "", "    ")
	if err != nil {
		return err
	}
	file.Write(b)
	return nil
}

func config(conf *Config) bool {
	configured := false

	if *flag_host != "" {
		configured = true
		conf.Host = *flag_host
	}
	if *flag_port != "" {
		configured = true
		conf.Port = *flag_port
	}
	if *flag_addr != "" {
		configured = true
		if !strings.Contains(*flag_addr, "://") {
			*flag_addr = "http://" + *flag_addr
		}
		addr, err := url.Parse(*flag_addr)
		if err != nil {
			log.Fatalln("-a:", err)
		}
		conf.Scheme = addr.Scheme
		host, port, err := net.SplitHostPort(addr.Host)
		if err == nil {
			conf.Host, conf.Port = host, port
		} else {
			conf.Host = path.Join(addr.Host, addr.Path)
		}
		if conf.Port == "" {
			conf.Port = "80"
		}
	}
	if conf.Scheme == "" {
		conf.Scheme = "http"
	}

	if configured {
		if err := writeConfig(conf); err != nil {
			log.Fatalln(err)
		}
	}

	return configured
}

type FileUpload struct {
	Name    string
	Content io.ReadCloser
}

// Post file to server. Keep retrying if the password is incorrect,
// otherwise exit with success or other errors.
func tryPost(conf *Config, upload FileUpload) string {
	if conf.Host == "" {
		fmt.Fprintln(os.Stderr, "Host not configured.")
		flag.Usage()
	}

	var alreadyWrong bool

	for {
		resp := postFile(conf, upload)
		var msg Resp
		err := json.NewDecoder(resp.Body).Decode(&msg)
		resp.Body.Close()
		if err != nil {
			log.Fatalln("error decoding server response:", err)
		}

		switch resp.StatusCode {
		case http.StatusForbidden:
			if alreadyWrong {
				fmt.Fprintln(os.Stderr, "Sorry, wrong password.")
			} else {
				fmt.Fprintln(os.Stderr, "Server returned error:", msg.Err)
				fmt.Fprintln(os.Stderr, "You'll need a new password. If the request is successful,")
				fmt.Fprintf(os.Stderr, "it will be saved in %s.\n", PasswordStorageMechanism)
				alreadyWrong = true
			}
			fmt.Fprint(os.Stderr, "Password: ")
			pass, err := readPassword()
			if err != nil {
				log.Fatalln(err)
			}
			if err = updatePassword(conf, pass); err != nil {
				log.Fatalln(err)
			}

		case http.StatusCreated:
			u := msg.URL
			if *flag_inclname {
				u = path.Join(u, upload.Name)
			}
			u = conf.Scheme + "://" + u
			fmt.Println(u)
			return u

		default:
			fmt.Fprintln(os.Stderr, resp.Status)
			fmt.Fprintln(os.Stderr, "Server returned error:", msg.Err)
			return ""
		}
	}

}

func postFile(conf *Config, upload FileUpload) *http.Response {
	var (
		sz  int64
		err error
	)

	if seeker, ok := upload.Content.(io.Seeker); ok {
		sz, err = seeker.Seek(0, os.SEEK_END)
		if err != nil {
			log.Fatalln(err)
		}
		seeker.Seek(0, os.SEEK_SET)
	}

	var body io.ReadCloser

	// only show progress if the size is bigger than some arbitrary amount
	// (512KiB) and -P isn't set
	if sz > 512*1024 && !*flag_noprog {
		r := newProgressReader(upload.Content, sz)
		go r.Report()
		body = r
	} else {
		body = upload.Content
	}

	req, err := http.NewRequest("POST", conf.UploadURL(), body)
	if err != nil {
		log.Fatalln(err)
	}

	var name string
	if *flag_name != "" {
		name = *flag_name
	} else {
		name = upload.Name
	}
	req.Header.Set("X-Airlift-Filename", name)

	// attach the password. Only do so if there's a password stored for the
	// given host.
	pass, err := getPassword(conf)
	switch err {
	case nil:
		req.Header.Set("X-Airlift-Password", pass)
	case errPassNotFound:
		break
	default:
		log.Fatalln(err)
	}

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatalln(err)
	}

	return resp
}

type Resp struct {
	URL string
	Err string
}

func newProgressReader(r io.ReadCloser, total int64) *ProgressReader {
	p := &ProgressReader{
		ReadCloser: r,
		total:      total,
		width:      getTermWidth(),
		read: make(chan struct {
			n   int
			err error
		}, 10),
		closed: make(chan struct{}, 1),
	}
	if p.width >= 3 {
		p.buf = make([]rune, p.width-2)
	}
	return p
}

type ProgressReader struct {
	io.ReadCloser
	total   int64
	current int64
	width   int
	buf     []rune
	read    chan struct {
		n   int
		err error
	}
	closed chan struct{}
}

var barChars = []rune{' ', '▏', '▎', '▍', '▌', '▋', '▊', '▉'}

func (r *ProgressReader) Read(p []byte) (n int, err error) {
	n, err = r.ReadCloser.Read(p)
	r.read <- struct {
		n   int
		err error
	}{n, err}
	return
}

func (r *ProgressReader) Close() error {
	r.closed <- struct{}{}
	return r.ReadCloser.Close()
}

func (r *ProgressReader) Report() {
	if r.buf == nil {
		return
	}
	defer func() {
		fmt.Fprint(os.Stdout, "\033[J")
	}()
	t := time.NewTicker(33 * time.Millisecond)
	for {
		select {
		case <-r.closed:
			r.current = r.total
			r.output()
			return
		case read := <-r.read:
			if read.err != nil {
				return
			}
			r.current += int64(read.n)
		case <-t.C:
			r.output()
		}
	}
}

func (r *ProgressReader) output() {
	last := barChars[len(barChars)-1]
	progress := float64(r.current) / float64(r.total)
	q := float64(r.width-2)*progress + 1
	x := int(q)
	frac := barChars[int((q-float64(x))*float64(len(barChars)))]

	ch := last
	for i := 0; i < len(r.buf); i++ {
		if i == x {
			r.buf[i] = frac
			ch = ' '
		} else {
			r.buf[i] = ch
		}
	}
	fmt.Fprint(os.Stderr, "\033[J["+string(r.buf)+"]\n\033[1A")
}

// read a password from stdin, disabling console echo
func readPassword() (string, error) {
	/*
		if err := toggleEcho(false); err != nil {
			return "", err
		}
	*/
	toggleEcho(false)
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Scan()
	s := scanner.Text()
	fmt.Fprintln(os.Stderr)
	if err := scanner.Err(); err != nil {
		return "", err
	}

	/*
		if err := toggleEcho(true); err != nil {
			return "", err
		}
	*/
	toggleEcho(true)
	return s, nil
}
<commit_msg>Clean up a bit.<commit_after>package main

import (
	"bufio"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"net/url"
	"os"
	"path"
	"path/filepath"
	"strings"
	"time"
)

var (
	flag_host     = flag.String("h", "", "Set host to upload to")
	flag_port     = flag.String("p", "", "Set port or interface of remote server to upload to")
	flag_addr     = flag.String("a", "", "Set whole address of server to upload to")
	flag_name     = flag.String("f", "", "Specify a different filename to use. If stdin is used, it names the stdin stream")
	flag_inclname = flag.Bool("n", false, "Include filename in returned URL")
	flag_stdin    = flag.Bool("s", false, "Read from stdin")
	flag_nocopy   = flag.Bool("C", false, "Do not copy link to clipboard")
	flag_noprog   = flag.Bool("P", false, "Do not show progress bar")
	dotfilePath   string
)

func init() {
	log.SetFlags(log.Lshortfile)
	flag.Usage = func() {
		fmt.Fprintln(os.Stderr, `usage: lift [options] <filename>
Options:`)

		flag.PrintDefaults()

		fmt.Fprintln(os.Stderr, `Optional parameters specify the connection details to the remote server. -a
sets the entire URL, including scheme (and optional port), and overrides -h and
-p.

If options are specified, they will be saved in the configuration file.
The location of this file is system-dependent:
	$HOME/.airlift on POSIX;
	%LOCALAPPDATA%\airlift\airlift_config on Windows.`)
		os.Exit(1)
	}
	flag.Parse()
}

func main() {
	conf, err := loadConfig()
	if err != nil {
		log.Fatalln(err)
	}

	configured := config(conf)

	if flag.NArg() == 0 {
		if configured {
			os.Exit(0)
		}
		if !*flag_stdin {
			flag.Usage()
		}
	}

	uploads := make([]FileUpload, 0, flag.NArg()+1)

	if *flag_stdin {
		tmp, err := ioutil.TempFile("", "airlift-upload")
		if err != nil {
			log.Fatal("Failed to buffer stdin:", tmp)
		}
		io.Copy(tmp, os.Stdin)
		tmp.Seek(0, os.SEEK_SET)
		s := FileUpload{"stdin", tmp}
		if *flag_name != "" {
			s.Name = *flag_name
			*flag_name = ""
		}
		uploads = append(uploads, s)
	}

	for _, arg := range flag.Args() {
		file, err := os.Open(arg)
		if err != nil {
			log.Fatalln(err)
		}
		name := filepath.Base(file.Name())
		uploads = append(uploads, FileUpload{name, file})
	}

	urls := make([]string, 0, flag.NArg()+1)
	for _, upload := range uploads {
		u := tryPost(conf, upload)
		if u == "" {
			return
		}
		urls = append(urls, u)
	}

	if !*flag_nocopy {
		str := strings.Join(urls, "\n")
		if err := copyString(str); err != nil {
			if err != errNotCopying {
				fmt.Fprintf(os.Stderr, "(Error copying to clipboard: %v)\n", err)
			}
		} else {
			fmt.Fprintln(os.Stderr, "(Copied to clipboard)")
		}
	}
}

type NotAnError int

func (err NotAnError) Error() string {
	return "this is not an error"
}

const (
	errPassNotFound NotAnError = iota // password not found for host
	errNotCopying                     // not copying anything on this system (no clipboard)
)

func (c *Config) UploadURL() string {
	return c.Scheme + "://" + c.Host + ":" + c.Port + "/upload/file"
}

func loadConfig() (*Config, error) {
	buf, err := ioutil.ReadFile(dotfilePath)
	if err != nil {
		if os.IsNotExist(err) {
			conf := &Config{
				Scheme: "http",
				Port:   "80",
			}
			return conf, writeConfig(conf)
		}
		return nil, err
	}
	conf := new(Config)
	if err := json.Unmarshal(buf, conf); err != nil {
		return nil, fmt.Errorf("Error reading config: %v", err)
	}
	return conf, nil
}

func writeConfig(conf *Config) error {
	dir := filepath.Dir(dotfilePath)
	os.MkdirAll(dir, os.FileMode(0755))
	file, err := os.OpenFile(dotfilePath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, os.FileMode(0600))
	if err != nil {
		return err
	}
	b, err := json.MarshalIndent(conf, "", "    ")
	if err != nil {
		return err
	}
	file.Write(b)
	return nil
}

func config(conf *Config) bool {
	configured := false

	if *flag_host != "" {
		configured = true
		conf.Host = *flag_host
	}
	if *flag_port != "" {
		configured = true
		conf.Port = *flag_port
	}
	if *flag_addr != "" {
		configured = true
		if !strings.Contains(*flag_addr, "://") {
			*flag_addr = "http://" + *flag_addr
		}
		addr, err := url.Parse(*flag_addr)
		if err != nil {
			log.Fatalln("-a:", err)
		}
		conf.Scheme = addr.Scheme
		host, port, err := net.SplitHostPort(addr.Host)
		if err == nil {
			conf.Host, conf.Port = host, port
		} else {
			conf.Host = path.Join(addr.Host, addr.Path)
		}
		if conf.Port == "" {
			conf.Port = "80"
		}
	}
	if conf.Scheme == "" {
		conf.Scheme = "http"
	}

	if configured {
		if err := writeConfig(conf); err != nil {
			log.Fatalln(err)
		}
	}

	return configured
}

type FileUpload struct {
	Name    string
	Content io.ReadCloser
}

// Post file to server. Keep retrying if the password is incorrect,
// otherwise exit with success or other errors.
func tryPost(conf *Config, upload FileUpload) string {
	if conf.Host == "" {
		fmt.Fprintln(os.Stderr, "Host not configured.")
		flag.Usage()
	}

	var alreadyWrong bool

	for {
		resp := postFile(conf, upload)
		var msg Resp
		err := json.NewDecoder(resp.Body).Decode(&msg)
		resp.Body.Close()
		if err != nil {
			log.Fatalln("error decoding server response:", err)
		}

		switch resp.StatusCode {
		case http.StatusForbidden:
			if alreadyWrong {
				fmt.Fprintln(os.Stderr, "Sorry, wrong password.")
			} else {
				fmt.Fprintln(os.Stderr, "Server returned error:", msg.Err)
				fmt.Fprintln(os.Stderr, "You'll need a new password. If the request is successful,")
				fmt.Fprintf(os.Stderr, "it will be saved in %s.\n", PasswordStorageMechanism)
				alreadyWrong = true
			}
			fmt.Fprint(os.Stderr, "Password: ")
			pass, err := readPassword()
			if err != nil {
				log.Fatalln(err)
			}
			if err = updatePassword(conf, pass); err != nil {
				log.Fatalln(err)
			}

		case http.StatusCreated:
			u := msg.URL
			if *flag_inclname {
				u = path.Join(u, upload.Name)
			}
			u = conf.Scheme + "://" + u
			fmt.Println(u)
			return u

		default:
			fmt.Fprintln(os.Stderr, resp.Status)
			fmt.Fprintln(os.Stderr, "Server returned error:", msg.Err)
			return ""
		}
	}

}

func postFile(conf *Config, upload FileUpload) *http.Response {
	var (
		sz  int64
		err error
	)

	if seeker, ok := upload.Content.(io.Seeker); ok {
		sz, err = seeker.Seek(0, os.SEEK_END)
		if err != nil {
			log.Fatalln(err)
		}
		seeker.Seek(0, os.SEEK_SET)
	}

	var body io.ReadCloser

	// only show progress if the size is bigger than some arbitrary amount
	// (512KiB) and -P isn't set
	if sz > 512*1024 && !*flag_noprog {
		r := newProgressReader(upload.Content, sz)
		go r.Report()
		body = r
	} else {
		body = upload.Content
	}

	req, err := http.NewRequest("POST", conf.UploadURL(), body)
	if err != nil {
		log.Fatalln(err)
	}

	var name string
	if *flag_name != "" {
		name = *flag_name
	} else {
		name = upload.Name
	}
	req.Header.Set("X-Airlift-Filename", name)

	// attach the password. Only do so if there's a password stored for the
	// given host.
	pass, err := getPassword(conf)
	switch err {
	case nil:
		req.Header.Set("X-Airlift-Password", pass)
	case errPassNotFound:
		break
	default:
		log.Fatalln(err)
	}

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatalln(err)
	}

	return resp
}

type Resp struct {
	URL string
	Err string
}

func newProgressReader(r io.ReadCloser, total int64) *ProgressReader {
	p := &ProgressReader{
		ReadCloser: r,
		total:      total,
		width:      getTermWidth(),
		read: make(chan struct {
			n   int
			err error
		}, 10),
		closed: make(chan struct{}, 1),
	}
	if p.width >= 3 {
		p.buf = make([]rune, p.width-2)
	}
	return p
}

type ProgressReader struct {
	io.ReadCloser
	total   int64
	current int64
	width   int
	buf     []rune
	read    chan struct {
		n   int
		err error
	}
	closed chan struct{}
}

var barChars = []rune{' ', '▏', '▎', '▍', '▌', '▋', '▊', '▉'}

func (r *ProgressReader) Read(p []byte) (n int, err error) {
	n, err = r.ReadCloser.Read(p)
	r.read <- struct {
		n   int
		err error
	}{n, err}
	return
}

func (r *ProgressReader) Close() error {
	r.closed <- struct{}{}
	return r.ReadCloser.Close()
}

func (r *ProgressReader) Report() {
	if r.buf == nil {
		return
	}
	defer func() {
		fmt.Fprint(os.Stdout, "\033[J")
	}()
	t := time.NewTicker(33 * time.Millisecond)
	for {
		select {
		case <-r.closed:
			r.current = r.total
			r.output()
			return
		case read := <-r.read:
			if read.err != nil {
				return
			}
			r.current += int64(read.n)
		case <-t.C:
			r.output()
		}
	}
}

func (r *ProgressReader) output() {
	last := barChars[len(barChars)-1]
	progress := float64(r.current) / float64(r.total)
	q := float64(r.width-2)*progress + 1
	x := int(q)
	frac := barChars[int((q-float64(x))*float64(len(barChars)))]

	ch := last
	for i := 0; i < len(r.buf); i++ {
		if i == x {
			r.buf[i] = frac
			ch = ' '
		} else {
			r.buf[i] = ch
		}
	}
	fmt.Fprint(os.Stderr, "\033[J["+string(r.buf)+"]\n\033[1A")
}

// read a password from stdin, disabling console echo
func readPassword() (string, error) {
	toggleEcho(false)

	scanner := bufio.NewScanner(os.Stdin)
	scanner.Scan()
	s := scanner.Text()
	fmt.Fprintln(os.Stderr)
	if err := scanner.Err(); err != nil {
		return "", err
	}

	toggleEcho(true)
	return s, nil
}
<|endoftext|>


<commit_before>package boilingcore

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"strings"
	"testing"
)

type NopWriteCloser struct {
	io.Writer
}

func (NopWriteCloser) Close() error {
	return nil
}

func nopCloser(w io.Writer) io.WriteCloser {
	return NopWriteCloser{w}
}

func TestWriteFile(t *testing.T) {
	// t.Parallel() cannot be used

	// set the function pointer back to its original value
	// after we modify it for the test
	saveTestHarnessWriteFile := testHarnessWriteFile
	defer func() {
		testHarnessWriteFile = saveTestHarnessWriteFile
	}()

	var output []byte
	testHarnessWriteFile = func(_ string, in []byte, _ os.FileMode) error {
		output = in
		return nil
	}

	buf := &bytes.Buffer{}
	writePackageName(buf, "pkg")
	fmt.Fprintf(buf, "func hello() {}\n\n\nfunc world() {\nreturn\n}\n\n\n\n")

	if err := writeFile("", "", buf, true); err != nil {
		t.Error(err)
	}

	if string(output) != "package pkg\n\nfunc hello() {}\n\nfunc world() {\n\treturn\n}\n" {
		t.Errorf("Wrong output: %q", output)
	}
}

func TestFormatBuffer(t *testing.T) {
	t.Parallel()

	buf := &bytes.Buffer{}

	fmt.Fprintf(buf, "package pkg\n\nfunc() {a}\n")

	// Only test error case - happy case is taken care of by template test
	_, err := formatBuffer(buf)
	if err == nil {
		t.Error("want an error")
	}

	if txt := err.Error(); !strings.Contains(txt, ">>>> func() {a}") {
		t.Error("got:\n", txt)
	}
}

func TestOutputFilenameParts(t *testing.T) {
	t.Parallel()

	tests := []struct {
		Filename string

		FirstDir    string
		Normalized  string
		IsSingleton bool
		IsGo        bool
		UsePkg      bool
	}{
		{"templates/00_struct.go.tpl", "templates", "struct.go", false, true, true},
		{"templates/singleton/00_struct.go.tpl", "templates", "struct.go", true, true, true},
		{"templates/notpkg/00_struct.go.tpl", "templates", "notpkg/struct.go", false, true, false},
		{"templates/js/singleton/00_struct.js.tpl", "templates", "js/struct.js", true, false, false},
		{"templates/js/00_struct.js.tpl", "templates", "js/struct.js", false, false, false},
	}

	for i, test := range tests {
		firstDir, normalized, isSingleton, isGo, usePkg := outputFilenameParts(test.Filename)

		if firstDir != test.FirstDir {
			t.Errorf("%d) first dir wrong, want: %s, got: %s", i, test.FirstDir, firstDir)
		}
		if normalized != test.Normalized {
			t.Errorf("%d) normalized wrong, want: %s, got: %s", i, test.Normalized, normalized)
		}
		if isSingleton != test.IsSingleton {
			t.Errorf("%d) isSingleton wrong, want: %t, got: %t", i, test.IsSingleton, isSingleton)
		}
		if isGo != test.IsGo {
			t.Errorf("%d) isGo wrong, want: %t, got: %t", i, test.IsGo, isGo)
		}
		if usePkg != test.UsePkg {
			t.Errorf("%d) usePkg wrong, want: %t, got: %t", i, test.UsePkg, usePkg)
		}
	}
}
<commit_msg>Correct a test failure<commit_after>package boilingcore

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"strings"
	"testing"
)

type NopWriteCloser struct {
	io.Writer
}

func (NopWriteCloser) Close() error {
	return nil
}

func nopCloser(w io.Writer) io.WriteCloser {
	return NopWriteCloser{w}
}

func TestWriteFile(t *testing.T) {
	// t.Parallel() cannot be used

	// set the function pointer back to its original value
	// after we modify it for the test
	saveTestHarnessWriteFile := testHarnessWriteFile
	defer func() {
		testHarnessWriteFile = saveTestHarnessWriteFile
	}()

	var output []byte
	testHarnessWriteFile = func(_ string, in []byte, _ os.FileMode) error {
		output = in
		return nil
	}

	buf := &bytes.Buffer{}
	writePackageName(buf, "pkg")
	fmt.Fprintf(buf, "func hello() {}\n\n\nfunc world() {\nreturn\n}\n\n\n\n")

	if err := writeFile("", "", buf, true); err != nil {
		t.Error(err)
	}

	if string(output) != "package pkg\n\nfunc hello() {}\n\nfunc world() {\n\treturn\n}\n" {
		t.Errorf("Wrong output: %q", output)
	}
}

func TestFormatBuffer(t *testing.T) {
	t.Parallel()

	buf := &bytes.Buffer{}

	fmt.Fprintf(buf, "package pkg\n\nfunc() {a}\n")

	// Only test error case - happy case is taken care of by template test
	_, err := formatBuffer(buf)
	if err == nil {
		t.Error("want an error")
	}

	if txt := err.Error(); !strings.Contains(txt, ">>>> func() {a}") {
		t.Error("got:\n", txt)
	}
}

func TestOutputFilenameParts(t *testing.T) {
	t.Parallel()

	tests := []struct {
		Filename string

		FirstDir    string
		Normalized  string
		IsSingleton bool
		IsGo        bool
		UsePkg      bool
	}{
		{"templates/00_struct.go.tpl", "templates", "struct.go", false, true, true},
		{"templates/singleton/00_struct.go.tpl", "templates", "struct.go", true, true, true},
		{"templates/notpkg/00_struct.go.tpl", "templates", "notpkg/struct.go", false, true, false},
		{"templates/js/singleton/00_struct.js.tpl", "templates", "js/struct.js", true, false, false},
		{"templates/js/00_struct.js.tpl", "templates", "js/struct.js", false, false, false},
	}

	for i, test := range tests {
		normalized, isSingleton, isGo, usePkg := outputFilenameParts(test.Filename)

		if normalized != test.Normalized {
			t.Errorf("%d) normalized wrong, want: %s, got: %s", i, test.Normalized, normalized)
		}
		if isSingleton != test.IsSingleton {
			t.Errorf("%d) isSingleton wrong, want: %t, got: %t", i, test.IsSingleton, isSingleton)
		}
		if isGo != test.IsGo {
			t.Errorf("%d) isGo wrong, want: %t, got: %t", i, test.IsGo, isGo)
		}
		if usePkg != test.UsePkg {
			t.Errorf("%d) usePkg wrong, want: %t, got: %t", i, test.UsePkg, usePkg)
		}
	}
}
<|endoftext|>


<commit_before>package core

import (
	"fmt"
	"sync/atomic"
	"time"
)

// GameStats holds current game statistics
var GameStats = Statistics{
	started: time.Now(),
}

// Statistics hold game stats
type Statistics struct {
	gamesPlayed      int64
	clientsConnected int64
	started          time.Time
}

// StatisticsInfo is serialized Statistics
type StatisticsInfo struct {
	GamesPlayed      int64
	ClientsConnected int64
	Uptime           string
}

// AddPlayedGame increments played games count
func (s *Statistics) AddPlayedGame() {
	atomic.AddInt64(&s.gamesPlayed, 1)
}

// OnClientConnected - call when client has connected
func (s *Statistics) OnClientConnected() {
	atomic.AddInt64(&s.clientsConnected, 1)
}

// OnClientDisconnected - call when client disconnected
func (s *Statistics) OnClientDisconnected() {
	atomic.AddInt64(&s.clientsConnected, -1)
}

// ToInfo get StatisticsInfo intance for current Statistics
func (s *Statistics) ToInfo() *StatisticsInfo {
	i := StatisticsInfo{
		ClientsConnected: s.clientsConnected,
		GamesPlayed:      s.gamesPlayed,
	}
	d := time.Now().Sub(s.started)
	i.Uptime = fmt.Sprintf("%02d:%02d:%02d",
		int(d.Hours()), int(d.Minutes()), int(d.Seconds()))
	return &i
}
<commit_msg>fixed uptime<commit_after>package core

import (
	"fmt"
	"sync/atomic"
	"time"
)

// GameStats holds current game statistics
var GameStats = Statistics{
	started: time.Now(),
}

// Statistics hold game stats
type Statistics struct {
	gamesPlayed      int64
	clientsConnected int64
	started          time.Time
}

// StatisticsInfo is serialized Statistics
type StatisticsInfo struct {
	GamesPlayed      int64
	ClientsConnected int64
	Uptime           string
}

// AddPlayedGame increments played games count
func (s *Statistics) AddPlayedGame() {
	atomic.AddInt64(&s.gamesPlayed, 1)
}

// OnClientConnected - call when client has connected
func (s *Statistics) OnClientConnected() {
	atomic.AddInt64(&s.clientsConnected, 1)
}

// OnClientDisconnected - call when client disconnected
func (s *Statistics) OnClientDisconnected() {
	atomic.AddInt64(&s.clientsConnected, -1)
}

// ToInfo get StatisticsInfo intance for current Statistics
func (s *Statistics) ToInfo() *StatisticsInfo {
	i := StatisticsInfo{
		ClientsConnected: s.clientsConnected,
		GamesPlayed:      s.gamesPlayed,
	}
	d := time.Now().Sub(s.started)
	i.Uptime = fmt.Sprintf("%02d:%02d:%02d",
		int(d.Hours()), int(d.Minutes())%60, int(d.Seconds())%60)
	return &i
}
<|endoftext|>


<commit_before>package deploy

import (
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"bytes"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/ieee0824/getenv"
	"github.com/jobtalk/pnzr/api"
	"github.com/jobtalk/pnzr/lib"
	"github.com/jobtalk/pnzr/lib/setting"
)

type DeployCommand struct {
	sess           *session.Session
	file           *string
	profile        *string
	kmsKeyID       *string
	region         *string
	externalPath   *string
	outerVals      *string
	awsAccessKeyID *string
	awsSecretKeyID *string
	tagOverride    *string
	dryRun         *bool
}

var re = regexp.MustCompile(`.*\.json$`)

func parseDockerImage(image string) (url, tag string) {
	r := strings.Split(image, ":")
	if len(r) == 2 {
		return r[0], r[1]
	}
	return r[0], ""
}

func fileList(root string) ([]string, error) {
	if root == "" {
		return nil, nil
	}
	ret := []string{}
	err := filepath.Walk(root,
		func(path string, info os.FileInfo, err error) error {
			if info == nil {
				return errors.New("file info is nil")
			}
			if info.IsDir() {
				return nil
			}

			rel, err := filepath.Rel(root, path)
			if re.MatchString(rel) {
				ret = append(ret, rel)
			}

			return nil
		})

	if err != nil {
		return nil, err
	}

	return ret, nil
}

type deployConfigure struct {
	*setting.Setting
}

func isEncrypted(data []byte) bool {
	var buffer = map[string]interface{}{}
	if err := json.Unmarshal(data, &buffer); err != nil {
		return false
	}
	elem, ok := buffer["cipher"]
	if !ok {
		return false
	}
	str, ok := elem.(string)
	if !ok {
		return false
	}

	return len(str) != 0
}

func (d *DeployCommand) decrypt(bin []byte) ([]byte, error) {
	kms := lib.NewKMSFromBinary(bin, d.sess)
	if kms == nil {
		return nil, errors.New(fmt.Sprintf("%v format is illegal", string(bin)))
	}
	plainText, err := kms.SetKeyID(*d.kmsKeyID).Decrypt()
	if err != nil {
		return nil, err
	}
	return plainText, nil
}

func (d *DeployCommand) readConf(base []byte, externalPathList []string) (*deployConfigure, error) {
	var root = *d.externalPath
	var ret = &deployConfigure{}
	baseStr := string(base)

	root = strings.TrimSuffix(root, "/")
	for _, externalPath := range externalPathList {
		external, err := ioutil.ReadFile(root + "/" + externalPath)
		if err != nil {
			return nil, err
		}
		if isEncrypted(external) {
			plain, err := d.decrypt(external)
			if err != nil {
				return nil, err
			}
			external = plain
		}
		baseStr, err = lib.Embedde(baseStr, string(external))
		if err != nil {
			return nil, err
		}
	}
	if err := json.Unmarshal([]byte(baseStr), ret); err != nil {
		return nil, err
	}
	return ret, nil
}

func (d *DeployCommand) parseArgs(args []string) (helpString string) {
	flagSet := new(flag.FlagSet)
	var f *string

	buffer := new(bytes.Buffer)
	flagSet.SetOutput(buffer)

	d.kmsKeyID = flagSet.String("key_id", getenv.String("KMS_KEY_ID"), "Amazon KMS key ID")
	d.file = flagSet.String("file", "", "target file")
	f = flagSet.String("f", "", "target file")
	d.profile = flagSet.String("profile", getenv.String("AWS_PROFILE_NAME", "default"), "aws credentials profile name")
	d.region = flagSet.String("region", getenv.String("AWS_REGION", "ap-northeast-1"), "aws region")
	d.externalPath = flagSet.String("vars_path", getenv.String("PNZR_VARS_PATH"), "external conf path")
	d.outerVals = flagSet.String("V", "", "outer values")
	d.tagOverride = flagSet.String("t", getenv.String("DOCKER_DEFAULT_DEPLOY_TAG", "latest"), "tag override param")
	d.awsAccessKeyID = flagSet.String("aws-access-key-id", getenv.String("AWS_ACCESS_KEY_ID"), "aws access key id")
	d.awsSecretKeyID = flagSet.String("aws-secret-key-id", getenv.String("AWS_SECRET_KEY_ID"), "aws secret key id")
	d.dryRun = flagSet.Bool("dry-run", false, "dry run mode")

	if err := flagSet.Parse(args); err != nil {
		if err == flag.ErrHelp {
			return buffer.String()
		}
		panic(err)
	}

	if *f == "" && *d.file == "" && len(flagSet.Args()) != 0 {
		targetName := flagSet.Args()[0]
		d.file = &targetName
	}

	if *d.file == "" {
		d.file = f
	}

	var awsConfig = aws.Config{}

	if *d.awsAccessKeyID != "" && *d.awsSecretKeyID != "" && *d.profile == "" {
		awsConfig.Credentials = credentials.NewStaticCredentials(*d.awsAccessKeyID, *d.awsSecretKeyID, "")
		awsConfig.Region = d.region
	}

	d.sess = session.Must(session.NewSessionWithOptions(session.Options{
		AssumeRoleTokenProvider: stscreds.StdinTokenProvider,
		SharedConfigState:       session.SharedConfigEnable,
		Profile:                 *d.profile,
		Config:                  awsConfig,
	}))

	return
}

func (d *DeployCommand) Run(args []string) int {
	d.parseArgs(args)
	var config = &deployConfigure{}

	externalList, err := fileList(*d.externalPath)
	if err != nil {
		log.Fatalln(err)
	}
	baseConfBinary, err := ioutil.ReadFile(*d.file)
	if err != nil {
		log.Fatal(err)
	}

	if *d.outerVals != "" {
		baseStr, err := lib.Embedde(string(baseConfBinary), *d.outerVals)
		if err == nil {
			baseConfBinary = []byte(baseStr)
		}
	}

	if externalList != nil {
		c, err := d.readConf(baseConfBinary, externalList)
		if err != nil {
			log.Fatalln(err)
		}
		config = c
	} else {
		bin, err := ioutil.ReadFile(*d.file)
		if err != nil {
			log.Fatalln(err)
		}
		if err := json.Unmarshal(bin, config); err != nil {
			log.Fatalln(err)
		}
	}

	for i, containerDefinition := range config.ECS.TaskDefinition.ContainerDefinitions {
		imageName, tag := parseDockerImage(*containerDefinition.Image)
		if tag == "$tag" {
			image := imageName + ":" + *d.tagOverride
			config.ECS.TaskDefinition.ContainerDefinitions[i].Image = &image
		} else if tag == "" {
			image := imageName + ":" + "latest"
			config.ECS.TaskDefinition.ContainerDefinitions[i].Image = &image
		}
	}

	f, err := os.Open("/dev/stderr")
	if err != nil {
		panic(err)
	}
	if *d.dryRun {
		fmt.Fprintf(f, "******** DRY RUN ********\n%s\n", *config.Setting.ECS)
		return 0
	}

	result, err := api.Deploy(d.sess, config.Setting)
	if err != nil {
		log.Fatalln(err)
	}
	resultJSON, err := json.MarshalIndent(result, "", "    ")
	if err != nil {
		log.Fatalln(err)
	}
	fmt.Println(string(resultJSON))
	return 0
}

func (c *DeployCommand) Synopsis() string {
	return "Deploy docker on ecs."
}

func (c *DeployCommand) Help() string {
	return c.parseArgs([]string{"-h"})
}
<commit_msg>Openをifの中に入れ、config.Setting.ECSをconfing.ECSに変更<commit_after>package deploy

import (
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"bytes"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/ieee0824/getenv"
	"github.com/jobtalk/pnzr/api"
	"github.com/jobtalk/pnzr/lib"
	"github.com/jobtalk/pnzr/lib/setting"
)

type DeployCommand struct {
	sess           *session.Session
	file           *string
	profile        *string
	kmsKeyID       *string
	region         *string
	externalPath   *string
	outerVals      *string
	awsAccessKeyID *string
	awsSecretKeyID *string
	tagOverride    *string
	dryRun         *bool
}

var re = regexp.MustCompile(`.*\.json$`)

func parseDockerImage(image string) (url, tag string) {
	r := strings.Split(image, ":")
	if len(r) == 2 {
		return r[0], r[1]
	}
	return r[0], ""
}

func fileList(root string) ([]string, error) {
	if root == "" {
		return nil, nil
	}
	ret := []string{}
	err := filepath.Walk(root,
		func(path string, info os.FileInfo, err error) error {
			if info == nil {
				return errors.New("file info is nil")
			}
			if info.IsDir() {
				return nil
			}

			rel, err := filepath.Rel(root, path)
			if re.MatchString(rel) {
				ret = append(ret, rel)
			}

			return nil
		})

	if err != nil {
		return nil, err
	}

	return ret, nil
}

type deployConfigure struct {
	*setting.Setting
}

func isEncrypted(data []byte) bool {
	var buffer = map[string]interface{}{}
	if err := json.Unmarshal(data, &buffer); err != nil {
		return false
	}
	elem, ok := buffer["cipher"]
	if !ok {
		return false
	}
	str, ok := elem.(string)
	if !ok {
		return false
	}

	return len(str) != 0
}

func (d *DeployCommand) decrypt(bin []byte) ([]byte, error) {
	kms := lib.NewKMSFromBinary(bin, d.sess)
	if kms == nil {
		return nil, errors.New(fmt.Sprintf("%v format is illegal", string(bin)))
	}
	plainText, err := kms.SetKeyID(*d.kmsKeyID).Decrypt()
	if err != nil {
		return nil, err
	}
	return plainText, nil
}

func (d *DeployCommand) readConf(base []byte, externalPathList []string) (*deployConfigure, error) {
	var root = *d.externalPath
	var ret = &deployConfigure{}
	baseStr := string(base)

	root = strings.TrimSuffix(root, "/")
	for _, externalPath := range externalPathList {
		external, err := ioutil.ReadFile(root + "/" + externalPath)
		if err != nil {
			return nil, err
		}
		if isEncrypted(external) {
			plain, err := d.decrypt(external)
			if err != nil {
				return nil, err
			}
			external = plain
		}
		baseStr, err = lib.Embedde(baseStr, string(external))
		if err != nil {
			return nil, err
		}
	}
	if err := json.Unmarshal([]byte(baseStr), ret); err != nil {
		return nil, err
	}
	return ret, nil
}

func (d *DeployCommand) parseArgs(args []string) (helpString string) {
	flagSet := new(flag.FlagSet)
	var f *string

	buffer := new(bytes.Buffer)
	flagSet.SetOutput(buffer)

	d.kmsKeyID = flagSet.String("key_id", getenv.String("KMS_KEY_ID"), "Amazon KMS key ID")
	d.file = flagSet.String("file", "", "target file")
	f = flagSet.String("f", "", "target file")
	d.profile = flagSet.String("profile", getenv.String("AWS_PROFILE_NAME", "default"), "aws credentials profile name")
	d.region = flagSet.String("region", getenv.String("AWS_REGION", "ap-northeast-1"), "aws region")
	d.externalPath = flagSet.String("vars_path", getenv.String("PNZR_VARS_PATH"), "external conf path")
	d.outerVals = flagSet.String("V", "", "outer values")
	d.tagOverride = flagSet.String("t", getenv.String("DOCKER_DEFAULT_DEPLOY_TAG", "latest"), "tag override param")
	d.awsAccessKeyID = flagSet.String("aws-access-key-id", getenv.String("AWS_ACCESS_KEY_ID"), "aws access key id")
	d.awsSecretKeyID = flagSet.String("aws-secret-key-id", getenv.String("AWS_SECRET_KEY_ID"), "aws secret key id")
	d.dryRun = flagSet.Bool("dry-run", false, "dry run mode")

	if err := flagSet.Parse(args); err != nil {
		if err == flag.ErrHelp {
			return buffer.String()
		}
		panic(err)
	}

	if *f == "" && *d.file == "" && len(flagSet.Args()) != 0 {
		targetName := flagSet.Args()[0]
		d.file = &targetName
	}

	if *d.file == "" {
		d.file = f
	}

	var awsConfig = aws.Config{}

	if *d.awsAccessKeyID != "" && *d.awsSecretKeyID != "" && *d.profile == "" {
		awsConfig.Credentials = credentials.NewStaticCredentials(*d.awsAccessKeyID, *d.awsSecretKeyID, "")
		awsConfig.Region = d.region
	}

	d.sess = session.Must(session.NewSessionWithOptions(session.Options{
		AssumeRoleTokenProvider: stscreds.StdinTokenProvider,
		SharedConfigState:       session.SharedConfigEnable,
		Profile:                 *d.profile,
		Config:                  awsConfig,
	}))

	return
}

func (d *DeployCommand) Run(args []string) int {
	d.parseArgs(args)
	var config = &deployConfigure{}

	externalList, err := fileList(*d.externalPath)
	if err != nil {
		log.Fatalln(err)
	}
	baseConfBinary, err := ioutil.ReadFile(*d.file)
	if err != nil {
		log.Fatal(err)
	}

	if *d.outerVals != "" {
		baseStr, err := lib.Embedde(string(baseConfBinary), *d.outerVals)
		if err == nil {
			baseConfBinary = []byte(baseStr)
		}
	}

	if externalList != nil {
		c, err := d.readConf(baseConfBinary, externalList)
		if err != nil {
			log.Fatalln(err)
		}
		config = c
	} else {
		bin, err := ioutil.ReadFile(*d.file)
		if err != nil {
			log.Fatalln(err)
		}
		if err := json.Unmarshal(bin, config); err != nil {
			log.Fatalln(err)
		}
	}

	for i, containerDefinition := range config.ECS.TaskDefinition.ContainerDefinitions {
		imageName, tag := parseDockerImage(*containerDefinition.Image)
		if tag == "$tag" {
			image := imageName + ":" + *d.tagOverride
			config.ECS.TaskDefinition.ContainerDefinitions[i].Image = &image
		} else if tag == "" {
			image := imageName + ":" + "latest"
			config.ECS.TaskDefinition.ContainerDefinitions[i].Image = &image
		}
	}

	if *d.dryRun {
		f, err := os.Open("/dev/stderr")
		if err != nil {
			panic(err)
		}
		fmt.Fprintf(f, "******** DRY RUN ********\n%s\n", *config.ECS)
		f.Close()
		return 0
	}

	result, err := api.Deploy(d.sess, config.Setting)
	if err != nil {
		log.Fatalln(err)
	}
	resultJSON, err := json.MarshalIndent(result, "", "    ")
	if err != nil {
		log.Fatalln(err)
	}
	fmt.Println(string(resultJSON))
	return 0
}

func (c *DeployCommand) Synopsis() string {
	return "Deploy docker on ecs."
}

func (c *DeployCommand) Help() string {
	return c.parseArgs([]string{"-h"})
}
<|endoftext|>


<commit_before>package dom

import (
	"testing"
)

// Tests basic getters etc.
func TestAttrGetters(t *testing.T) {
	doc := NewDocument()
	elem, _ := doc.CreateElement("tag")
	doc.AppendChild(elem)
	a, _ := doc.CreateAttributeNS("http://example.org/lol", "pfx:cruft")
	elem.SetAttributeNode(a)
	a.SetValue("valval")
	if a.GetName() != "pfx:cruft" {
		t.Error("incorrect node name")
	}
	if a.GetNodeName() != "pfx:cruft" {
		t.Error("incorrect node name")
	}
	if a.GetLocalName() != "cruft" {
		t.Error("incorrect node name")
	}
	if a.GetNamespacePrefix() != "pfx" {
		t.Error("incorrect prefix")
	}
	if a.GetNamespaceURI() != "http://example.org/lol" {
		t.Error("incorrect namespace URI")
	}
	if a.GetParentNode() != nil {
		t.Error("attr cannot have a parent (must be nil)")
	}
	bogusElem, _ := doc.CreateElement("bogus")
	if err := a.AppendChild(bogusElem); err == nil {
		t.Error("expected an error at this point")
	}
	a.setParentNode(bogusElem)
	if a.GetParentNode() != nil {
		t.Error("parent node should be nil at all times")
	}
	if len(a.GetChildNodes()) != 0 {
		t.Error("len of child nodes must be zero at all times")
	}
	if a.GetFirstChild() != nil {
		t.Error("first child must always be nil")
	}
	if a.GetAttributes() != nil {
		t.Error("attributes must always be nil")
	}
	if a.GetOwnerDocument() != doc {
		t.Error("incorrect owner document")
	}
	if a.HasChildNodes() != false {
		t.Error("must always return false, but was true")
	}
	if a.GetOwnerElement() != elem {
		t.Error("incorrect owner element")
	}
	if a.GetNodeType() != AttributeNode {
		t.Errorf("incorrect node type for attribute")
	}
	if a.GetNodeValue() != "valval" {
		t.Errorf("incorrect node value: '%v'", a.GetNodeValue())
	}
	if a.GetValue() != "valval" {
		t.Errorf("incorrect node value: '%v'", a.GetValue())
	}
	if a.GetPreviousSibling() != nil {
		t.Error("expected nil previous sibling")
	}
	if a.GetNextSibling() != nil {
		t.Error("expected nil next sibling")
	}
	if a.GetLastChild() != nil {
		t.Error("expecting nil last child")
	}
}

func TestAttrLookupNamespaceURI(t *testing.T) {
	doc := NewDocument()

	root, _ := doc.CreateElement("root")
	root.SetAttribute("xmlns:pfx", "http://example.org/pfx")
	root.SetAttribute("xmlns:xfb", "urn:xfbcft")

	child, _ := doc.CreateElement("child")
	root.AppendChild(child) // must append child first or else SetAttribute fails.

	child.SetAttribute("pfx:name", "Mimi")

	t.Log(child.GetAttributes().GetItems())

	attr, ok := child.GetAttributes().GetNamedItem("pfx:name").(Attr)
	if !ok {
		t.Error("expected type assertion ok for Attr")
		t.FailNow()
	}

	ns, found := attr.LookupNamespaceURI("pfx")
	exp := "http://example.org/pfx"
	if ns != exp || !found {
		t.Errorf("expected '%v', got '%v'", exp, ns)
	}

	// Attribute node owned by nothing:
	attr, _ = doc.CreateAttribute("no-owner")
	if _, found := attr.LookupNamespaceURI("pfxWhatever"); found {
		t.Error("expecting false")
	}
}

func TestAttrLookupPrefix(t *testing.T) {
	doc := NewDocument()
	root, _ := doc.CreateElementNS("urn:ns:attr1", "ns1:root")
	sub1, _ := doc.CreateElement("ns1:sub1")
	sub2, _ := doc.CreateElement("ns1:sub2")
	sub3, _ := doc.CreateElement("ns1:sub3")
	sub4, _ := doc.CreateElement("ns1:sub4")

	attr1, _ := doc.CreateAttribute("ns1:name")
	attr1.SetValue("melissandre")

	doc.AppendChild(root)
	root.AppendChild(sub1)
	root.AppendChild(sub2)
	root.AppendChild(sub3)
	root.AppendChild(sub4)
	sub4.SetAttributeNode(attr1)

	pfx := attr1.LookupPrefix("urn:ns:attr1")
	if pfx != "ns1" {
		t.Errorf("expected 'ns1', got '%v'", pfx)
	}

	// Attribute node owned by nothing:
	attr1, _ = doc.CreateAttribute("no-owner")
	if attr1.LookupPrefix("n") != "" {
		t.Error("expecting empty string")
	}
}

func TestAttrReplaceInsertRemoveChild(t *testing.T) {
	doc := NewDocument()
	attr, _ := doc.CreateAttribute("attr")
	if _, err := attr.ReplaceChild(nil, nil); err == nil {
		t.Error("expected error")
	}
	if _, err := attr.InsertBefore(nil, nil); err == nil {
		t.Error("expected error")
	}
	if _, err := attr.RemoveChild(nil); err == nil {
		t.Error("expected error")
	}
}
<commit_msg>Log gone.<commit_after>package dom

import (
	"testing"
)

// Tests basic getters etc.
func TestAttrGetters(t *testing.T) {
	doc := NewDocument()
	elem, _ := doc.CreateElement("tag")
	doc.AppendChild(elem)
	a, _ := doc.CreateAttributeNS("http://example.org/lol", "pfx:cruft")
	elem.SetAttributeNode(a)
	a.SetValue("valval")
	if a.GetName() != "pfx:cruft" {
		t.Error("incorrect node name")
	}
	if a.GetNodeName() != "pfx:cruft" {
		t.Error("incorrect node name")
	}
	if a.GetLocalName() != "cruft" {
		t.Error("incorrect node name")
	}
	if a.GetNamespacePrefix() != "pfx" {
		t.Error("incorrect prefix")
	}
	if a.GetNamespaceURI() != "http://example.org/lol" {
		t.Error("incorrect namespace URI")
	}
	if a.GetParentNode() != nil {
		t.Error("attr cannot have a parent (must be nil)")
	}
	bogusElem, _ := doc.CreateElement("bogus")
	if err := a.AppendChild(bogusElem); err == nil {
		t.Error("expected an error at this point")
	}
	a.setParentNode(bogusElem)
	if a.GetParentNode() != nil {
		t.Error("parent node should be nil at all times")
	}
	if len(a.GetChildNodes()) != 0 {
		t.Error("len of child nodes must be zero at all times")
	}
	if a.GetFirstChild() != nil {
		t.Error("first child must always be nil")
	}
	if a.GetAttributes() != nil {
		t.Error("attributes must always be nil")
	}
	if a.GetOwnerDocument() != doc {
		t.Error("incorrect owner document")
	}
	if a.HasChildNodes() != false {
		t.Error("must always return false, but was true")
	}
	if a.GetOwnerElement() != elem {
		t.Error("incorrect owner element")
	}
	if a.GetNodeType() != AttributeNode {
		t.Errorf("incorrect node type for attribute")
	}
	if a.GetNodeValue() != "valval" {
		t.Errorf("incorrect node value: '%v'", a.GetNodeValue())
	}
	if a.GetValue() != "valval" {
		t.Errorf("incorrect node value: '%v'", a.GetValue())
	}
	if a.GetPreviousSibling() != nil {
		t.Error("expected nil previous sibling")
	}
	if a.GetNextSibling() != nil {
		t.Error("expected nil next sibling")
	}
	if a.GetLastChild() != nil {
		t.Error("expecting nil last child")
	}
}

func TestAttrLookupNamespaceURI(t *testing.T) {
	doc := NewDocument()

	root, _ := doc.CreateElement("root")
	root.SetAttribute("xmlns:pfx", "http://example.org/pfx")
	root.SetAttribute("xmlns:xfb", "urn:xfbcft")

	child, _ := doc.CreateElement("child")
	root.AppendChild(child) // must append child first or else SetAttribute fails.

	child.SetAttribute("pfx:name", "Mimi")

	attr, ok := child.GetAttributes().GetNamedItem("pfx:name").(Attr)
	if !ok {
		t.Error("expected type assertion ok for Attr")
		t.FailNow()
	}

	ns, found := attr.LookupNamespaceURI("pfx")
	exp := "http://example.org/pfx"
	if ns != exp || !found {
		t.Errorf("expected '%v', got '%v'", exp, ns)
	}

	// Attribute node owned by nothing:
	attr, _ = doc.CreateAttribute("no-owner")
	if _, found := attr.LookupNamespaceURI("pfxWhatever"); found {
		t.Error("expecting false")
	}
}

func TestAttrLookupPrefix(t *testing.T) {
	doc := NewDocument()
	root, _ := doc.CreateElementNS("urn:ns:attr1", "ns1:root")
	sub1, _ := doc.CreateElement("ns1:sub1")
	sub2, _ := doc.CreateElement("ns1:sub2")
	sub3, _ := doc.CreateElement("ns1:sub3")
	sub4, _ := doc.CreateElement("ns1:sub4")

	attr1, _ := doc.CreateAttribute("ns1:name")
	attr1.SetValue("melissandre")

	doc.AppendChild(root)
	root.AppendChild(sub1)
	root.AppendChild(sub2)
	root.AppendChild(sub3)
	root.AppendChild(sub4)
	sub4.SetAttributeNode(attr1)

	pfx := attr1.LookupPrefix("urn:ns:attr1")
	if pfx != "ns1" {
		t.Errorf("expected 'ns1', got '%v'", pfx)
	}

	// Attribute node owned by nothing:
	attr1, _ = doc.CreateAttribute("no-owner")
	if attr1.LookupPrefix("n") != "" {
		t.Error("expecting empty string")
	}
}

func TestAttrReplaceInsertRemoveChild(t *testing.T) {
	doc := NewDocument()
	attr, _ := doc.CreateAttribute("attr")
	if _, err := attr.ReplaceChild(nil, nil); err == nil {
		t.Error("expected error")
	}
	if _, err := attr.InsertBefore(nil, nil); err == nil {
		t.Error("expected error")
	}
	if _, err := attr.RemoveChild(nil); err == nil {
		t.Error("expected error")
	}
}
<|endoftext|>