<commit_before>/*
Copyright IBM Corp. 2016 All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

		 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package util

import (
	"fmt"
	"github.com/op/go-logging"
	"os"
	"sync"
)

const (
	LOGGING_MESSAGE_BUFF_MODULE = "mbuff"
	LOGGING_EMITTER_MODULE      = "emitter"
	LOGGING_GOSMEMBER_MODULE    = "gossip"
	LOGGING_DISCOVERY_MODULE    = "discovery"
)

var loggersByModules = make(map[string]*Logger)
var defaultLevel = logging.WARNING
var lock = sync.Mutex{}

var format = logging.MustStringFormatter(
	`%{color}%{level} %{longfunc}():%{color:reset}(%{module})%{message}`,
)

func init() {
	logging.SetFormatter(format)
}

type Logger struct {
	lock   *sync.Mutex
	logger logging.Logger
	module string
}

func SetDefaultFormat(formatStr string) {
	format = logging.MustStringFormatter(formatStr)
}

func SetDefaultLoggingLevel(level logging.Level) {
	defaultLevel = level
}

func (l *Logger) SetLevel(lvl logging.Level) {
	logging.SetLevel(lvl, l.module)
}

func GetLogger(module string, peerId string) *Logger {
	module = module + "-" + peerId
	lock.Lock()
	defer lock.Unlock()

	if lgr, ok := loggersByModules[module]; ok {
		return lgr
	}

	// Logger doesn't exist, create a new one

	lvl, err := logging.LogLevel(defaultLevel.String())
	// Shouldn't happen, since setting default logging level validity
	// is checked in compile-time
	if err != nil {
		fmt.Fprintf(os.Stderr, "Invalid default logging level: %v\n", err)
		return nil
	}
	logging.SetLevel(lvl, module)
	lgr := &Logger{lock: &sync.Mutex{}}
	lgr.logger = *logging.MustGetLogger(module)
	lgr.logger.ExtraCalldepth++
	lgr.module = module
	loggersByModules[module] = lgr
	return lgr
}

func (l *Logger) Fatal(args ...interface{}) {
	l.lock.Lock()
	defer l.lock.Unlock()
	l.logger.Fatal(args)
}

func (l *Logger) Fatalf(format string, args ...interface{}) {
	l.lock.Lock()
	defer l.lock.Unlock()
	l.logger.Fatalf(format, args)
}

func (l *Logger) Panic(args ...interface{}) {
	l.lock.Lock()
	defer l.lock.Unlock()
	l.logger.Panic(args)
}

func (l *Logger) Panicf(format string, args ...interface{}) {
	l.lock.Lock()
	defer l.lock.Unlock()
	l.logger.Panicf(format, args)
}

func (l *Logger) Critical(args ...interface{}) {
	l.lock.Lock()
	defer l.lock.Unlock()
	l.logger.Critical(args)
}

func (l *Logger) Criticalf(format string, args ...interface{}) {
	l.lock.Lock()
	defer l.lock.Unlock()
	l.logger.Criticalf(format, args)
}

func (l *Logger) Error(args ...interface{}) {
	l.lock.Lock()
	defer l.lock.Unlock()
	l.logger.Error(args)
}

func (l *Logger) Errorf(format string, args ...interface{}) {
	l.lock.Lock()
	defer l.lock.Unlock()
	l.logger.Errorf(format, args)
}

func (l *Logger) Warning(args ...interface{}) {
	l.lock.Lock()
	defer l.lock.Unlock()
	l.logger.Warning(args)
}

func (l *Logger) Warningf(format string, args ...interface{}) {
	l.lock.Lock()
	defer l.lock.Unlock()
	l.logger.Warningf(format, args)
}

func (l *Logger) Notice(args ...interface{}) {
	l.lock.Lock()
	defer l.lock.Unlock()
	l.logger.Notice(args)
}

func (l *Logger) Noticef(format string, args ...interface{}) {
	l.lock.Lock()
	defer l.lock.Unlock()
	l.logger.Noticef(format, args)
}

func (l *Logger) Info(args ...interface{}) {
	l.lock.Lock()
	defer l.lock.Unlock()
	l.logger.Info(args)
}

func (l *Logger) Infof(format string, args ...interface{}) {
	l.lock.Lock()
	defer l.lock.Unlock()
	l.logger.Infof(format, args)
}

func (l *Logger) Debug(args ...interface{}) {
	l.lock.Lock()
	defer l.lock.Unlock()
	l.logger.Debug(args)
}

func (l *Logger) Debugf(format string, args ...interface{}) {
	l.lock.Lock()
	defer l.lock.Unlock()
	l.logger.Debugf(format, args)
}
<commit_msg>Urgent logging fix for gossip<commit_after>/*
Copyright IBM Corp. 2016 All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

		 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package util

import (
	"fmt"
	"github.com/op/go-logging"
	"os"
	"sync"
)

const (
	LOGGING_MESSAGE_BUFF_MODULE = "mbuff"
	LOGGING_EMITTER_MODULE      = "emitter"
	LOGGING_GOSMEMBER_MODULE    = "gossip"
	LOGGING_DISCOVERY_MODULE    = "discovery"
)

var loggersByModules = make(map[string]*Logger)
var defaultLevel = logging.WARNING
var lock = sync.Mutex{}

var format = logging.MustStringFormatter(
	`%{color}%{level} %{longfunc}():%{color:reset}(%{module})%{message}`,
)

func init() {
	logging.SetFormatter(format)
}

type Logger struct {
	logger logging.Logger
	module string
}

func SetDefaultFormat(formatStr string) {
	format = logging.MustStringFormatter(formatStr)
}

func SetDefaultLoggingLevel(level logging.Level) {
	defaultLevel = level
}

func (l *Logger) SetLevel(lvl logging.Level) {
	logging.SetLevel(lvl, l.module)
}

func GetLogger(module string, peerId string) *Logger {
	module = module + "-" + peerId
	lock.Lock()
	defer lock.Unlock()

	if lgr, ok := loggersByModules[module]; ok {
		return lgr
	}

	// Logger doesn't exist, create a new one

	lvl, err := logging.LogLevel(defaultLevel.String())
	// Shouldn't happen, since setting default logging level validity
	// is checked in compile-time
	if err != nil {
		fmt.Fprintf(os.Stderr, "Invalid default logging level: %v\n", err)
		return nil
	}
	logging.SetLevel(lvl, module)
	lgr := &Logger{}
	lgr.logger = *logging.MustGetLogger(module)
	lgr.logger.ExtraCalldepth++
	lgr.module = module
	loggersByModules[module] = lgr
	return lgr
}

func (l *Logger) Fatal(args ...interface{}) {
	lock.Lock()
	defer lock.Unlock()
	l.logger.Fatal(args)
}

func (l *Logger) Fatalf(format string, args ...interface{}) {
	lock.Lock()
	defer lock.Unlock()
	l.logger.Fatalf(format, args)
}

func (l *Logger) Panic(args ...interface{}) {
	lock.Lock()
	defer lock.Unlock()
	l.logger.Panic(args)
}

func (l *Logger) Panicf(format string, args ...interface{}) {
	lock.Lock()
	defer lock.Unlock()
	l.logger.Panicf(format, args)
}

func (l *Logger) Critical(args ...interface{}) {
	lock.Lock()
	defer lock.Unlock()
	l.logger.Critical(args)
}

func (l *Logger) Criticalf(format string, args ...interface{}) {
	lock.Lock()
	defer lock.Unlock()
	l.logger.Criticalf(format, args)
}

func (l *Logger) Error(args ...interface{}) {
	lock.Lock()
	defer lock.Unlock()
	l.logger.Error(args)
}

func (l *Logger) Errorf(format string, args ...interface{}) {
	lock.Lock()
	defer lock.Unlock()
	l.logger.Errorf(format, args)
}

func (l *Logger) Warning(args ...interface{}) {
	lock.Lock()
	defer lock.Unlock()
	l.logger.Warning(args)
}

func (l *Logger) Warningf(format string, args ...interface{}) {
	lock.Lock()
	defer lock.Unlock()
	l.logger.Warningf(format, args)
}

func (l *Logger) Notice(args ...interface{}) {
	lock.Lock()
	defer lock.Unlock()
	l.logger.Notice(args)
}

func (l *Logger) Noticef(format string, args ...interface{}) {
	lock.Lock()
	defer lock.Unlock()
	l.logger.Noticef(format, args)
}

func (l *Logger) Info(args ...interface{}) {
	lock.Lock()
	defer lock.Unlock()
	l.logger.Info(args)
}

func (l *Logger) Infof(format string, args ...interface{}) {
	lock.Lock()
	defer lock.Unlock()
	l.logger.Infof(format, args)
}

func (l *Logger) Debug(args ...interface{}) {
	lock.Lock()
	defer lock.Unlock()
	l.logger.Debug(args)
}

func (l *Logger) Debugf(format string, args ...interface{}) {
	lock.Lock()
	defer lock.Unlock()
	l.logger.Debugf(format, args)
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package disk

import (
	"context"
	"flag"
	"fmt"
	"strings"

	"github.com/vmware/govmomi/govc/cli"
	"github.com/vmware/govmomi/govc/flags"
	"github.com/vmware/govmomi/vim25/types"
)

type attach struct {
	*flags.DatastoreFlag
	*flags.VirtualMachineFlag

	persist    bool
	link       bool
	disk       string
	controller string
	sharing    string
}

func init() {
	cli.Register("vm.disk.attach", &attach{})
}

func (cmd *attach) Register(ctx context.Context, f *flag.FlagSet) {
	cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
	cmd.DatastoreFlag.Register(ctx, f)
	cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
	cmd.VirtualMachineFlag.Register(ctx, f)

	f.BoolVar(&cmd.persist, "persist", true, "Persist attached disk")
	f.BoolVar(&cmd.link, "link", true, "Link specified disk")
	f.StringVar(&cmd.controller, "controller", "", "Disk controller")
	f.StringVar(&cmd.disk, "disk", "", "Disk path name")
	f.StringVar(&cmd.sharing, "sharing", "", fmt.Sprintf("Sharing (%s)", strings.Join(sharing, "|")))
}

func (cmd *attach) Process(ctx context.Context) error {
	if err := cmd.DatastoreFlag.Process(ctx); err != nil {
		return err
	}
	if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
		return err
	}
	return nil
}

func (cmd *attach) Description() string {
	return `Attach existing disk to VM.

Examples:
  govc vm.disk.attach -vm $name -disk $name/disk1.vmdk
  govc vm.disk.attach -vm $name -disk $name/shared.vmdk -link=false -sharing sharingMultiWriter`
}

func (cmd *attach) Run(ctx context.Context, f *flag.FlagSet) error {
	vm, err := cmd.VirtualMachine()
	if err != nil {
		return err
	}

	if vm == nil {
		return flag.ErrHelp
	}

	ds, err := cmd.Datastore()
	if err != nil {
		return err
	}

	devices, err := vm.Device(ctx)
	if err != nil {
		return err
	}

	controller, err := devices.FindDiskController(cmd.controller)
	if err != nil {
		return err
	}

	disk := devices.CreateDisk(controller, ds.Reference(), ds.Path(cmd.disk))
	backing := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo)
	backing.Sharing = cmd.sharing

	if cmd.link {
		if cmd.persist {
			backing.DiskMode = string(types.VirtualDiskModeIndependent_persistent)
		} else {
			backing.DiskMode = string(types.VirtualDiskModeIndependent_nonpersistent)
		}

		disk = devices.ChildDisk(disk)
		return vm.AddDevice(ctx, disk)
	}

	if cmd.persist {
		backing.DiskMode = string(types.VirtualDiskModePersistent)
	} else {
		backing.DiskMode = string(types.VirtualDiskModeNonpersistent)
	}

	return vm.AddDevice(ctx, disk)
}
<commit_msg>govc: add vm.disk.attach -mode flag<commit_after>/*
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package disk

import (
	"context"
	"flag"
	"fmt"
	"strings"

	"github.com/vmware/govmomi/govc/cli"
	"github.com/vmware/govmomi/govc/flags"
	"github.com/vmware/govmomi/vim25/types"
)

type attach struct {
	*flags.DatastoreFlag
	*flags.VirtualMachineFlag

	persist    bool
	link       bool
	disk       string
	controller string
	mode       string
	sharing    string
}

func init() {
	cli.Register("vm.disk.attach", &attach{})
}

func (cmd *attach) Register(ctx context.Context, f *flag.FlagSet) {
	cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
	cmd.DatastoreFlag.Register(ctx, f)
	cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
	cmd.VirtualMachineFlag.Register(ctx, f)

	f.BoolVar(&cmd.persist, "persist", true, "Persist attached disk")
	f.BoolVar(&cmd.link, "link", true, "Link specified disk")
	f.StringVar(&cmd.controller, "controller", "", "Disk controller")
	f.StringVar(&cmd.disk, "disk", "", "Disk path name")
	f.StringVar(&cmd.mode, "mode", "", fmt.Sprintf("Disk mode (%s)", strings.Join(vdmTypes, "|")))
	f.StringVar(&cmd.sharing, "sharing", "", fmt.Sprintf("Sharing (%s)", strings.Join(sharing, "|")))
}

func (cmd *attach) Process(ctx context.Context) error {
	if err := cmd.DatastoreFlag.Process(ctx); err != nil {
		return err
	}
	if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
		return err
	}
	return nil
}

func (cmd *attach) Description() string {
	return `Attach existing disk to VM.

Examples:
  govc vm.disk.attach -vm $name -disk $name/disk1.vmdk
  govc vm.disk.attach -vm $name -disk $name/shared.vmdk -link=false -sharing sharingMultiWriter`
}

func (cmd *attach) Run(ctx context.Context, f *flag.FlagSet) error {
	vm, err := cmd.VirtualMachine()
	if err != nil {
		return err
	}

	if vm == nil {
		return flag.ErrHelp
	}

	ds, err := cmd.Datastore()
	if err != nil {
		return err
	}

	devices, err := vm.Device(ctx)
	if err != nil {
		return err
	}

	controller, err := devices.FindDiskController(cmd.controller)
	if err != nil {
		return err
	}

	disk := devices.CreateDisk(controller, ds.Reference(), ds.Path(cmd.disk))
	backing := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo)
	backing.Sharing = cmd.sharing

	if len(cmd.mode) != 0 {
		backing.DiskMode = cmd.mode
	}

	if cmd.link {
		if cmd.persist {
			backing.DiskMode = string(types.VirtualDiskModeIndependent_persistent)
		} else {
			backing.DiskMode = string(types.VirtualDiskModeIndependent_nonpersistent)
		}

		disk = devices.ChildDisk(disk)
		return vm.AddDevice(ctx, disk)
	}

	if cmd.persist {
		backing.DiskMode = string(types.VirtualDiskModePersistent)
	} else {
		backing.DiskMode = string(types.VirtualDiskModeNonpersistent)
	}

	return vm.AddDevice(ctx, disk)
}
<|endoftext|>


<commit_before>package rest

import (
	"errors"
	"github.com/smancke/guble/protocol"
	"github.com/smancke/guble/server"

	"github.com/rs/xid"

	"bytes"
	"io/ioutil"
	"net/http"
	"strings"
)

const X_HEADER_PREFIX = "x-guble-"

var errNotFound = errors.New("Not Found.")

type RestMessageAPI struct {
	router server.Router
	prefix string
}

func NewRestMessageAPI(router server.Router, prefix string) *RestMessageAPI {
	return &RestMessageAPI{router, prefix}
}

func (api *RestMessageAPI) GetPrefix() string {
	return api.prefix
}

func (api *RestMessageAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		http.Error(w, `Can not read body`, http.StatusBadRequest)
		return
	}

	topic, err := api.extractTopic(r.URL.Path)
	if err != nil {
		if err == errNotFound {
			http.NotFound(w, r)
			return
		}
		http.Error(w, "Server error.", http.StatusInternalServerError)
		return
	}

	msg := &protocol.Message{
		Path:          protocol.Path(topic),
		Body:          body,
		UserID:        q(r, `userId`),
		ApplicationID: xid.New().String(),
		MessageID:     q(r, `messageId`),
		HeaderJSON:    headersToJSON(r.Header),
	}

	api.router.HandleMessage(msg)
}

func (api *RestMessageAPI) extractTopic(path string) (string, error) {
	p := removeTrailingSlash(api.prefix) + "/message"
	if !strings.HasPrefix(path, p) {
		return "", errNotFound
	}

	// Remove "`api.prefix` + /message" and we remain with the topic
	topic := strings.TrimPrefix(path, p)
	if topic == "/" || topic == "" {
		return "", errNotFound
	}

	return topic, nil
}

// returns a query parameter
func q(r *http.Request, name string) string {
	params := r.URL.Query()[name]
	if len(params) > 0 {
		return params[0]
	}
	return ""
}

func headersToJSON(header http.Header) string {
	buff := &bytes.Buffer{}
	buff.WriteString("{")

	count := 0
	for key, valueList := range header {
		if strings.HasPrefix(strings.ToLower(key), X_HEADER_PREFIX) && len(valueList) > 0 {
			if count > 0 {
				buff.WriteString(",")
			}
			buff.WriteString(`"`)
			buff.WriteString(key[len(X_HEADER_PREFIX):])
			buff.WriteString(`":`)
			buff.WriteString(`"`)
			buff.WriteString(valueList[0])
			buff.WriteString(`"`)
			count++
		}
	}
	buff.WriteString("}")
	return string(buff.Bytes())
}

func removeTrailingSlash(path string) string {
	if len(path) > 1 && path[len(path)-1] == '/' {
		return path[:len(path)-1]
	}
	return path
}
<commit_msg>adding health in REST-API<commit_after>package rest

import (
	"errors"
	"github.com/smancke/guble/protocol"
	"github.com/smancke/guble/server"

	"github.com/rs/xid"

	"bytes"
	"io/ioutil"
	"net/http"
	"strings"
)

const X_HEADER_PREFIX = "x-guble-"

var errNotFound = errors.New("Not Found.")

type RestMessageAPI struct {
	router server.Router
	prefix string
}

func NewRestMessageAPI(router server.Router, prefix string) *RestMessageAPI {
	return &RestMessageAPI{router, prefix}
}

func (api *RestMessageAPI) GetPrefix() string {
	return api.prefix
}

func (api *RestMessageAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		http.Error(w, `Can not read body`, http.StatusBadRequest)
		return
	}

	topic, err := api.extractTopic(r.URL.Path)
	if err != nil {
		if err == errNotFound {
			http.NotFound(w, r)
			return
		}
		http.Error(w, "Server error.", http.StatusInternalServerError)
		return
	}

	msg := &protocol.Message{
		Path:          protocol.Path(topic),
		Body:          body,
		UserID:        q(r, `userId`),
		ApplicationID: xid.New().String(),
		MessageID:     q(r, `messageId`),
		HeaderJSON:    headersToJSON(r.Header),
	}

	api.router.HandleMessage(msg)
}

func (api *RestMessageAPI) Check() error {
	return nil
}

func (api *RestMessageAPI) extractTopic(path string) (string, error) {
	p := removeTrailingSlash(api.prefix) + "/message"
	if !strings.HasPrefix(path, p) {
		return "", errNotFound
	}

	// Remove "`api.prefix` + /message" and we remain with the topic
	topic := strings.TrimPrefix(path, p)
	if topic == "/" || topic == "" {
		return "", errNotFound
	}

	return topic, nil
}

// returns a query parameter
func q(r *http.Request, name string) string {
	params := r.URL.Query()[name]
	if len(params) > 0 {
		return params[0]
	}
	return ""
}

func headersToJSON(header http.Header) string {
	buff := &bytes.Buffer{}
	buff.WriteString("{")

	count := 0
	for key, valueList := range header {
		if strings.HasPrefix(strings.ToLower(key), X_HEADER_PREFIX) && len(valueList) > 0 {
			if count > 0 {
				buff.WriteString(",")
			}
			buff.WriteString(`"`)
			buff.WriteString(key[len(X_HEADER_PREFIX):])
			buff.WriteString(`":`)
			buff.WriteString(`"`)
			buff.WriteString(valueList[0])
			buff.WriteString(`"`)
			count++
		}
	}
	buff.WriteString("}")
	return string(buff.Bytes())
}

func removeTrailingSlash(path string) string {
	if len(path) > 1 && path[len(path)-1] == '/' {
		return path[:len(path)-1]
	}
	return path
}
<|endoftext|>


<commit_before>/*
Copyright 2022 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"strings"
	"sync"

	"context"

	"github.com/sirupsen/logrus"
	"gopkg.in/yaml.v3"
)

const (
	defaultOutputDir = "_output/js"

	rimraf = "node_modules/rimraf/bin.js"
	tsc    = "node_modules/typescript/bin/tsc"
	rollup = "node_modules/rollup/dist/bin/rollup"
	terser = "node_modules/terser/bin/terser"

	defaultRollupConfig = "rollup.config.js"
	defaultTerserConfig = "hack/ts.rollup_bundle.min.minify_options.json"

	defaultWorkersCount = 5
)

var (
	rootDir string
)

func rootDirWithGit() {
	// Best effort
	out, err := runCmd(nil, "git", "rev-parse", "--show-toplevel")
	if err != nil {
		logrus.WithError(err).Warn("Failed getting git root dir")
	}
	rootDir = out
}

type options struct {
	packages    string
	workers     int
	cleanupOnly bool
}

type packagesInfo struct {
	Packages []packageInfo `yaml:"packages"`
}

type packageInfo struct {
	Dir        string `yaml:"dir"`
	Entrypoint string `yaml:"entrypoint"`
	Dst        string `yaml:"dst"`
}

func loadPackagesInfo(f string) (*packagesInfo, error) {
	b, err := ioutil.ReadFile(f)
	if err != nil {
		return nil, fmt.Errorf("reading file %q: %w", f, err)
	}
	var res packagesInfo
	return &res, yaml.Unmarshal(b, &res)
}

// Mock for unit testing purpose
var runCmdInDirFunc = runCmdInDir

func runCmdInDir(dir string, additionalEnv []string, cmd string, args ...string) (string, error) {
	log := logrus.WithFields(logrus.Fields{"cmd": cmd, "args": args})
	command := exec.Command(cmd, args...)
	if dir != "" {
		command.Dir = dir
	}
	command.Env = append(os.Environ(), additionalEnv...)
	stdOut, err := command.StdoutPipe()
	if err != nil {
		return "", err
	}
	stdErr, err := command.StderrPipe()
	if err != nil {
		return "", err
	}
	if err := command.Start(); err != nil {
		return "", err
	}
	scanner := bufio.NewScanner(stdOut)
	var allOut string
	for scanner.Scan() {
		out := scanner.Text()
		allOut = allOut + out
		log.Info(out)
	}
	allErr, _ := io.ReadAll(stdErr)
	err = command.Wait()
	if len(allErr) > 0 {
		if err != nil {
			log.Error(string(allErr))
		} else {
			log.Warn(string(allErr))
		}
	}
	return strings.TrimSpace(allOut), err
}

func runCmd(additionalEnv []string, cmd string, args ...string) (string, error) {
	return runCmdInDirFunc(rootDir, additionalEnv, cmd, args...)
}

func rollupOne(pi *packageInfo, cleanupOnly bool) error {
	entrypointFileBasename := strings.TrimSuffix(path.Base(pi.Entrypoint), ".ts")
	// Intermediate output files, stored under `_output` dir
	jsOutputFile := path.Join(defaultOutputDir, pi.Dir, entrypointFileBasename+".js")
	bundleOutputDir := path.Join(defaultOutputDir, pi.Dir)
	rollupOutputFile := path.Join(bundleOutputDir, "bundle.js")
	// terserOutputFile is the minified bundle, which is placed next to all
	// other static files in the source tree
	terserOutputFile := path.Join(pi.Dir, pi.Dst)
	if cleanupOnly {
		return os.Remove(terserOutputFile)
	}
	if _, err := runCmd(nil, rimraf, "dist"); err != nil {
		return fmt.Errorf("running rimraf: %w", err)
	}
	if _, err := runCmd(nil, tsc, "-p", path.Join(pi.Dir, "tsconfig.json"), "--outDir", defaultOutputDir); err != nil {
		return fmt.Errorf("running tsc: %w", err)
	}
	if _, err := runCmd(nil, rollup, "--environment", fmt.Sprintf("ROLLUP_OUT_FILE:%s,ROLLUP_ENTRYPOINT:%s", rollupOutputFile, jsOutputFile), "-c", defaultRollupConfig, "--preserveSymlinks"); err != nil {
		return fmt.Errorf("running rollup: %w", err)
	}
	if _, err := runCmd(nil, terser, rollupOutputFile, "--output", terserOutputFile, "--config-file", defaultTerserConfig); err != nil {
		return fmt.Errorf("running terser: %w", err)
	}
	return nil
}

func main() {
	var o options
	flag.StringVar(&o.packages, "packages", "", "Yaml file contains list of packages to be rolled up.")
	flag.IntVar(&o.workers, "workers", defaultWorkersCount, "Number of workers in parallel.")
	flag.BoolVar(&o.cleanupOnly, "cleanup-only", false, "Indicate cleanup only.")
	flag.StringVar(&rootDir, "root-dir", "", "Root dir of this repo, where everything happens.")
	flag.Parse()

	if rootDir == "" {
		rootDirWithGit()
	}
	if rootDir == "" {
		logrus.Error("Unable to determine root dir, please pass in --root-dir.")
		os.Exit(1)
	}

	pis, err := loadPackagesInfo(o.packages)
	if err != nil {
		logrus.WithError(err).WithField("packages", o.packages).Error("Failed loading")
		os.Exit(1)
	}

	var wg sync.WaitGroup
	packageChan := make(chan packageInfo, 10)
	errChan := make(chan error, len(pis.Packages))
	doneChan := make(chan packageInfo, len(pis.Packages))
	// Start workers
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	for i := 0; i < o.workers; i++ {
		go func(ctx context.Context, packageChan chan packageInfo, errChan chan error, doneChan chan packageInfo) {
			for {
				select {
				case pi := <-packageChan:
					err := rollupOne(&pi, o.cleanupOnly)
					if err != nil {
						errChan <- fmt.Errorf("rollup package %q failed: %v", pi.Entrypoint, err)
					}
					doneChan <- pi
				case <-ctx.Done():
					return
				}
			}
		}(ctx, packageChan, errChan, doneChan)
	}

	for _, pi := range pis.Packages {
		pi := pi
		wg.Add(1)
		packageChan <- pi
	}

	go func(ctx context.Context, wg *sync.WaitGroup, doneChan chan packageInfo) {
		var done int
		for {
			select {
			case pi := <-doneChan:
				done++
				logrus.WithFields(logrus.Fields{"entrypoint": pi.Entrypoint, "done": done, "total": len(pis.Packages)}).Info("Done with package.")
				wg.Done()
			case <-ctx.Done():
				return
			}
		}
	}(ctx, &wg, doneChan)

	wg.Wait()
	for {
		select {
		case err := <-errChan:
			logrus.WithError(err).Error("Failed.")
			os.Exit(1)
		default:
			return
		}
	}
}
<commit_msg>Fix deck image build flakiness unique intermittent filename<commit_after>/*
Copyright 2022 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"strings"
	"sync"

	"context"

	"github.com/sirupsen/logrus"
	"gopkg.in/yaml.v3"
)

const (
	defaultOutputDir = "_output/js"

	rimraf = "node_modules/rimraf/bin.js"
	tsc    = "node_modules/typescript/bin/tsc"
	rollup = "node_modules/rollup/dist/bin/rollup"
	terser = "node_modules/terser/bin/terser"

	defaultRollupConfig = "rollup.config.js"
	defaultTerserConfig = "hack/ts.rollup_bundle.min.minify_options.json"

	defaultWorkersCount = 5
)

var (
	rootDir string
)

func rootDirWithGit() {
	// Best effort
	out, err := runCmd(nil, "git", "rev-parse", "--show-toplevel")
	if err != nil {
		logrus.WithError(err).Warn("Failed getting git root dir")
	}
	rootDir = out
}

type options struct {
	packages    string
	workers     int
	cleanupOnly bool
}

type packagesInfo struct {
	Packages []packageInfo `yaml:"packages"`
}

type packageInfo struct {
	Dir        string `yaml:"dir"`
	Entrypoint string `yaml:"entrypoint"`
	Dst        string `yaml:"dst"`
}

func loadPackagesInfo(f string) (*packagesInfo, error) {
	b, err := ioutil.ReadFile(f)
	if err != nil {
		return nil, fmt.Errorf("reading file %q: %w", f, err)
	}
	var res packagesInfo
	return &res, yaml.Unmarshal(b, &res)
}

// Mock for unit testing purpose
var runCmdInDirFunc = runCmdInDir

func runCmdInDir(dir string, additionalEnv []string, cmd string, args ...string) (string, error) {
	log := logrus.WithFields(logrus.Fields{"cmd": cmd, "args": args})
	command := exec.Command(cmd, args...)
	if dir != "" {
		command.Dir = dir
	}
	command.Env = append(os.Environ(), additionalEnv...)
	stdOut, err := command.StdoutPipe()
	if err != nil {
		return "", err
	}
	stdErr, err := command.StderrPipe()
	if err != nil {
		return "", err
	}
	if err := command.Start(); err != nil {
		return "", err
	}
	scanner := bufio.NewScanner(stdOut)
	var allOut string
	for scanner.Scan() {
		out := scanner.Text()
		allOut = allOut + out
		log.Info(out)
	}
	allErr, _ := io.ReadAll(stdErr)
	err = command.Wait()
	if len(allErr) > 0 {
		if err != nil {
			log.Error(string(allErr))
		} else {
			log.Warn(string(allErr))
		}
	}
	return strings.TrimSpace(allOut), err
}

func runCmd(additionalEnv []string, cmd string, args ...string) (string, error) {
	return runCmdInDirFunc(rootDir, additionalEnv, cmd, args...)
}

func rollupOne(pi *packageInfo, cleanupOnly bool) error {
	entrypointFileBasename := strings.TrimSuffix(path.Base(pi.Entrypoint), ".ts")
	// Intermediate output files, stored under `_output` dir
	jsOutputFile := path.Join(defaultOutputDir, pi.Dir, entrypointFileBasename+".js")
	bundleOutputDir := path.Join(defaultOutputDir, pi.Dir)
	rollupOutputFile := path.Join(bundleOutputDir, fmt.Sprintf("%s_bundle.js", entrypointFileBasename))
	// terserOutputFile is the minified bundle, which is placed next to all
	// other static files in the source tree
	terserOutputFile := path.Join(pi.Dir, pi.Dst)
	if cleanupOnly {
		return os.Remove(terserOutputFile)
	}
	if _, err := runCmd(nil, rimraf, "dist"); err != nil {
		return fmt.Errorf("running rimraf: %w", err)
	}
	if _, err := runCmd(nil, tsc, "-p", path.Join(pi.Dir, "tsconfig.json"), "--outDir", defaultOutputDir); err != nil {
		return fmt.Errorf("running tsc: %w", err)
	}
	if _, err := runCmd(nil, rollup, "--environment", fmt.Sprintf("ROLLUP_OUT_FILE:%s,ROLLUP_ENTRYPOINT:%s", rollupOutputFile, jsOutputFile), "-c", defaultRollupConfig, "--preserveSymlinks"); err != nil {
		return fmt.Errorf("running rollup: %w", err)
	}
	if _, err := runCmd(nil, terser, rollupOutputFile, "--output", terserOutputFile, "--config-file", defaultTerserConfig); err != nil {
		return fmt.Errorf("running terser: %w", err)
	}
	return nil
}

func main() {
	var o options
	flag.StringVar(&o.packages, "packages", "", "Yaml file contains list of packages to be rolled up.")
	flag.IntVar(&o.workers, "workers", defaultWorkersCount, "Number of workers in parallel.")
	flag.BoolVar(&o.cleanupOnly, "cleanup-only", false, "Indicate cleanup only.")
	flag.StringVar(&rootDir, "root-dir", "", "Root dir of this repo, where everything happens.")
	flag.Parse()

	if rootDir == "" {
		rootDirWithGit()
	}
	if rootDir == "" {
		logrus.Error("Unable to determine root dir, please pass in --root-dir.")
		os.Exit(1)
	}

	pis, err := loadPackagesInfo(o.packages)
	if err != nil {
		logrus.WithError(err).WithField("packages", o.packages).Error("Failed loading")
		os.Exit(1)
	}

	var wg sync.WaitGroup
	packageChan := make(chan packageInfo, 10)
	errChan := make(chan error, len(pis.Packages))
	doneChan := make(chan packageInfo, len(pis.Packages))
	// Start workers
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	for i := 0; i < o.workers; i++ {
		go func(ctx context.Context, packageChan chan packageInfo, errChan chan error, doneChan chan packageInfo) {
			for {
				select {
				case pi := <-packageChan:
					err := rollupOne(&pi, o.cleanupOnly)
					if err != nil {
						errChan <- fmt.Errorf("rollup package %q failed: %v", pi.Entrypoint, err)
					}
					doneChan <- pi
				case <-ctx.Done():
					return
				}
			}
		}(ctx, packageChan, errChan, doneChan)
	}

	for _, pi := range pis.Packages {
		pi := pi
		wg.Add(1)
		packageChan <- pi
	}

	go func(ctx context.Context, wg *sync.WaitGroup, doneChan chan packageInfo) {
		var done int
		for {
			select {
			case pi := <-doneChan:
				done++
				logrus.WithFields(logrus.Fields{"entrypoint": pi.Entrypoint, "done": done, "total": len(pis.Packages)}).Info("Done with package.")
				wg.Done()
			case <-ctx.Done():
				return
			}
		}
	}(ctx, &wg, doneChan)

	wg.Wait()
	for {
		select {
		case err := <-errChan:
			logrus.WithError(err).Error("Failed.")
			os.Exit(1)
		default:
			return
		}
	}
}
<|endoftext|>


<commit_before>package integration

import (
	"log"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"
	"time"

	"github.com/EaseApp/web-backend/src/sync"
	"github.com/gorilla/websocket"
	"github.com/stretchr/testify/assert"
)

func TestSocketConnection(t *testing.T) {
	syncServer := setUpSyncServer(t)
	webServer := setUpServer(t)
	testUser := createTestUser(webServer.URL, t)
	testApplication := createTestApp(webServer.URL, testUser.APIToken, "test", t)

	testcases := []struct {
		subscribeTo                   string
		firstSocketMessage            string
		firstSocketResponse           string
		publishTo                     string
		publishData                   string
		expectedData                  string
		expectedApplicationStatusCode int
	}{
		{
			// Subscribe to an application, get the relavent data
			subscribeTo:                   "ronswanson_test",
			firstSocketMessage:            `{"username": "ronswanson", "application": "test", "authorization": "` + testApplication.AppToken + `"}`,
			firstSocketResponse:           `{"status": "success"}`,
			publishTo:                     "test",
			publishData:                   `{"data": "test"}`,
			expectedData:                  `{"data": "test"}`,
			expectedApplicationStatusCode: http.StatusOK,
		},
		{
			// Subscribe to one application, shouldn't get data with bad Publish call.
			subscribeTo:                   "ronswanson_test",
			firstSocketMessage:            `{"username": "ronswanson", "application": "test", "authorization": "123"}`,
			firstSocketResponse:           `{"status": "failed"}`,
			publishTo:                     "user_differentApp",
			publishData:                   `{"data":"test"}`,
			expectedData:                  "",
			expectedApplicationStatusCode: http.StatusUnauthorized,
		},
	}

	for _, testcase := range testcases {
		port := strings.Split(syncServer.URL, ":")[2]
		conn := openConnection("ws://localhost:" + port + "/sub") // Connect to sync annonymously
		defer conn.Close()

		sendSocketData(conn, testcase.firstSocketMessage)
		assert.Equal(t, testcase.firstSocketResponse, grabSocketData(conn), "Socket response failed")

		path := "/pub/ronswanson/" + testcase.publishTo
		// log.Println(syncServer.URL, path)
		resp := sendJSON(testcase.publishData, testApplication.AppToken, syncServer.URL, path, "POST", t) // Publish to an app
		assert.Equal(t, testcase.expectedApplicationStatusCode, resp.StatusCode)
		actual := grabSocketData(conn)
		assert.Equal(t, testcase.expectedData, actual)

	}
	defer syncServer.Close()
}

func grabSocketData(conn *websocket.Conn) string {
	conn.SetReadDeadline(time.Now().Add(1 * time.Second))
	_, p, err := conn.ReadMessage() // This methods blocks. Make sure to set Deadline
	if err != nil {
		log.Println(err)
	}
	return string(p)

}

func sendSocketData(conn *websocket.Conn, data string) error {
	return conn.WriteMessage(1, []byte(data))
}

func openConnection(url string) *websocket.Conn {
	// log.Println("URL: ", url)
	var DefaultDialer = &websocket.Dialer{
		Proxy: http.ProxyFromEnvironment,
	}

	header := make(http.Header)
	conn, _, err := DefaultDialer.Dial(url, header)
	if err != nil {
		log.Println(err)
	}
	return conn
}

func setUpSyncServer(t *testing.T) *httptest.Server {
	client := getDBClient(t)
	mux := sync.NewServer(client)
	log.Println("Sync server running...")
	return httptest.NewServer(mux)
}
<commit_msg>integration tests return testUsers and testApplications instead of just tokens<commit_after>package integration

import (
	"log"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"
	"time"

	"github.com/EaseApp/web-backend/src/sync"
	"github.com/gorilla/websocket"
	"github.com/stretchr/testify/assert"
)

func TestSocketConnection(t *testing.T) {
	syncServer := setUpSyncServer(t)
	webServer := setUpServer(t)
	testUser := createTestUser(webServer.URL, t)
	testApplication := createTestApp(webServer.URL, testUser.APIToken, "test", t)

	testcases := []struct {
		subscribeTo                   string
		firstSocketMessage            string
		firstSocketResponse           string
		publishTo                     string
		publishData                   string
		expectedData                  string
		expectedApplicationStatusCode int
	}{
		{
			// Subscribe to an application, get the relavent data
			subscribeTo:                   testUser.ID + "_" + "test",
			firstSocketMessage:            `{"username": "` + testUser.ID + `", "application": "test", "authorization": "` + testApplication.AppToken + `"}`,
			firstSocketResponse:           `{"status": "success"}`,
			publishTo:                     "test",
			publishData:                   `{"data": "test"}`,
			expectedData:                  `{"data": "test"}`,
			expectedApplicationStatusCode: http.StatusOK,
		},
		{
			// Subscribe to one application, shouldn't get data with bad Publish call.
			subscribeTo:                   "ronswanson_test",
			firstSocketMessage:            `{"username": "ronswanson", "application": "test", "authorization": "123"}`,
			firstSocketResponse:           `{"status": "failed"}`,
			publishTo:                     "user_differentApp",
			publishData:                   `{"data":"test"}`,
			expectedData:                  "",
			expectedApplicationStatusCode: http.StatusUnauthorized,
		},
	}

	for _, testcase := range testcases {
		port := strings.Split(syncServer.URL, ":")[2]
		conn := openConnection("ws://localhost:" + port + "/sub") // Connect to sync annonymously
		defer conn.Close()

		sendSocketData(conn, testcase.firstSocketMessage)
		assert.Equal(t, testcase.firstSocketResponse, grabSocketData(conn), "Socket response failed")

		path := "/pub/ronswanson/" + testcase.publishTo
		// log.Println(syncServer.URL, path)
		resp := sendJSON(testcase.publishData, testApplication.AppToken, syncServer.URL, path, "POST", t) // Publish to an app
		assert.Equal(t, testcase.expectedApplicationStatusCode, resp.StatusCode)
		actual := grabSocketData(conn)
		assert.Equal(t, testcase.expectedData, actual)

	}
	defer syncServer.Close()
}

func grabSocketData(conn *websocket.Conn) string {
	conn.SetReadDeadline(time.Now().Add(1 * time.Second))
	_, p, err := conn.ReadMessage() // This methods blocks. Make sure to set Deadline
	if err != nil {
		log.Println(err)
	}
	return string(p)

}

func sendSocketData(conn *websocket.Conn, data string) error {
	return conn.WriteMessage(1, []byte(data))
}

func openConnection(url string) *websocket.Conn {
	// log.Println("URL: ", url)
	var DefaultDialer = &websocket.Dialer{
		Proxy: http.ProxyFromEnvironment,
	}

	header := make(http.Header)
	conn, _, err := DefaultDialer.Dial(url, header)
	if err != nil {
		log.Println(err)
	}
	return conn
}

func setUpSyncServer(t *testing.T) *httptest.Server {
	client := getDBClient(t)
	mux := sync.NewServer(client)
	log.Println("Sync server running...")
	return httptest.NewServer(mux)
}
<|endoftext|>


<commit_before>package interpreter

import (
    "fmt"
    "jvmgo/jvm/rtda"
    "jvmgo/jvm/instructions"
)

// todo
func Loop(thread *rtda.Thread) {
    defer _debug(thread) // todo

    decoder := instructions.NewInstructionDecoder()
    for {
        frame := thread.CurrentFrame()

        // decode
        code := frame.Method().Code()
        pc := thread.PC()
        _, inst, nextPC := decoder.Decode(code, pc)
        frame.SetNextPC(nextPC)

        // execute
        //_logInstruction(frame, thread.PC(), opcode, inst)
        inst.Execute(frame)
        if !thread.IsStackEmpty() {
            topFrame := thread.TopFrame()
            thread.SetPC(topFrame.NextPC())
        } else {
            break;
        }
    }

    // terminate thread
    threadObj := thread.JThread()
    threadObj.Monitor().NotifyAll()
}

// todo
func _debug(thread *rtda.Thread) {
    if r := recover(); r != nil {
        for !thread.IsStackEmpty() {
            frame := thread.PopFrame()
            fmt.Printf("%v %v\n", frame.Method().Class(), frame.Method())
        }

        err, ok := r.(error)
        if !ok {
            err = fmt.Errorf("%v", r)
            panic(err.Error())
        } else {
            panic(err.Error())
        }
    }
}

func _logInstruction(frame *rtda.Frame, pc int, opcode uint8, inst instructions.Instruction) {
    method := frame.Method()
    methodName := method.Name()
    className := method.Class().Name()
    if method.IsStatic() {
        fmt.Printf("exec: %v.%v() #%v 0x%x %v\n", className, methodName, pc, opcode, inst)
    } else {
        fmt.Printf("exec: %v#%v() #%v 0x%x %v\n", className, methodName, pc, opcode, inst)
    }
}
<commit_msg>code refactor<commit_after>package interpreter

import (
    "fmt"
    "jvmgo/jvm/rtda"
    "jvmgo/jvm/instructions"
)

// todo
func Loop(thread *rtda.Thread) {
    defer _debug(thread) // todo

    decoder := instructions.NewInstructionDecoder()
    for {
        frame := thread.CurrentFrame()

        // decode
        code := frame.Method().Code()
        pc := thread.PC()
        _, inst, nextPC := decoder.Decode(code, pc)
        frame.SetNextPC(nextPC)

        // execute
        //_logInstruction(frame, opcode, inst)
        inst.Execute(frame)
        if !thread.IsStackEmpty() {
            topFrame := thread.TopFrame()
            thread.SetPC(topFrame.NextPC())
        } else {
            break;
        }
    }

    // terminate thread
    threadObj := thread.JThread()
    threadObj.Monitor().NotifyAll()
}

// todo
func _debug(thread *rtda.Thread) {
    if r := recover(); r != nil {
        for !thread.IsStackEmpty() {
            frame := thread.PopFrame()
            fmt.Printf("%v %v\n", frame.Method().Class(), frame.Method())
        }

        err, ok := r.(error)
        if !ok {
            err = fmt.Errorf("%v", r)
            panic(err.Error())
        } else {
            panic(err.Error())
        }
    }
}

func _logInstruction(frame *rtda.Frame, opcode uint8, inst instructions.Instruction) {
    thread := frame.Thread()
    method := frame.Method()
    methodName := method.Name()
    className := method.Class().Name()
    pc := thread.PC()
    if method.IsStatic() {
        fmt.Printf("exec: %v.%v() #%v 0x%x %v\n", className, methodName, pc, opcode, inst)
    } else {
        fmt.Printf("exec: %v#%v() #%v 0x%x %v\n", className, methodName, pc, opcode, inst)
    }
}
<|endoftext|>


<commit_before>package anaconda

import (
	"net/url"
)

type Cursor struct {
	Previous_cursor     int64
	Previous_cursor_str string

	Ids []int64

	Next_cursor     int64
	Next_cursor_str string
}

type Friendship struct {
	Name        string
	Id_str      string
	Id          int64
	Connections []string
	Screen_name string
}

//GetFriendshipsNoRetweets returns a collection of user_ids that the currently authenticated user does not want to receive retweets from.
//It does not currently support the stringify_ids parameter
func (a TwitterApi) GetFriendshipsNoRetweets() (ids []int64, err error) {
	err = a.apiGet("https://api.twitter.com/1.1/friendships/no_retweets/ids.json", nil, &ids)
	return
}

func (a TwitterApi) GetFriendsIds(v url.Values) (c Cursor, err error) {
	err = a.apiGet("https://api.twitter.com/1.1/friends/ids.json", v, &c)
	return
}

func (a TwitterApi) GetFriendshipsLookup(v url.Values) (friendships []Friendship, err error) {
	err = a.apiGet("http://api.twitter.com/1.1/friendships/lookup.json", v, &friendships)
	return
}

func (a TwitterApi) GetFriendshipsIncoming(v url.Values) (c Cursor, err error) {
	err = a.apiGet("https://api.twitter.com/1.1/friendships/incoming.json", v, &c)
	return
}

func (a TwitterApi) GetFriendshipsOutgoing(v url.Values) (c Cursor, err error) {
	err = a.apiGet("http://api.twitter.com/1.1/friendships/outgoing.json", v, &c)
	return
}
<commit_msg>Implement GetFollowersList, which returns a list of followers (cursor)<commit_after>package anaconda

import (
	"net/url"
)

type Cursor struct {
	Previous_cursor     int64
	Previous_cursor_str string

	Ids []int64

	Next_cursor     int64
	Next_cursor_str string
}

type TwitterUserCursor struct {
    Previous_cursor int64
    Previous_cursor_str string
    Next_cursor int64
    Next_cursor_str string
    Users []TwitterUser
}

type Friendship struct {
	Name        string
	Id_str      string
	Id          int64
	Connections []string
	Screen_name string
}

//GetFriendshipsNoRetweets returns a collection of user_ids that the currently authenticated user does not want to receive retweets from.
//It does not currently support the stringify_ids parameter
func (a TwitterApi) GetFriendshipsNoRetweets() (ids []int64, err error) {
	err = a.apiGet("https://api.twitter.com/1.1/friendships/no_retweets/ids.json", nil, &ids)
	return
}

func (a TwitterApi) GetFriendsIds(v url.Values) (c Cursor, err error) {
	err = a.apiGet("https://api.twitter.com/1.1/friends/ids.json", v, &c)
	return
}

func (a TwitterApi) GetFriendshipsLookup(v url.Values) (friendships []Friendship, err error) {
	err = a.apiGet("http://api.twitter.com/1.1/friendships/lookup.json", v, &friendships)
	return
}

func (a TwitterApi) GetFriendshipsIncoming(v url.Values) (c Cursor, err error) {
	err = a.apiGet("https://api.twitter.com/1.1/friendships/incoming.json", v, &c)
	return
}

func (a TwitterApi) GetFriendshipsOutgoing(v url.Values) (c Cursor, err error) {
	err = a.apiGet("http://api.twitter.com/1.1/friendships/outgoing.json", v, &c)
	return
}

func (a TwitterApi) GetFollowersList(v url.Values) (c TwitterUserCursor, err error) {
    err = a.apiGet("https://api.twitter.com/1.1/followers/list.json", v, &c)
	return
}
<|endoftext|>


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

package glusterfs

import (
	"encoding/json"
	"errors"
	"github.com/boltdb/bolt"
	"github.com/gorilla/mux"
	"github.com/heketi/heketi/utils"
	"net/http"
)

var (
	ErrNotFound = errors.New("Id not found")
)

func (a *App) ClusterCreate(w http.ResponseWriter, r *http.Request) {

	// Create a new ClusterInfo
	entry := NewClusterEntry()
	entry.Info.Id = utils.GenUUID()

	// Convert entry to bytes
	buffer, err := entry.Marshal()
	if err != nil {
		http.Error(w, "Unable to create cluster", http.StatusInternalServerError)
		return
	}

	// Add cluster to db
	err = a.db.Update(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(BOLTDB_BUCKET_CLUSTER))
		if b == nil {
			logger.Error("Unable to save new cluster information in db")
			return errors.New("Unable to open bucket")
		}

		err = b.Put([]byte(entry.Info.Id), buffer)
		if err != nil {
			logger.Error("Unable to save new cluster information in db")
			return err
		}

		return nil

	})

	if err != nil {
		logger.Err(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Send back we created it (as long as we did not fail)
	w.Header().Set("Content-Type", "application/json; charset=UTF-8")
	w.WriteHeader(http.StatusCreated)
	if err := json.NewEncoder(w).Encode(entry.Info); err != nil {
		panic(err)
	}
}

func (a *App) ClusterList(w http.ResponseWriter, r *http.Request) {

	var list ClusterListResponse
	list.Clusters = make([]string, 0)

	// Get all the cluster ids from the DB
	err := a.db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(BOLTDB_BUCKET_CLUSTER))
		if b == nil {
			logger.Error("Unable to access db")
			return errors.New("Unable to open bucket")
		}

		b.ForEach(func(k, v []byte) error {
			list.Clusters = append(list.Clusters, string(k))
			return nil
		})

		return nil
	})

	if err != nil {
		logger.Err(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Send list back
	w.Header().Set("Content-Type", "application/json; charset=UTF-8")
	w.WriteHeader(http.StatusOK)
	if err := json.NewEncoder(w).Encode(list); err != nil {
		panic(err)
	}
}

func (a *App) ClusterInfo(w http.ResponseWriter, r *http.Request) {

	// Get the id from the URL
	vars := mux.Vars(r)
	id := vars["id"]

	// Get info from db
	var entry ClusterEntry
	err := a.db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(BOLTDB_BUCKET_CLUSTER))
		if b == nil {
			logger.Error("Unable to access db")
			return errors.New("Unable to open bucket")
		}

		val := b.Get([]byte(id))
		if val == nil {
			return ErrNotFound
		}

		return entry.Unmarshal(val)
	})
	if err == ErrNotFound {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	} else if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	// Write msg
	w.Header().Set("Content-Type", "application/json; charset=UTF-8")
	w.WriteHeader(http.StatusOK)
	if err := json.NewEncoder(w).Encode(entry.Info); err != nil {
		panic(err)
	}

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

package glusterfs

import (
	"encoding/json"
	"errors"
	"github.com/boltdb/bolt"
	"github.com/gorilla/mux"
	"github.com/heketi/heketi/utils"
	"net/http"
)

var (
	ErrNotFound = errors.New("Id not found")
)

func (a *App) ClusterCreate(w http.ResponseWriter, r *http.Request) {

	// Create a new ClusterInfo
	entry := NewClusterEntry()
	entry.Info.Id = utils.GenUUID()

	// Convert entry to bytes
	buffer, err := entry.Marshal()
	if err != nil {
		http.Error(w, "Unable to create cluster", http.StatusInternalServerError)
		return
	}

	// Add cluster to db
	err = a.db.Update(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(BOLTDB_BUCKET_CLUSTER))
		if b == nil {
			logger.Error("Unable to save new cluster information in db")
			return errors.New("Unable to open bucket")
		}

		err = b.Put([]byte(entry.Info.Id), buffer)
		if err != nil {
			logger.Error("Unable to save new cluster information in db")
			return err
		}

		return nil

	})

	if err != nil {
		logger.Err(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Send back we created it (as long as we did not fail)
	w.Header().Set("Content-Type", "application/json; charset=UTF-8")
	w.WriteHeader(http.StatusCreated)
	if err := json.NewEncoder(w).Encode(entry.Info); err != nil {
		panic(err)
	}
}

func (a *App) ClusterList(w http.ResponseWriter, r *http.Request) {

	var list ClusterListResponse
	list.Clusters = make([]string, 0)

	// Get all the cluster ids from the DB
	err := a.db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(BOLTDB_BUCKET_CLUSTER))
		if b == nil {
			logger.Error("Unable to access db")
			return errors.New("Unable to open bucket")
		}

		b.ForEach(func(k, v []byte) error {
			list.Clusters = append(list.Clusters, string(k))
			return nil
		})

		return nil
	})

	if err != nil {
		logger.Err(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Send list back
	w.Header().Set("Content-Type", "application/json; charset=UTF-8")
	w.WriteHeader(http.StatusOK)
	if err := json.NewEncoder(w).Encode(list); err != nil {
		panic(err)
	}
}

func (a *App) ClusterInfo(w http.ResponseWriter, r *http.Request) {

	// Get the id from the URL
	vars := mux.Vars(r)
	id := vars["id"]

	// Get info from db
	var entry ClusterEntry
	err := a.db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(BOLTDB_BUCKET_CLUSTER))
		if b == nil {
			logger.Error("Unable to access db")
			return errors.New("Unable to open bucket")
		}

		val := b.Get([]byte(id))
		if val == nil {
			return ErrNotFound
		}

		return entry.Unmarshal(val)
	})
	if err == ErrNotFound {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	} else if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Write msg
	w.Header().Set("Content-Type", "application/json; charset=UTF-8")
	w.WriteHeader(http.StatusOK)
	if err := json.NewEncoder(w).Encode(entry.Info); err != nil {
		panic(err)
	}

}

func (a *App) ClusterDelete(w http.ResponseWriter, r *http.Request) {

	// Get the id from the URL
	vars := mux.Vars(r)
	id := vars["id"]

	// Get info from db
	var entry ClusterEntry
	err := a.db.Update(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(BOLTDB_BUCKET_CLUSTER))
		if b == nil {
			logger.Error("Unable to access db")
			return errors.New("Unable to access db")
		}

		// Get data from database
		val := b.Get([]byte(id))
		if val == nil {
			http.Error(w, err.Error(), http.StatusNotFound)
			return ErrNotFound
		}

		// Convert from bytes to a struct
		err = entry.Unmarshal(val)
		if err != nil {
			logger.Error("Unable to read from database: %v", err.Error())
			http.Error(w, "Unable to unmarshal from database", http.StatusInternalServerError)
			return err
		}

		// Check if the cluster has elements
		if len(entry.Info.Nodes) > 0 || len(entry.Info.Volumes) > 0 {
			logger.Warning("Unable to delete cluster [%v] because it contains volumes and/or nodes", id)
			http.Error(w, "Cluster contains nodes and/or volumes", http.StatusConflict)
			return errors.New("Cluster Conflict")
		}

		// Delete key
		err = b.Delete([]byte(id))
		if err != nil {
			logger.Error("Unable to delete container key [%v] in db: %v", id, err.Error())
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return err
		}

		// Show that the key has been deleted
		logger.Info("Deleted container [%d]", id)
		return nil
	})
	if err != nil {
		return
	}

	// Write msg
	w.WriteHeader(http.StatusOK)
}
<|endoftext|>


<commit_before>package gitiles

import (
	"fmt"
	"strings"

	"go.chromium.org/luci/common/errors"
)

// Validate returns an error if r is invalid.
func (r *LogRequest) Validate() error {
	switch {
	case r.Project == "":
		return errors.New("project is required")
	case r.PageSize < 0:
		return errors.New("page size must not be negative")
	case r.Treeish == "":
		return errors.New("treeish is required")
	default:
		return nil
	}
}

// Validate returns an error if r is invalid.
func (r *RefsRequest) Validate() error {
	switch {
	case r.Project == "":
		return errors.New("project is required")
	case r.RefsPath != "refs" && !strings.HasPrefix(r.RefsPath, "refs/"):
		return fmt.Errorf(`refsPath must be "refs" or start with "refs/": %q`, r.RefsPath)
	default:
		return nil
	}
}
<commit_msg>[gitiles] do not allow .. in Treeish<commit_after>package gitiles

import (
	"fmt"
	"strings"

	"go.chromium.org/luci/common/errors"
)

// Validate returns an error if r is invalid.
func (r *LogRequest) Validate() error {
	switch {
	case r.Project == "":
		return errors.New("project is required")
	case r.PageSize < 0:
		return errors.New("page size must not be negative")
	case r.Treeish == "":
		return errors.New("treeish is required")
	case strings.Contains(r.Treeish, ".."):
		return errors.New("treeish cannot contain \"..\"; use Ancestor instead")
	default:
		return nil
	}
}

// Validate returns an error if r is invalid.
func (r *RefsRequest) Validate() error {
	switch {
	case r.Project == "":
		return errors.New("project is required")
	case r.RefsPath != "refs" && !strings.HasPrefix(r.RefsPath, "refs/"):
		return fmt.Errorf(`refsPath must be "refs" or start with "refs/": %q`, r.RefsPath)
	default:
		return nil
	}
}
<|endoftext|>


<commit_before>// Attributions
// some of the details below have been reproduced here from;
// Effective Go [http://golang.org/doc/effective_go.html]
// The Go Programming Language Specification [http://golang.org/ref/spec]
package main

import "fmt"

func main() {
	// In Go there are two distinct categories of types:
	//------------------------

	// 1. Value type variables point directly to their value contained in memory.
	// All types explored in previous sections except "pointer", "slice", "map",
	// and "channel" are value types.

	// 2. Reference types variable "pointer, slice, map, and channel", contains the
	// address of the memory location where the value is stored.

	// Merory allocation in Go
	//------------------------
	// Go has two allocation primitives, the built-in functions new and make.
	// They do different things and apply to different types, which can be
	// confusing, but the rules are simple.

	// allocation with new
	//------------------------
	// Let's talk about new first. It's a built-in function that allocates memory,
	//  but unlike its namesakes in some other languages it does not initialize
	// the memory, it only zeros it. That is, new(T) allocates zeroed storage for
	// a new item of type T and returns its address, a value of type *T.
	// In Go terminology, it returns a pointer to a newly allocated zero value of type T.

	// Since the memory returned by new is zeroed, it's helpful to arrange when
	// designing your data structures that the zero value of each type can be used without further initialization.

	// Memory allocated as a result of declaring a variable of value type is zeroed. This is
	// know as the zero value of the type. This behavior is illustated in the following
	// code fragment

	var (
		a uint8
		b int
		c float64
		d bool
		e string
		f complex128
		g [4]bool
	)

	type car struct {
		make  string
		model string
		year  int16
	}

	h := car{}

	fmt.Printf("a = %d (%T)\n", a, a)
	fmt.Printf("b = %d (%T)\n", b, b)
	fmt.Printf("c = %f (%T)\n", c, c)
	fmt.Printf("d = %t (%T)\n", d, d)
	fmt.Printf("e = %#v (%T)\n", e, e)
	fmt.Printf("f = %f (%T)\n", f, f)
	fmt.Printf("g = %#v (%T)\n", g, g)
	fmt.Printf("h = %#v (%T)\n", h, h)

	// allocation with make
	//------------------------
	// The built-in function make(T, args) serves a purpose different from new(T).
	// It creates slices, maps, and channels only, and it returns an initialized (not zeroed)
	// value of type T (not *T). The reason for the distinction is that these three types
	// represent, under the covers, references to data structures that must be initialized
	// before use. A slice, for example, is a three-item descriptor containing a pointer to
	// the data (inside an array), the length, and the capacity, and until those items are
	// initialized, the slice is nil. For slices, maps, and channels, make initializes the
	// internal data structure and prepares the value for use.

	var i []int64
	if i == nil {
		fmt.Println("i is nil")
	}
	fmt.Printf("i = %#v (%T)\n", i, i)

	j := make([]int64, 5)
	if j == nil {
		fmt.Println("j is nil")
	}
	fmt.Printf("j = %#v (%T)\n", j, j)

	var k map[string]int64
	if k == nil {
		fmt.Println("k is nil")
	}
	fmt.Printf("k = %#v (%T)\n", k, k)

	l := make(map[string]int64, 5)
	fmt.Printf("l = %#v (%T)\n", l, l)

	var m chan string
	if m == nil {
		fmt.Println("m is nil")
	}
	fmt.Printf("m = %#v (%T)\n", m, m)

	n := make(chan string)
	fmt.Printf("n = %#v (%T)\n", n, n)
}
<commit_msg>add commnetray<commit_after>// Attributions
// some of the details below have been reproduced here from;
// Effective Go [http://golang.org/doc/effective_go.html]
// The Go Programming Language Specification [http://golang.org/ref/spec]
package main

import "fmt"

func main() {
	// In Go there are two distinct categories of types:
	//------------------------

	// 1. Value type variables point directly to their value contained in memory.
	// All types explored in previous sections except "pointer", "slice", "map",
	// and "channel" are value types.

	// 2. Reference types variable "pointer, slice, map, and channel", contains the
	// address of the memory location where the value is stored.

	// Merory allocation in Go
	//------------------------
	// Go has two allocation primitives, the built-in functions new and make.
	// They do different things and apply to different types, which can be
	// confusing, but the rules are simple.

	// allocation with new
	//------------------------
	// Let's talk about new first. It's a built-in function that allocates memory,
	// but unlike its namesakes in some other languages it does not initialize
	// the memory, it only zeros it. That is, new(T) allocates zeroed storage for
	// a new item of type T and returns its address, a value of type *T.
	// In Go terminology, it returns a pointer to a newly allocated zero value of type T.

	// Since the memory returned by new is zeroed, it's helpful to arrange when
	// designing your data structures that the zero value of each type can be used without further initialization.

	// Memory allocated as a result of declaring a variable of value type is zeroed. This is
	// know as the zero value of the type. This behavior is illustated in the following
	// code fragment

	var (
		a uint8
		b int
		c float64
		d bool
		e string
		f complex128
		g [4]bool
	)

	type car struct {
		make  string
		model string
		year  int16
	}

	h := car{}

	fmt.Printf("a = %d (%T)\n", a, a)
	fmt.Printf("b = %d (%T)\n", b, b)
	fmt.Printf("c = %f (%T)\n", c, c)
	fmt.Printf("d = %t (%T)\n", d, d)
	fmt.Printf("e = %#v (%T)\n", e, e)
	fmt.Printf("f = %f (%T)\n", f, f)
	fmt.Printf("g = %#v (%T)\n", g, g)
	fmt.Printf("h = %#v (%T)\n", h, h)

	// allocation with make
	//------------------------
	// The built-in function make(T, args) serves a purpose different from new(T).
	// It creates slices, maps, and channels only, and it returns an initialized (not zeroed)
	// value of type T (not *T). The reason for the distinction is that these three types
	// represent, under the covers, references to data structures that must be initialized
	// before use. A slice, for example, is a three-item descriptor containing a pointer to
	// the data (inside an array), the length, and the capacity, and until those items are
	// initialized, the slice is nil. For slices, maps, and channels, make initializes the
	// internal data structure and prepares the value for use.

	var i []int64
	if i == nil {
		fmt.Println("i is nil")
	}
	fmt.Printf("i = %#v (%T)\n", i, i)

	j := make([]int64, 5)
	if j == nil {
		fmt.Println("j is nil")
	}
	fmt.Printf("j = %#v (%T)\n", j, j)

	var k map[string]int64
	if k == nil {
		fmt.Println("k is nil")
	}
	fmt.Printf("k = %#v (%T)\n", k, k)

	l := make(map[string]int64, 5)
	fmt.Printf("l = %#v (%T)\n", l, l)

	var m chan string
	if m == nil {
		fmt.Println("m is nil")
	}
	fmt.Printf("m = %#v (%T)\n", m, m)

	n := make(chan string)
	fmt.Printf("n = %#v (%T)\n", n, n)
}
<|endoftext|>


<commit_before>package gaerecords

import (
	"os"
	"fmt"
	"appengine/datastore"
)

// The ID value of a record that indicates there is no ID.  A record
// will have no ID if it has not yet been saved, or if it has been deleted.
var NoIDValue int64 = 0

// Represents a single record of data (like a single row in a database, or a single resource
// on a web server).  Synonymous with an Entity in appengine/datastore.
type Record struct {
	fields map[string]interface{}

	model *Model

	datastoreKey *datastore.Key

	recordID int64
}

/*
	Constuctors
	----------------------------------------------------------------------
*/

// Creates a new record of the given Model type.  Not recommended.  Instead call the
// New() method on the model object itself.
func NewRecord(model *Model) *Record {

	record := new(Record)
	record.model = model
	return record

}

/*
	Properties
	----------------------------------------------------------------------
*/

// Gets the current Model object describing this type of record.
func (r *Record) Model() *Model {
	return r.model
}

/*
	IDs
	----------------------------------------------------------------------
*/

// Gets the unique ID for this record.  A record will be assigned a unique ID
// only when it is persisted in the datastore.  Otherwise, the ID will be equal to NoIDValue.
// Use IsPersisted() to check if a record has been persisted in the datastore or not.
func (r *Record) ID() int64 {
	return r.recordID
}

// Sets the ID for this record.  Used internally.
func (r *Record) setID(id int64) *Record {

	// set the record ID
	r.recordID = id

	r.invalidateDatastoreKey()

	// chain
	return r
}

/*
	Persistence
	----------------------------------------------------------------------
*/

// CAUTION: This method does NOT load persisted records.  See Find().
// PropertyLoadSaver.Load: Takes a channel of datastore.Property objects and
// applies them to the internal Fields() object.
// Used internally by the datastore.
func (r *Record) Load(c <-chan datastore.Property) os.Error {

	// load the fields
	for f := range c {
		r.Fields()[f.Name] = f.Value
	}

	// no errors
	return nil
}

// CAUTION: This method does NOT persist records.  See Put().
// PropertyLoadSaver.Save: Writes datastore.Property objects and
// representing the Fields() of this record to the specified channel.
// Used internally by the datastore to persist the values.
func (r *Record) Save(c chan<- datastore.Property) os.Error {

	for k, v := range r.Fields() {
		c <- datastore.Property{
			Name:  k,
			Value: v,
		}
	}

	// this channel is finished
	close(c)

	// no errors
	return nil
}

// Saves or updates this record.  Returns nil if successful, otherwise returns the os.Error
// that was retrned by appengime/datastore.
//  record.Put()
func (r *Record) Put() os.Error {
	return putOne(r)
}

// Deletes this record.  Returns nil if successful, otherwise returns the os.Error
// that was retrned by appengime/datastore.
//   record.Delete()
func (r *Record) Delete() os.Error {
	return deleteOne(r)
}

/*
	Datastore Key
	----------------------------------------------------------------------
*/

// Gets the appengine/datastore Key for this record.  If this record is persisted in the
// datastore it wil be a complete key, otherwise, this method will return an incomplete key.
func (r *Record) DatastoreKey() *datastore.Key {

	if r.datastoreKey == nil {

		var key *datastore.Key

		if r.IsPersisted() {
			key = r.model.NewKeyWithID(r.ID())
		} else {
			key = r.model.NewKey()
		}

		r.datastoreKey = key

	}

	return r.datastoreKey

}

// Sets the datastore Key and updates the records ID if needed
func (r *Record) SetDatastoreKey(key *datastore.Key) *Record {

	// does the key have an ID?
	if key.IntID() > 0 {

		// set the ID
		r.setID(key.IntID())

	}

	// set the key
	r.datastoreKey = key

	// chain
	return r

}

// Invalidates the internally cached datastore key for this
// record so that when it is next requested via DatastoreKey() it will
// be regenerated to match the corrected state
func (r *Record) invalidateDatastoreKey() {
	r.datastoreKey = nil
}

// Whether this record has been persisted in the
// datastore or not, i.e. record.ID != NoIDValue
func (r *Record) IsPersisted() bool {
	return r.recordID != NoIDValue
}

/*
	Fields
	----------------------------------------------------------------------
*/

// Gets the internal storage map (map[string]interface{}) that contains the
// persistable fields for this record.  Instead of manipulating this object directly,
// you should use the Get*() and Set*() methods.
func (r *Record) Fields() map[string]interface{} {

	// ensure we have a map to store the fields
	if r.fields == nil {
		r.fields = make(map[string]interface{})
	}

	return r.fields

}

// Gets the value of a field in a record.  Strongly typed alternatives are provided and recommended
// to use where possible.
func (r *Record) Get(key string) interface{} {
	return r.Fields()[key]
}

// Sets a field in the record.  The value must be an acceptable datastore
// type or another Record.  Strongly typed alternatives are provided and recommended
// to use where possible.
func (r *Record) Set(key string, value interface{}) *Record {
	r.Fields()[key] = value
	return r
}

// Gets a string field
func (r *Record) GetString(key string) string {
	return fmt.Sprint(r.Get(key))
}

// Sets the string value of a field
func (r *Record) SetString(key string, value string) *Record {
	return r.Set(key, value)
}

// Gets the int64 value of a field with the specified key.
func (r *Record) GetInt64(key string) int64 {
	return r.Get(key).(int64)
}

// Sets the int64 value of a field with the specified key.
func (r *Record) SetInt64(key string, value int64) *Record {
	return r.Set(key, value)
}

// Gets the bool value of a field with the specified key.
func (r *Record) GetBool(key string) bool {
	return r.Get(key).(bool)
}

// Sets the bool value of a field with the specified key.
func (r *Record) SetBool(key string, value bool) *Record {
	return r.Set(key, value)
}

// Gets the *datastore.Key value of a field with the specified key.
func (r *Record) GetKeyField(key string) *datastore.Key {
	return r.Get(key).(*datastore.Key)
}

// Sets the *datastore.Key value of a field with the specified key.
func (r *Record) SetKeyField(key string, value *datastore.Key) *Record {
	return r.Set(key, value)
}
<commit_msg>added descriptions of Record fields<commit_after>package gaerecords

import (
	"os"
	"fmt"
	"appengine/datastore"
)

// The ID value of a record that indicates there is no ID.  A record
// will have no ID if it has not yet been saved, or if it has been deleted.
var NoIDValue int64 = 0

// Represents a single record of data (like a single row in a database, or a single resource
// on a web server).  Synonymous with an Entity in appengine/datastore.
type Record struct {

	// internal storage of record field data.
	fields map[string]interface{}

	// a reference to the model describing the
	// type of this record.
	model *Model

	// an internal cache of the datastore.Key
	datastoreKey *datastore.Key

	// internal storage of this record's ID
	recordID int64
}

/*
	Constuctors
	----------------------------------------------------------------------
*/

// Creates a new record of the given Model type.  Not recommended.  Instead call the
// New() method on the model object itself.
func NewRecord(model *Model) *Record {

	record := new(Record)
	record.model = model
	return record

}

/*
	Properties
	----------------------------------------------------------------------
*/

// Gets the current Model object describing this type of record.
func (r *Record) Model() *Model {
	return r.model
}

/*
	IDs
	----------------------------------------------------------------------
*/

// Gets the unique ID for this record.  A record will be assigned a unique ID
// only when it is persisted in the datastore.  Otherwise, the ID will be equal to NoIDValue.
// Use IsPersisted() to check if a record has been persisted in the datastore or not.
func (r *Record) ID() int64 {
	return r.recordID
}

// Sets the ID for this record.  Used internally.
func (r *Record) setID(id int64) *Record {

	// set the record ID
	r.recordID = id

	r.invalidateDatastoreKey()

	// chain
	return r
}

/*
	Persistence
	----------------------------------------------------------------------
*/

// CAUTION: This method does NOT load persisted records.  See Find().
// PropertyLoadSaver.Load: Takes a channel of datastore.Property objects and
// applies them to the internal Fields() object.
// Used internally by the datastore.
func (r *Record) Load(c <-chan datastore.Property) os.Error {

	// load the fields
	for f := range c {
		r.Fields()[f.Name] = f.Value
	}

	// no errors
	return nil
}

// CAUTION: This method does NOT persist records.  See Put().
// PropertyLoadSaver.Save: Writes datastore.Property objects and
// representing the Fields() of this record to the specified channel.
// Used internally by the datastore to persist the values.
func (r *Record) Save(c chan<- datastore.Property) os.Error {

	for k, v := range r.Fields() {
		c <- datastore.Property{
			Name:  k,
			Value: v,
		}
	}

	// this channel is finished
	close(c)

	// no errors
	return nil
}

// Saves or updates this record.  Returns nil if successful, otherwise returns the os.Error
// that was retrned by appengime/datastore.
//  record.Put()
func (r *Record) Put() os.Error {
	return putOne(r)
}

// Deletes this record.  Returns nil if successful, otherwise returns the os.Error
// that was retrned by appengime/datastore.
//   record.Delete()
func (r *Record) Delete() os.Error {
	return deleteOne(r)
}

/*
	Datastore Key
	----------------------------------------------------------------------
*/

// Gets the appengine/datastore Key for this record.  If this record is persisted in the
// datastore it wil be a complete key, otherwise, this method will return an incomplete key.
func (r *Record) DatastoreKey() *datastore.Key {

	if r.datastoreKey == nil {

		var key *datastore.Key

		if r.IsPersisted() {
			key = r.model.NewKeyWithID(r.ID())
		} else {
			key = r.model.NewKey()
		}

		r.datastoreKey = key

	}

	return r.datastoreKey

}

// Sets the datastore Key and updates the records ID if needed
func (r *Record) SetDatastoreKey(key *datastore.Key) *Record {

	// does the key have an ID?
	if key.IntID() > 0 {

		// set the ID
		r.setID(key.IntID())

	}

	// set the key
	r.datastoreKey = key

	// chain
	return r

}

// Invalidates the internally cached datastore key for this
// record so that when it is next requested via DatastoreKey() it will
// be regenerated to match the corrected state
func (r *Record) invalidateDatastoreKey() {
	r.datastoreKey = nil
}

// Whether this record has been persisted in the
// datastore or not, i.e. record.ID != NoIDValue
func (r *Record) IsPersisted() bool {
	return r.recordID != NoIDValue
}

/*
	Fields
	----------------------------------------------------------------------
*/

// Gets the internal storage map (map[string]interface{}) that contains the
// persistable fields for this record.  Instead of manipulating this object directly,
// you should use the Get*() and Set*() methods.
func (r *Record) Fields() map[string]interface{} {

	// ensure we have a map to store the fields
	if r.fields == nil {
		r.fields = make(map[string]interface{})
	}

	return r.fields

}

// Gets the value of a field in a record.  Strongly typed alternatives are provided and recommended
// to use where possible.
func (r *Record) Get(key string) interface{} {
	return r.Fields()[key]
}

// Sets a field in the record.  The value must be an acceptable datastore
// type or another Record.  Strongly typed alternatives are provided and recommended
// to use where possible.
func (r *Record) Set(key string, value interface{}) *Record {
	r.Fields()[key] = value
	return r
}

// Gets a string field
func (r *Record) GetString(key string) string {
	return fmt.Sprint(r.Get(key))
}

// Sets the string value of a field
func (r *Record) SetString(key string, value string) *Record {
	return r.Set(key, value)
}

// Gets the int64 value of a field with the specified key.
func (r *Record) GetInt64(key string) int64 {
	return r.Get(key).(int64)
}

// Sets the int64 value of a field with the specified key.
func (r *Record) SetInt64(key string, value int64) *Record {
	return r.Set(key, value)
}

// Gets the bool value of a field with the specified key.
func (r *Record) GetBool(key string) bool {
	return r.Get(key).(bool)
}

// Sets the bool value of a field with the specified key.
func (r *Record) SetBool(key string, value bool) *Record {
	return r.Set(key, value)
}

// Gets the *datastore.Key value of a field with the specified key.
func (r *Record) GetKeyField(key string) *datastore.Key {
	return r.Get(key).(*datastore.Key)
}

// Sets the *datastore.Key value of a field with the specified key.
func (r *Record) SetKeyField(key string, value *datastore.Key) *Record {
	return r.Set(key, value)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"os"
	"strings"
	"text/template"
)

// Property represents an AWS CloudFormation resource property
type Property struct {

	// Documentation - A link to the AWS CloudFormation User Guide that provides information about the property.
	Documentation string `json:"Documentation"`

	// DuplicatesAllowed - If the value of the Type field is List, indicates whether AWS CloudFormation allows duplicate values.
	// If the value is true, AWS CloudFormation ignores duplicate values. If the value is false,
	// AWS CloudFormation returns an error if you submit duplicate values.
	DuplicatesAllowed bool `json:"DuplicatesAllowed"`

	// ItemType - If the value of the Type field is List or Map, indicates the type of list or map if they contain
	// non-primitive types. Otherwise, this field is omitted. For lists or maps that contain primitive
	// types, the PrimitiveItemType property indicates the valid value type.
	//
	// A subproperty name is a valid item type. For example, if the type value is List and the item type
	//  value is PortMapping, you can specify a list of port mapping properties.
	ItemType string `json:"ItemType"`

	// PrimitiveItemType - If the value of the Type field is List or Map, indicates the type of list or map
	// if they contain primitive types. Otherwise, this field is omitted. For lists or maps that contain
	// non-primitive types, the ItemType property indicates the valid value type.
	// The valid primitive types for lists and maps are String, Long, Integer, Double, Boolean, or Timestamp.
	// For example, if the type value is List and the item type value is String, you can specify a list of strings
	// for the property. If the type value is Map and the item type value is Boolean, you can specify a string
	// to Boolean mapping for the property.
	PrimitiveItemType string `json:"PrimitiveItemType"`

	// PrimitiveType - For primitive values, the valid primitive type for the property. A primitive type is a
	// basic data type for resource property values.
	// The valid primitive types are String, Long, Integer, Double, Boolean, Timestamp or Json.
	// If valid values are a non-primitive type, this field is omitted and the Type field indicates the valid value type.
	PrimitiveType string `json:"PrimitiveType"`

	// Required indicates whether the property is required.
	Required bool `json:"Required"`

	// Type - For non-primitive types, valid values for the property. The valid types are a subproperty name,
	// List or Map. If valid values are a primitive type, this field is omitted and the PrimitiveType field
	// indicates the valid value type. A list is a comma-separated list of values. A map is a set of key-value pairs,
	// where the keys are always strings. The value type for lists and maps are indicated by the ItemType
	// or PrimitiveItemType field.
	Type string `json:"Type"`

	// UpdateType - During a stack update, the update behavior when you add, remove, or modify the property.
	// AWS CloudFormation replaces the resource when you change Immutable properties. AWS CloudFormation doesn't
	// replace the resource when you change mutable properties. Conditional updates can be mutable or immutable,
	// depending on, for example, which other properties you updated. For more information, see the relevant
	// resource type documentation.
	UpdateType string `json:"UpdateType"`

	// Types - if a property can be different types, they will be listed here
	PrimitiveTypes     []string `json:"PrimitiveTypes"`
	PrimitiveItemTypes []string `json:"PrimitiveItemTypes"`
	ItemTypes          []string `json:"ItemTypes"`
	Types              []string `json:"Types"`
}

// Schema returns a JSON Schema for the resource (as a string)
func (p Property) Schema(name, parent string) string {

	// Open the schema template and setup a counter function that will
	// available in the template to be used to detect when trailing commas
	// are required in the JSON when looping through maps
	tmpl, err := template.New("schema-property.template").Funcs(template.FuncMap{
		"counter":           counter,
		"convertToJSONType": convertTypeToJSON,
	}).ParseFiles("generate/templates/schema-property.template")

	var buf bytes.Buffer
	parentpaths := strings.Split(parent, ".")

	templateData := struct {
		Name     string
		Parent   string
		Property Property
	}{
		Name:     name,
		Parent:   parentpaths[0],
		Property: p,
	}

	// Execute the template, writing it to the buffer
	err = tmpl.Execute(&buf, templateData)
	if err != nil {
		fmt.Printf("Error: Failed to generate property %s\n%s\n", name, err)
		os.Exit(1)
	}

	return buf.String()

}

// IsPolymorphic checks whether a property can be multiple different types
func (p Property) IsPolymorphic() bool {
	return len(p.PrimitiveTypes) > 0 || len(p.PrimitiveItemTypes) > 0 || len(p.PrimitiveItemTypes) > 0 || len(p.ItemTypes) > 0 || len(p.Types) > 0
}

// IsPrimitive checks whether a property is a primitive type
func (p Property) IsPrimitive() bool {
	return p.PrimitiveType != ""
}

func (p Property) IsNumeric() bool {
	return p.IsPrimitive() &&
		(p.PrimitiveType == "Long" ||
			p.PrimitiveType == "Integer" ||
			p.PrimitiveType == "Double" ||
			p.PrimitiveType == "Boolean")
}

// IsMap checks whether a property should be a map (map[string]...)
func (p Property) IsMap() bool {
	return p.Type == "Map"
}

// IsMapOfPrimitives checks whether a map contains primitive values
func (p Property) IsMapOfPrimitives() bool {
	return p.IsMap() && p.PrimitiveItemType != ""
}

// IsList checks whether a property should be a list ([]...)
func (p Property) IsList() bool {
	return p.Type == "List"
}

// IsListOfPrimitives checks whether a list containers primitive values
func (p Property) IsListOfPrimitives() bool {
	return p.IsList() && p.PrimitiveItemType != ""
}

// IsCustomType checks wither a property is a custom type
func (p Property) IsCustomType() bool {
	return p.PrimitiveType == "" && p.ItemType == "" && p.PrimitiveItemType == ""
}

// GoType returns the correct type for this property
// within a Go struct. For example, []string or map[string]AWSLambdaFunction_VpcConfig
func (p Property) GoType(basename string, name string) string {

	if p.IsPolymorphic() {

		generatePolymorphicProperty(basename+"_"+name, p)
		return basename + "_" + name

	}

	if p.IsMap() {

		if p.IsMapOfPrimitives() {
			return "map[string]" + convertTypeToGo(p.PrimitiveItemType)
		}

		if p.ItemType == "Tag" {
			return "map[string]Tag"
		}

		return "map[string]" + basename + "_" + p.ItemType

	}

	if p.IsList() {

		if p.IsListOfPrimitives() {
			return "[]" + convertTypeToGo(p.PrimitiveItemType)
		}

		if p.ItemType == "Tag" {
			return "[]Tag"
		}

		return "[]" + basename + "_" + p.ItemType

	}

	if p.IsCustomType() {
		return basename + "_" + p.Type
	}

	// Must be a primitive value
	return convertTypeToGo(p.PrimitiveType)

}

// GetJSONPrimitiveType returns the correct primitive property type for a JSON Schema.
// If the property is a list/map, then it will return the type of the items.
func (p Property) GetJSONPrimitiveType() string {

	if p.IsPrimitive() {
		return convertTypeToJSON(p.PrimitiveType)
	}

	if p.IsMap() && p.IsMapOfPrimitives() {
		return convertTypeToJSON(p.PrimitiveItemType)
	}

	if p.IsList() && p.IsListOfPrimitives() {
		return convertTypeToJSON(p.PrimitiveItemType)
	}

	return "unknown"

}

func convertTypeToGo(pt string) string {
	switch pt {
	case "String":
		return "string"
	case "Long":
		return "int64"
	case "Integer":
		return "int"
	case "Double":
		return "float64"
	case "Boolean":
		return "bool"
	case "Timestamp":
		return "string"
	case "Json":
		return "interface{}"
	default:
		return pt
	}
}

func convertTypeToJSON(name string) string {
	switch name {
	case "String":
		return "string"
	case "Long":
		return "number"
	case "Integer":
		return "number"
	case "Double":
		return "number"
	case "Boolean":
		return "boolean"
	case "Timestamp":
		return "string"
	case "Json":
		return "object"
	default:
		return name
	}
}
<commit_msg>Workaround for AWS CloudFormation specification that currently reports a field as Map when it should be Json<commit_after>package main

import (
	"bytes"
	"fmt"
	"os"
	"strings"
	"text/template"
)

// Property represents an AWS CloudFormation resource property
type Property struct {

	// Documentation - A link to the AWS CloudFormation User Guide that provides information about the property.
	Documentation string `json:"Documentation"`

	// DuplicatesAllowed - If the value of the Type field is List, indicates whether AWS CloudFormation allows duplicate values.
	// If the value is true, AWS CloudFormation ignores duplicate values. If the value is false,
	// AWS CloudFormation returns an error if you submit duplicate values.
	DuplicatesAllowed bool `json:"DuplicatesAllowed"`

	// ItemType - If the value of the Type field is List or Map, indicates the type of list or map if they contain
	// non-primitive types. Otherwise, this field is omitted. For lists or maps that contain primitive
	// types, the PrimitiveItemType property indicates the valid value type.
	//
	// A subproperty name is a valid item type. For example, if the type value is List and the item type
	//  value is PortMapping, you can specify a list of port mapping properties.
	ItemType string `json:"ItemType"`

	// PrimitiveItemType - If the value of the Type field is List or Map, indicates the type of list or map
	// if they contain primitive types. Otherwise, this field is omitted. For lists or maps that contain
	// non-primitive types, the ItemType property indicates the valid value type.
	// The valid primitive types for lists and maps are String, Long, Integer, Double, Boolean, or Timestamp.
	// For example, if the type value is List and the item type value is String, you can specify a list of strings
	// for the property. If the type value is Map and the item type value is Boolean, you can specify a string
	// to Boolean mapping for the property.
	PrimitiveItemType string `json:"PrimitiveItemType"`

	// PrimitiveType - For primitive values, the valid primitive type for the property. A primitive type is a
	// basic data type for resource property values.
	// The valid primitive types are String, Long, Integer, Double, Boolean, Timestamp or Json.
	// If valid values are a non-primitive type, this field is omitted and the Type field indicates the valid value type.
	PrimitiveType string `json:"PrimitiveType"`

	// Required indicates whether the property is required.
	Required bool `json:"Required"`

	// Type - For non-primitive types, valid values for the property. The valid types are a subproperty name,
	// List or Map. If valid values are a primitive type, this field is omitted and the PrimitiveType field
	// indicates the valid value type. A list is a comma-separated list of values. A map is a set of key-value pairs,
	// where the keys are always strings. The value type for lists and maps are indicated by the ItemType
	// or PrimitiveItemType field.
	Type string `json:"Type"`

	// UpdateType - During a stack update, the update behavior when you add, remove, or modify the property.
	// AWS CloudFormation replaces the resource when you change Immutable properties. AWS CloudFormation doesn't
	// replace the resource when you change mutable properties. Conditional updates can be mutable or immutable,
	// depending on, for example, which other properties you updated. For more information, see the relevant
	// resource type documentation.
	UpdateType string `json:"UpdateType"`

	// Types - if a property can be different types, they will be listed here
	PrimitiveTypes     []string `json:"PrimitiveTypes"`
	PrimitiveItemTypes []string `json:"PrimitiveItemTypes"`
	ItemTypes          []string `json:"ItemTypes"`
	Types              []string `json:"Types"`
}

// Schema returns a JSON Schema for the resource (as a string)
func (p Property) Schema(name, parent string) string {

	// Open the schema template and setup a counter function that will
	// available in the template to be used to detect when trailing commas
	// are required in the JSON when looping through maps
	tmpl, err := template.New("schema-property.template").Funcs(template.FuncMap{
		"counter":           counter,
		"convertToJSONType": convertTypeToJSON,
	}).ParseFiles("generate/templates/schema-property.template")

	var buf bytes.Buffer
	parentpaths := strings.Split(parent, ".")

	templateData := struct {
		Name     string
		Parent   string
		Property Property
	}{
		Name:     name,
		Parent:   parentpaths[0],
		Property: p,
	}

	// Execute the template, writing it to the buffer
	err = tmpl.Execute(&buf, templateData)
	if err != nil {
		fmt.Printf("Error: Failed to generate property %s\n%s\n", name, err)
		os.Exit(1)
	}

	return buf.String()

}

// IsPolymorphic checks whether a property can be multiple different types
func (p Property) IsPolymorphic() bool {
	return len(p.PrimitiveTypes) > 0 || len(p.PrimitiveItemTypes) > 0 || len(p.PrimitiveItemTypes) > 0 || len(p.ItemTypes) > 0 || len(p.Types) > 0
}

// IsPrimitive checks whether a property is a primitive type
func (p Property) IsPrimitive() bool {
	return p.PrimitiveType != ""
}

func (p Property) IsNumeric() bool {
	return p.IsPrimitive() &&
		(p.PrimitiveType == "Long" ||
			p.PrimitiveType == "Integer" ||
			p.PrimitiveType == "Double" ||
			p.PrimitiveType == "Boolean")
}

// IsMap checks whether a property should be a map (map[string]...)
func (p Property) IsMap() bool {
	return p.Type == "Map"
}

// IsMapOfPrimitives checks whether a map contains primitive values
func (p Property) IsMapOfPrimitives() bool {
	return p.IsMap() && p.PrimitiveItemType != ""
}

// IsList checks whether a property should be a list ([]...)
func (p Property) IsList() bool {
	return p.Type == "List"
}

// IsListOfPrimitives checks whether a list containers primitive values
func (p Property) IsListOfPrimitives() bool {
	return p.IsList() && p.PrimitiveItemType != ""
}

// IsCustomType checks wither a property is a custom type
func (p Property) IsCustomType() bool {
	return p.PrimitiveType == "" && p.ItemType == "" && p.PrimitiveItemType == ""
}

// GoType returns the correct type for this property
// within a Go struct. For example, []string or map[string]AWSLambdaFunction_VpcConfig
func (p Property) GoType(basename string, name string) string {

	if p.IsPolymorphic() {

		generatePolymorphicProperty(basename+"_"+name, p)
		return basename + "_" + name

	}

	if p.IsMap() {

		if p.IsMapOfPrimitives() {
			return "map[string]" + convertTypeToGo(p.PrimitiveItemType)
		}

		if p.ItemType == "Tag" {
			return "map[string]Tag"
		}

		return "map[string]" + basename + "_" + p.ItemType

	}

	if p.IsList() {

		if p.IsListOfPrimitives() {
			return "[]" + convertTypeToGo(p.PrimitiveItemType)
		}

		if p.ItemType == "Tag" {
			return "[]Tag"
		}

		return "[]" + basename + "_" + p.ItemType

	}

	if p.IsCustomType() {
		return basename + "_" + p.Type
	}

	// Must be a primitive value
	return convertTypeToGo(p.PrimitiveType)

}

// GetJSONPrimitiveType returns the correct primitive property type for a JSON Schema.
// If the property is a list/map, then it will return the type of the items.
func (p Property) GetJSONPrimitiveType() string {

	if p.IsPrimitive() {
		return convertTypeToJSON(p.PrimitiveType)
	}

	if p.IsMap() && p.IsMapOfPrimitives() {
		return convertTypeToJSON(p.PrimitiveItemType)
	}

	if p.IsList() && p.IsListOfPrimitives() {
		return convertTypeToJSON(p.PrimitiveItemType)
	}

	return "unknown"

}

func convertTypeToGo(pt string) string {
	switch pt {
	case "String":
		return "string"
	case "Long":
		return "int64"
	case "Integer":
		return "int"
	case "Double":
		return "float64"
	case "Boolean":
		return "bool"
	case "Timestamp":
		return "string"
	case "Json":
		return "interface{}"
	case "Map":
		return "interface{}"
	default:
		return pt
	}
}

func convertTypeToJSON(name string) string {
	switch name {
	case "String":
		return "string"
	case "Long":
		return "number"
	case "Integer":
		return "number"
	case "Double":
		return "number"
	case "Boolean":
		return "boolean"
	case "Timestamp":
		return "string"
	case "Json":
		return "object"
	case "Map":
		return "object"
	default:
		return name
	}
}
<|endoftext|>


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

package generator

func getOmitEmpty(gc *GenContext, sf *StructField) string {
	// TODO(pquerna): non-nil checks, look at isEmptyValue()
	//	return "if mj." + sf.Name + " != nil {" + "\n"
	switch sf.Type {
	case "string":
		return "if len(mj." + sf.Name + ") != 0 {" + "\n"
	case "uint", "uint8", "uint16", "uint32", "uint64", "int", "int8", "int16", "int32", "int64", "float32", "float64":
		return "if mj." + sf.Name + " != 0 {" + "\n"
	case "ptr":
		// TODO(pquerna): pointers. oops.
		return "if mj." + sf.Name + " != nil {" + "\n"
	default:
		// TODO(pquerna): fix types
		return "if true {" + "\n"
	}
}

func getValue(gc *GenContext, sf *StructField) string {
	var out = ""
	// TODO(pquerna): non-nil checks, look at isEmptyValue()
	switch sf.Type {
	case "uint", "uint8", "uint16", "uint32", "uint64":
		out += "buf.Write(strconv.AppendUint([]byte{}, uint64(mj." + sf.Name + "), 10))" + "\n"
	case "int", "int8", "int16", "int32", "int64":
		out += "buf.Write(strconv.AppendInt([]byte{}, int64(mj." + sf.Name + "), 10))" + "\n"
	case "string":
		out += "buf.WriteString(`\"`)" + "\n"
		out += "buf.WriteString(mj." + sf.Name + ")" + "\n"
		out += "buf.WriteString(`\"`)" + "\n"
	default:
		// println(sf.Type)
		out += "obj, err = json.Marshal(mj." + sf.Name + ")" + "\n"
		out += "if err != nil {" + "\n"
		out += "  return nil, err" + "\n"
		out += "}" + "\n"
		out += "buf.Write(obj)" + "\n"
	}
	return out
}

func CreateMarshalJSON(gc *GenContext, si *StructInfo) error {
	var out = ""

	out += `func (mj *` + si.Name + `) MarshalJSON() ([]byte, error) {` + "\n"
	out += `var buf bytes.Buffer` + "\n"
	out += `var err error` + "\n"
	out += `var obj []byte` + "\n"
	out += `var first bool = true` + "\n"
	out += `_ = obj` + "\n"
	out += `_ = err` + "\n"
	out += `_ = first` + "\n"
	out += "buf.WriteString(`{`)" + "\n"

	for _, f := range si.Fields {
		if f.JsonName == "-" {
			continue
		}

		if f.OmitEmpty {
			out += getOmitEmpty(gc, &f)
		}

		out += "if first == true {" + "\n"
		out += "first = false" + "\n"
		out += "buf.WriteString(`\"`)" + "\n"
		out += "} else {" + "\n"
		out += "buf.WriteString(`,\"`)" + "\n"
		out += "}" + "\n"

		out += "buf.WriteString(`" + f.JsonName + "`)" + "\n"
		out += "buf.WriteString(`\":`)" + "\n"
		out += getValue(gc, &f)
		if f.OmitEmpty {
			out += "}" + "\n"
		}
	}

	out += "buf.WriteString(`}`)" + "\n"
	out += "println(string(buf.Bytes()))" + "\n"
	out += `return buf.Bytes(), nil` + "\n"
	out += `}` + "\n"
	gc.AddFunc(out)
	return nil
}
<commit_msg>fix bool<commit_after>/**
 *  Copyright 2014 Paul Querna
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package generator

func getOmitEmpty(gc *GenContext, sf *StructField) string {
	// TODO(pquerna): non-nil checks, look at isEmptyValue()
	//	return "if mj." + sf.Name + " != nil {" + "\n"
	switch sf.Type {
	case "string":
		return "if len(mj." + sf.Name + ") != 0 {" + "\n"
	case "uint", "uint8", "uint16", "uint32", "uint64", "int", "int8", "int16", "int32", "int64", "float32", "float64":
		return "if mj." + sf.Name + " != 0 {" + "\n"
	case "bool":
		return "if mj." + sf.Name + " != false {" + "\n"
	case "ptr":
		// TODO(pquerna): pointers. oops.
		return "if mj." + sf.Name + " != nil {" + "\n"
	default:
		// TODO(pquerna): fix types
		return "if true {" + "\n"
	}
}

func getValue(gc *GenContext, sf *StructField) string {
	var out = ""
	// TODO(pquerna): non-nil checks, look at isEmptyValue()
	switch sf.Type {
	case "uint", "uint8", "uint16", "uint32", "uint64":
		out += "buf.Write(strconv.AppendUint([]byte{}, uint64(mj." + sf.Name + "), 10))" + "\n"
	case "int", "int8", "int16", "int32", "int64":
		out += "buf.Write(strconv.AppendInt([]byte{}, int64(mj." + sf.Name + "), 10))" + "\n"
	case "string":
		out += "buf.WriteString(`\"`)" + "\n"
		out += "buf.WriteString(mj." + sf.Name + ")" + "\n"
		out += "buf.WriteString(`\"`)" + "\n"
	default:
		// println(sf.Type)
		out += "obj, err = json.Marshal(mj." + sf.Name + ")" + "\n"
		out += "if err != nil {" + "\n"
		out += "  return nil, err" + "\n"
		out += "}" + "\n"
		out += "buf.Write(obj)" + "\n"
	}
	return out
}

func CreateMarshalJSON(gc *GenContext, si *StructInfo) error {
	var out = ""

	out += `func (mj *` + si.Name + `) MarshalJSON() ([]byte, error) {` + "\n"
	out += `var buf bytes.Buffer` + "\n"
	out += `var err error` + "\n"
	out += `var obj []byte` + "\n"
	out += `var first bool = true` + "\n"
	out += `_ = obj` + "\n"
	out += `_ = err` + "\n"
	out += `_ = first` + "\n"
	out += "buf.WriteString(`{`)" + "\n"

	for _, f := range si.Fields {
		if f.JsonName == "-" {
			continue
		}

		if f.OmitEmpty {
			out += getOmitEmpty(gc, &f)
		}

		out += "if first == true {" + "\n"
		out += "first = false" + "\n"
		out += "buf.WriteString(`\"`)" + "\n"
		out += "} else {" + "\n"
		out += "buf.WriteString(`,\"`)" + "\n"
		out += "}" + "\n"

		out += "buf.WriteString(`" + f.JsonName + "`)" + "\n"
		out += "buf.WriteString(`\":`)" + "\n"
		out += getValue(gc, &f)
		if f.OmitEmpty {
			out += "}" + "\n"
		}
	}

	out += "buf.WriteString(`}`)" + "\n"
	// out += "println(string(buf.Bytes()))" + "\n"
	out += `return buf.Bytes(), nil` + "\n"
	out += `}` + "\n"
	gc.AddFunc(out)
	return nil
}
<|endoftext|>