<commit_before>// Copyright 2014 Paul Jolly <paul@myitcv.org.uk>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package neovim_test

import (
	"fmt"
	"log"
	"net"
	"os"
	"os/exec"
	"strings"
	"sync"
	"testing"

	"github.com/go-fsnotify/fsnotify"
	"github.com/juju/errgo"
	"github.com/myitcv/neovim"

	. "gopkg.in/check.v1"
	// "github.com/vmihailenco/msgpack"
)

type mpResponse struct {
	t     int
	msgID uint32
	err   interface{}
}

type NeovimTest struct {
	client      *neovim.Client
	nvim        *exec.Cmd
	watcher     *fsnotify.Watcher
	startListen chan chan struct{}
}

func Test(t *testing.T) { TestingT(t) }

var _ = Suite(&NeovimTest{})

// func (t *NeovimTest) SetUpSuite(c *C) {
// 	watcher, err := fsnotify.NewWatcher()
// 	if err != nil {
// 		log.Fatalf("Could not create a new watcher: %v", err)
// 	}
// 	t.watcher = watcher

// 	t.startListen = make(chan chan struct{})

// 	go func() {
// 		var respChan chan struct{}
// 		for {
// 			select {
// 			case respChan = <-t.startListen:
// 				respChan <- struct{}{}
// 			case event := <-t.watcher.Events:
// 				fmt.Println("Got an event")
// 				if respChan == nil {
// 					log.Fatalf("Got unexpected event; not listening but got %v\n", event)
// 				}
// 				if event.Op&fsnotify.Create == fsnotify.Create {
// 					respChan <- struct{}{}
// 					respChan = nil
// 				}
// 			case err := <-t.watcher.Errors:
// 				log.Fatalf("Got an error in the watcher: %v\n", err)
// 			}
// 		}
// 	}()
// }

// func (t *NeovimTest) TearDownSuite(c *C) {
// 	err := t.watcher.Close()
// 	if err != nil {
// 		log.Fatalf("Could not cleanly shut down watcher: %v\n", err)
// 	}
// }

func (t *NeovimTest) SetUpTest(c *C) {
	la := os.Getenv("NEOVIM_LISTEN_ADDRESS")

	// cur_t := time.Now()
	// la := fmt.Sprintf("/tmp/neovim.%v%v", cur_t.Unix(), cur_t.Nanosecond())
	// e_la := "NEOVIM_LISTEN_ADDRESS=" + la

	// now start the process and wait for the socket file to be created
	// t.nvim = exec.Command("nvim", "-u /dev/null")
	// new_env := os.Environ()

	// found := false
	// for i, _ := range new_env {
	// 	if strings.HasPrefix(new_env[i], "NEOVIM_LISTEN_ADDRESS=") {
	// 		found = true
	// 		new_env[i] = e_la
	// 	}
	// }
	// if !found {
	// 	new_env = append(new_env, e_la)
	// }
	// t.nvim.Env = new_env

	// done_chan := make(chan struct{})
	// t.startListen <- done_chan
	// <-done_chan
	// t.watcher.Add(la)
	// err := t.nvim.Start()
	// if err != nil {
	// 	log.Fatalf("Could not start nvim instance: %v\n", err)
	// }
	// <-done_chan
	// t.watcher.Remove(la)

	// fmt.Println("Starting test")

	// now we can create a new client
	client, err := neovim.NewUnixClient("unix", nil, &net.UnixAddr{Name: la})
	if err != nil {
		log.Fatalf("Could not setup client: %v", errgo.Details(err))
	}
	client.PanicOnError = true
	t.client = client
}

// func (t *NeovimTest) TearDownTest(c *C) {
// 	err := t.nvim.Process.Kill()
// 	if err != nil {
// 		log.Fatalf("Could not kill nvim instance: %v\n", err)
// 	}
// }

func (t *NeovimTest) TestClientGetBuffers(c *C) {
	ba, err := t.client.GetBuffers()
	c.Assert(err, IsNil)
	c.Assert(ba, NotNil)
}

func (t *NeovimTest) TestConcurrentClientGetBuffers(c *C) {
	var wg sync.WaitGroup
	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			ba, err := t.client.GetBuffers()
			c.Assert(err, IsNil)
			c.Assert(ba, NotNil)
		}()
	}
	wg.Wait()
}

func (t *NeovimTest) TestClientGetCurrentBuffer(c *C) {
	_, err := t.client.GetCurrentBuffer()
	c.Assert(err, IsNil)
}

func (t *NeovimTest) TestBufferGetLength(c *C) {
	b, err := t.client.GetCurrentBuffer()
	c.Assert(err, IsNil)
	l, err := b.GetLength()
	c.Assert(err, IsNil)
	c.Assert(l, Equals, 1)
}

func (t *NeovimTest) TestBufferSetGetLine(c *C) {
	b, err := t.client.GetCurrentBuffer()
	c.Assert(err, IsNil)
	val := "This is line 1"
	err = b.SetLine(0, val)
	c.Assert(err, IsNil)
	l, err := b.GetLine(0)
	c.Assert(err, IsNil)
	c.Assert(l, Equals, val)
	err = b.DelLine(0)
	c.Assert(err, IsNil)
	length, err := b.GetLength()
	c.Assert(err, IsNil)
	c.Assert(length, Equals, 1)
}

func (t *NeovimTest) TestEval(c *C) {
	res, err := t.client.Eval(`matchadd("Keyword", '\%1l\%1c.\{4\}')`)
	c.Assert(err, IsNil)
	res_i := res.(int64)
	c.Assert(res_i > 0, Equals, true)
}

func (t *NeovimTest) TestClientSubscribe(c *C) {
	respChan := make(chan neovim.SubscriptionEvent)
	errChan := make(chan error)
	topic := "event1"
	val := []interface{}{1, 2, 3}

	vals := make([]string, len(val))
	for i := range val {
		vals[i] = fmt.Sprintf("%v", val[i])
	}

	t.client.SubChan <- neovim.Subscription{
		Topic:  topic,
		Events: respChan,
		Error:  errChan,
	}
	err := <-errChan
	c.Assert(err, IsNil)
	err = t.client.Subscribe(topic)
	c.Assert(err, IsNil)
	command := fmt.Sprintf(`call send_event(0, "%v", [%v])`, topic, strings.Join(vals, ","))
	err = t.client.Command(command)
	c.Assert(err, IsNil)
	resp := <-respChan
	c.Assert(resp, NotNil)
}

func (t *NeovimTest) TestGetSlice(c *C) {
	cb, err := t.client.GetCurrentBuffer()
	c.Assert(err, IsNil)
	lines, err := cb.GetSlice(0, -1, true, true)
	c.Assert(err, IsNil)
	c.Assert(lines, NotNil)
}
<commit_msg>Update tests and add some benchmarks<commit_after>// Copyright 2014 Paul Jolly <paul@myitcv.org.uk>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package neovim_test

import (
	"fmt"
	"log"
	"net"
	"os"
	"os/exec"
	"strings"
	"sync"
	"testing"

	"github.com/go-fsnotify/fsnotify"
	"github.com/juju/errgo"
	"github.com/myitcv/neovim"

	. "gopkg.in/check.v1"
	// "github.com/vmihailenco/msgpack"
)

type mpResponse struct {
	t     int
	msgID uint32
	err   interface{}
}

type NeovimTest struct {
	client      *neovim.Client
	nvim        *exec.Cmd
	watcher     *fsnotify.Watcher
	startListen chan chan struct{}
}

func Test(t *testing.T) { TestingT(t) }

var _ = Suite(&NeovimTest{})

// func (t *NeovimTest) SetUpSuite(c *C) {
// 	watcher, err := fsnotify.NewWatcher()
// 	if err != nil {
// 		log.Fatalf("Could not create a new watcher: %v", err)
// 	}
// 	t.watcher = watcher

// 	t.startListen = make(chan chan struct{})

// 	go func() {
// 		var respChan chan struct{}
// 		for {
// 			select {
// 			case respChan = <-t.startListen:
// 				respChan <- struct{}{}
// 			case event := <-t.watcher.Events:
// 				fmt.Println("Got an event")
// 				if respChan == nil {
// 					log.Fatalf("Got unexpected event; not listening but got %v\n", event)
// 				}
// 				if event.Op&fsnotify.Create == fsnotify.Create {
// 					respChan <- struct{}{}
// 					respChan = nil
// 				}
// 			case err := <-t.watcher.Errors:
// 				log.Fatalf("Got an error in the watcher: %v\n", err)
// 			}
// 		}
// 	}()
// }

// func (t *NeovimTest) TearDownSuite(c *C) {
// 	err := t.watcher.Close()
// 	if err != nil {
// 		log.Fatalf("Could not cleanly shut down watcher: %v\n", err)
// 	}
// }

func (t *NeovimTest) SetUpTest(c *C) {
	la := os.Getenv("NEOVIM_LISTEN_ADDRESS")

	// cur_t := time.Now()
	// la := fmt.Sprintf("/tmp/neovim.%v%v", cur_t.Unix(), cur_t.Nanosecond())
	// e_la := "NEOVIM_LISTEN_ADDRESS=" + la

	// now start the process and wait for the socket file to be created
	// t.nvim = exec.Command("nvim", "-u /dev/null")
	// new_env := os.Environ()

	// found := false
	// for i, _ := range new_env {
	// 	if strings.HasPrefix(new_env[i], "NEOVIM_LISTEN_ADDRESS=") {
	// 		found = true
	// 		new_env[i] = e_la
	// 	}
	// }
	// if !found {
	// 	new_env = append(new_env, e_la)
	// }
	// t.nvim.Env = new_env

	// done_chan := make(chan struct{})
	// t.startListen <- done_chan
	// <-done_chan
	// t.watcher.Add(la)
	// err := t.nvim.Start()
	// if err != nil {
	// 	log.Fatalf("Could not start nvim instance: %v\n", err)
	// }
	// <-done_chan
	// t.watcher.Remove(la)

	// fmt.Println("Starting test")

	// now we can create a new client
	client, err := neovim.NewUnixClient("unix", nil, &net.UnixAddr{Name: la})
	if err != nil {
		log.Fatalf("Could not setup client: %v", errgo.Details(err))
	}
	client.PanicOnError = true
	t.client = client
}

// func (t *NeovimTest) TearDownTest(c *C) {
// 	err := t.nvim.Process.Kill()
// 	if err != nil {
// 		log.Fatalf("Could not kill nvim instance: %v\n", err)
// 	}
// }

func (t *NeovimTest) TestClientGetBuffers(c *C) {
	ba, err := t.client.GetBuffers()
	c.Assert(err, IsNil)
	c.Assert(ba, NotNil)
}

func (t *NeovimTest) TestConcurrentClientGetBuffers(c *C) {
	var wg sync.WaitGroup
	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			ba, err := t.client.GetBuffers()
			c.Assert(err, IsNil)
			c.Assert(ba, NotNil)
		}()
	}
	wg.Wait()
}

func (t *NeovimTest) TestClientGetCurrentBuffer(c *C) {
	_, err := t.client.GetCurrentBuffer()
	c.Assert(err, IsNil)
}

func (t *NeovimTest) TestBufferGetLength(c *C) {
	b, err := t.client.GetCurrentBuffer()
	c.Assert(err, IsNil)
	l, err := b.GetLength()
	c.Assert(err, IsNil)
	c.Assert(l, Equals, 1)
}

func (t *NeovimTest) TestBufferSetGetLine(c *C) {
	b, err := t.client.GetCurrentBuffer()
	c.Assert(err, IsNil)
	val := "This is line 1"
	err = b.SetLine(0, val)
	c.Assert(err, IsNil)
	l, err := b.GetLine(0)
	c.Assert(err, IsNil)
	c.Assert(l, Equals, val)
	err = b.DelLine(0)
	c.Assert(err, IsNil)
	length, err := b.GetLength()
	c.Assert(err, IsNil)
	c.Assert(length, Equals, 1)
}

func (t *NeovimTest) TestEval(c *C) {
	res, err := t.client.Eval(`4`)
	c.Assert(err, IsNil)
	res_i := res.(int64)
	c.Assert(res_i > 0, Equals, true)
}

func (t *NeovimTest) TestClientSubscribe(c *C) {
	respChan := make(chan neovim.SubscriptionEvent)
	errChan := make(chan error)
	topic := "event1"
	val := []interface{}{1, 2, 3}

	vals := make([]string, len(val))
	for i := range val {
		vals[i] = fmt.Sprintf("%v", val[i])
	}

	t.client.SubChan <- neovim.Subscription{
		Topic:  topic,
		Events: respChan,
		Error:  errChan,
	}
	err := <-errChan
	c.Assert(err, IsNil)
	err = t.client.Subscribe(topic)
	c.Assert(err, IsNil)
	command := fmt.Sprintf(`call send_event(0, "%v", [%v])`, topic, strings.Join(vals, ","))
	err = t.client.Command(command)
	c.Assert(err, IsNil)
	resp := <-respChan
	c.Assert(resp, NotNil)
}

func (t *NeovimTest) TestGetSlice(c *C) {
	cb, err := t.client.GetCurrentBuffer()
	c.Assert(err, IsNil)
	lines, err := cb.GetSlice(0, -1, true, true)
	c.Assert(err, IsNil)
	c.Assert(lines, NotNil)
}

func (t *NeovimTest) TestNumberEval(c *C) {
	_, err := t.client.Eval("127")
	c.Assert(err, IsNil)
}

func (t *NeovimTest) TestArrayEval(c *C) {
	err := t.client.Command("let x=1 | let y=2")
	_v, err := t.client.Eval("[x,y]")
	v := _v.([]interface{})
	c.Assert(err, IsNil)
	comp := []int64{1, 2}
	c.Assert(len(v), Equals, len(comp))
	for i := range v {
		c.Assert(comp[i], Equals, v[i].(int64))
	}
}

func (t *NeovimTest) BenchmarkCommandAndEval(c *C) {
	for i := 0; i < c.N; i++ {
		err := t.client.Command(fmt.Sprintf("let x=%v", i))
		c.Assert(err, IsNil)
		v, err := t.client.Eval("x")
		c.Assert(err, IsNil)
		switch v.(type) {
		case int64:
			c.Assert(v, Equals, int64(i))
		case uint64:
			c.Assert(v, Equals, uint64(i))
		default:
			panic("Unkown type")
		}
	}
}

func (t *NeovimTest) BenchmarkMatchAddEmptyBuffer(c *C) {
	for i := 0; i < c.N; i++ {
		id, err := t.client.Eval(fmt.Sprintf("matchadd('String', '\\%%%vl\\%%2c\\_.\\{8\\}')", i))
		c.Assert(err, IsNil)
		c.Assert(id, NotNil)
	}
}

func (t *NeovimTest) BenchmarkGetBufferContents(c *C) {
	// TODO this needs to first fill the buffer with suitable contents
	cb, _ := t.client.GetCurrentBuffer()
	c.ResetTimer()
	for i := 0; i < c.N; i++ {
		_, _ = cb.GetSlice(0, -1, true, true)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/Sirupsen/logrus"
	"github.com/aybabtme/logzalgo"
)

func main() {
	log := logzalgo.New()
	for {
		log.WithFields(logrus.Fields{
			"animal": "walrus",
			"size":   "10",
		}).Print("To invoke the hive-mind representing chaos.")

		log.WithFields(logrus.Fields{
			"omg":    true,
			"number": 122,
		}).Warn("Invoking the feeling of chaos.")

		log.WithFields(logrus.Fields{
			"animal": "walrus",
			"size":   "10",
		}).Print("With out order.")

		log.WithFields(logrus.Fields{
			"animal": "walrus",
			"size":   "9",
		}).Error("The Nezperdian hive-mind of chaos. Zalgo.")

		log.WithFields(logrus.Fields{
			"omg":    true,
			"number": 100,
		}).Warn("He who Waits Behind The Wall.")

		log.Fatal("ZALGO !")
	}
}
<commit_msg>Fix logrus namespace casing.<commit_after>package main

import (
	"github.com/sirupsen/logrus"
	"github.com/aybabtme/logzalgo"
)

func main() {
	log := logzalgo.New()
	for {
		log.WithFields(logrus.Fields{
			"animal": "walrus",
			"size":   "10",
		}).Print("To invoke the hive-mind representing chaos.")

		log.WithFields(logrus.Fields{
			"omg":    true,
			"number": 122,
		}).Warn("Invoking the feeling of chaos.")

		log.WithFields(logrus.Fields{
			"animal": "walrus",
			"size":   "10",
		}).Print("With out order.")

		log.WithFields(logrus.Fields{
			"animal": "walrus",
			"size":   "9",
		}).Error("The Nezperdian hive-mind of chaos. Zalgo.")

		log.WithFields(logrus.Fields{
			"omg":    true,
			"number": 100,
		}).Warn("He who Waits Behind The Wall.")

		log.Fatal("ZALGO !")
	}
}
<|endoftext|>


<commit_before>package filesystem

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path"
	"time"

	"github.com/astaxie/beego/context"
	"github.com/astaxie/beego/logs"

	storagedriver "github.com/initlove/ocihub/storage/driver"
)

const (
	driverName = "filesystem"
)

// DriverParameters represents all configuration options available for the
// filesystem driver
type DriverParameters struct {
	RootDirectory string
}

type driver struct {
	rootDirectory string
}

func init() {
	if err := storagedriver.Register(driverName, &driver{}); err != nil {
		logs.Error("Failed to register Storage driver '%s'.", driverName)
	} else {
		logs.Debug("Storage driver '%s' registered.", driverName)
	}
}

func (d *driver) Init(parameters map[string]interface{}) error {
	if parameters != nil {
		data := parameters["rootDirectory"]
		if data != nil {
			if v, ok := data.(string); ok && v != "" {
				d.rootDirectory = v
				return nil
			} else {
				return errors.New("invalid 'rootDirectory' data, should be non-empty string")
			}
		}
	}

	return errors.New("missing 'rootDirectory' data")
}

func (d *driver) Valid(parameters map[string]interface{}) error {
	if parameters != nil {
		data := parameters["rootDirectory"]
		if data != nil {
			if v, ok := data.(string); ok && v != "" {
				return nil
			} else {
				return errors.New("invalid 'rootDirectory' data, should be non-empty string")
			}
		}
	}

	return errors.New("missing 'rootDirectory' data")
}

// Implement the storagedriver.StorageDriver interface
func (d *driver) Name() string {
	return driverName
}

// GetContent retrieves the content stored at "path" as a []byte.
func (d *driver) GetContent(ctx context.Context, path string) ([]byte, error) {
	rc, err := d.Reader(ctx, path, 0)
	if err != nil {
		return nil, err
	}
	defer rc.Close()

	p, err := ioutil.ReadAll(rc)
	if err != nil {
		return nil, err
	}

	return p, nil
}

// PutContent stores the []byte content at a location designated by "path".
func (d *driver) PutContent(ctx context.Context, subPath string, contents []byte) error {
	writer, err := d.Writer(ctx, subPath, false)
	if err != nil {
		return err
	}
	defer writer.Close()
	_, err = io.Copy(writer, bytes.NewReader(contents))
	if err != nil {
		writer.Cancel()
		return err
	}
	return writer.Commit()
}

// Reader retrieves an io.ReadCloser for the content stored at "path" with a
// given byte offset.
func (d *driver) Reader(ctx context.Context, path string, offset int64) (io.ReadCloser, error) {
	file, err := os.OpenFile(d.fullPath(path), os.O_RDONLY, 0644)
	if err != nil {
		if os.IsNotExist(err) {
			return nil, storagedriver.PathNotFoundError{Path: path}
		}

		return nil, err
	}

	seekPos, err := file.Seek(int64(offset), os.SEEK_SET)
	if err != nil {
		file.Close()
		return nil, err
	} else if seekPos < int64(offset) {
		file.Close()
		return nil, storagedriver.InvalidOffsetError{Path: path, Offset: offset}
	}

	return file, nil
}

func (d *driver) Writer(ctx context.Context, subPath string, append bool) (storagedriver.FileWriter, error) {
	fullPath := d.fullPath(subPath)
	parentDir := path.Dir(fullPath)
	if err := os.MkdirAll(parentDir, 0777); err != nil {
		return nil, err
	}

	fp, err := os.OpenFile(fullPath, os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		return nil, err
	}

	var offset int64

	if !append {
		err := fp.Truncate(0)
		if err != nil {
			fp.Close()
			return nil, err
		}
	} else {
		n, err := fp.Seek(0, os.SEEK_END)
		if err != nil {
			fp.Close()
			return nil, err
		}
		offset = int64(n)
	}

	return newFileWriter(fp, offset), nil
}

// Stat retrieves the FileInfo for the given path, including the current size
// in bytes and the creation time.
func (d *driver) Stat(ctx context.Context, subPath string) (storagedriver.FileInfo, error) {
	fullPath := d.fullPath(subPath)

	fi, err := os.Stat(fullPath)
	if err != nil {
		if os.IsNotExist(err) {
			return nil, storagedriver.PathNotFoundError{Path: subPath}
		}

		return nil, err
	}

	return fileInfo{
		path:     subPath,
		FileInfo: fi,
	}, nil
}

// List returns a list of the objects that are direct descendants of the given
// path.
func (d *driver) List(ctx context.Context, subPath string) ([]string, error) {
	fullPath := d.fullPath(subPath)

	dir, err := os.Open(fullPath)
	if err != nil {
		if os.IsNotExist(err) {
			return nil, storagedriver.PathNotFoundError{Path: subPath}
		}
		return nil, err
	}

	defer dir.Close()

	fileNames, err := dir.Readdirnames(0)
	if err != nil {
		return nil, err
	}

	keys := make([]string, 0, len(fileNames))
	for _, fileName := range fileNames {
		keys = append(keys, path.Join(subPath, fileName))
	}

	return keys, nil
}

// Move moves an object stored at sourcePath to destPath, removing the original
// object.
func (d *driver) Move(ctx context.Context, sourcePath string, destPath string) error {
	source := d.fullPath(sourcePath)
	dest := d.fullPath(destPath)

	if _, err := os.Stat(source); os.IsNotExist(err) {
		return storagedriver.PathNotFoundError{Path: sourcePath}
	}

	if err := os.MkdirAll(path.Dir(dest), 0755); err != nil {
		return err
	}

	err := os.Rename(source, dest)
	return err
}

// Delete recursively deletes all objects stored at "path" and its subpaths.
func (d *driver) Delete(ctx context.Context, subPath string) error {
	fullPath := d.fullPath(subPath)

	_, err := os.Stat(fullPath)
	if err != nil && !os.IsNotExist(err) {
		return err
	} else if err != nil {
		return storagedriver.PathNotFoundError{Path: subPath}
	}

	err = os.RemoveAll(fullPath)
	return err
}

// URLFor returns a URL which may be used to retrieve the content stored at the given path.
// May return an UnsupportedMethodErr in certain StorageDriver implementations.
func (d *driver) URLFor(ctx context.Context, path string, options map[string]interface{}) (string, error) {
	return "", storagedriver.ErrUnsupportedMethod{}
}

// fullPath returns the absolute path of a key within the Driver's storage.
func (d *driver) fullPath(subPath string) string {
	return path.Join(d.rootDirectory, subPath)
}

type fileInfo struct {
	os.FileInfo
	path string
}

var _ storagedriver.FileInfo = fileInfo{}

// Path provides the full path of the target of this file info.
func (fi fileInfo) Path() string {
	return fi.path
}

// Size returns current length in bytes of the file. The return value can
// be used to write to the end of the file at path. The value is
// meaningless if IsDir returns true.
func (fi fileInfo) Size() int64 {
	if fi.IsDir() {
		return 0
	}

	return fi.FileInfo.Size()
}

// ModTime returns the modification time for the file. For backends that
// don't have a modification time, the creation time should be returned.
func (fi fileInfo) ModTime() time.Time {
	return fi.FileInfo.ModTime()
}

// IsDir returns true if the path is a directory.
func (fi fileInfo) IsDir() bool {
	return fi.FileInfo.IsDir()
}

type fileWriter struct {
	file      *os.File
	size      int64
	bw        *bufio.Writer
	closed    bool
	committed bool
	cancelled bool
}

func newFileWriter(file *os.File, size int64) *fileWriter {
	return &fileWriter{
		file: file,
		size: size,
		bw:   bufio.NewWriter(file),
	}
}

func (fw *fileWriter) Write(p []byte) (int, error) {
	if fw.closed {
		return 0, fmt.Errorf("already closed")
	} else if fw.committed {
		return 0, fmt.Errorf("already committed")
	} else if fw.cancelled {
		return 0, fmt.Errorf("already cancelled")
	}
	n, err := fw.bw.Write(p)
	fw.size += int64(n)
	return n, err
}

func (fw *fileWriter) Size() int64 {
	return fw.size
}

func (fw *fileWriter) Close() error {
	if fw.closed {
		return fmt.Errorf("already closed")
	}

	if err := fw.bw.Flush(); err != nil {
		return err
	}

	if err := fw.file.Sync(); err != nil {
		return err
	}

	if err := fw.file.Close(); err != nil {
		return err
	}
	fw.closed = true
	return nil
}

func (fw *fileWriter) Cancel() error {
	if fw.closed {
		return fmt.Errorf("already closed")
	}

	fw.cancelled = true
	fw.file.Close()
	return os.Remove(fw.file.Name())
}

func (fw *fileWriter) Commit() error {
	if fw.closed {
		return fmt.Errorf("already closed")
	} else if fw.committed {
		return fmt.Errorf("already committed")
	} else if fw.cancelled {
		return fmt.Errorf("already cancelled")
	}

	if err := fw.bw.Flush(); err != nil {
		return err
	}

	if err := fw.file.Sync(); err != nil {
		return err
	}

	fw.committed = true
	return nil
}
<commit_msg>change else style<commit_after>package filesystem

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path"
	"time"

	"github.com/astaxie/beego/context"
	"github.com/astaxie/beego/logs"

	storagedriver "github.com/initlove/ocihub/storage/driver"
)

const (
	driverName = "filesystem"
)

// DriverParameters represents all configuration options available for the
// filesystem driver
type DriverParameters struct {
	RootDirectory string
}

type driver struct {
	rootDirectory string
}

func init() {
	if err := storagedriver.Register(driverName, &driver{}); err != nil {
		logs.Error("Failed to register Storage driver '%s'.", driverName)
	} else {
		logs.Debug("Storage driver '%s' registered.", driverName)
	}
}

func (d *driver) Init(parameters map[string]interface{}) error {
	if parameters != nil {
		data := parameters["rootDirectory"]
		if data != nil {
			if v, ok := data.(string); ok && v != "" {
				d.rootDirectory = v
				return nil
			}
			return errors.New("invalid 'rootDirectory' data, should be non-empty string")
		}
	}

	return errors.New("missing 'rootDirectory' data")
}

func (d *driver) Valid(parameters map[string]interface{}) error {
	if parameters != nil {
		data := parameters["rootDirectory"]
		if data != nil {
			if v, ok := data.(string); ok && v != "" {
				return nil
			}
			return errors.New("invalid 'rootDirectory' data, should be non-empty string")
		}
	}

	return errors.New("missing 'rootDirectory' data")
}

// Implement the storagedriver.StorageDriver interface
func (d *driver) Name() string {
	return driverName
}

// GetContent retrieves the content stored at "path" as a []byte.
func (d *driver) GetContent(ctx context.Context, path string) ([]byte, error) {
	rc, err := d.Reader(ctx, path, 0)
	if err != nil {
		return nil, err
	}
	defer rc.Close()

	p, err := ioutil.ReadAll(rc)
	if err != nil {
		return nil, err
	}

	return p, nil
}

// PutContent stores the []byte content at a location designated by "path".
func (d *driver) PutContent(ctx context.Context, subPath string, contents []byte) error {
	writer, err := d.Writer(ctx, subPath, false)
	if err != nil {
		return err
	}
	defer writer.Close()
	_, err = io.Copy(writer, bytes.NewReader(contents))
	if err != nil {
		writer.Cancel()
		return err
	}
	return writer.Commit()
}

// Reader retrieves an io.ReadCloser for the content stored at "path" with a
// given byte offset.
func (d *driver) Reader(ctx context.Context, path string, offset int64) (io.ReadCloser, error) {
	file, err := os.OpenFile(d.fullPath(path), os.O_RDONLY, 0644)
	if err != nil {
		if os.IsNotExist(err) {
			return nil, storagedriver.PathNotFoundError{Path: path}
		}

		return nil, err
	}

	seekPos, err := file.Seek(int64(offset), os.SEEK_SET)
	if err != nil {
		file.Close()
		return nil, err
	} else if seekPos < int64(offset) {
		file.Close()
		return nil, storagedriver.InvalidOffsetError{Path: path, Offset: offset}
	}

	return file, nil
}

func (d *driver) Writer(ctx context.Context, subPath string, append bool) (storagedriver.FileWriter, error) {
	fullPath := d.fullPath(subPath)
	parentDir := path.Dir(fullPath)
	if err := os.MkdirAll(parentDir, 0777); err != nil {
		return nil, err
	}

	fp, err := os.OpenFile(fullPath, os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		return nil, err
	}

	var offset int64

	if !append {
		err := fp.Truncate(0)
		if err != nil {
			fp.Close()
			return nil, err
		}
	} else {
		n, err := fp.Seek(0, os.SEEK_END)
		if err != nil {
			fp.Close()
			return nil, err
		}
		offset = int64(n)
	}

	return newFileWriter(fp, offset), nil
}

// Stat retrieves the FileInfo for the given path, including the current size
// in bytes and the creation time.
func (d *driver) Stat(ctx context.Context, subPath string) (storagedriver.FileInfo, error) {
	fullPath := d.fullPath(subPath)

	fi, err := os.Stat(fullPath)
	if err != nil {
		if os.IsNotExist(err) {
			return nil, storagedriver.PathNotFoundError{Path: subPath}
		}

		return nil, err
	}

	return fileInfo{
		path:     subPath,
		FileInfo: fi,
	}, nil
}

// List returns a list of the objects that are direct descendants of the given
// path.
func (d *driver) List(ctx context.Context, subPath string) ([]string, error) {
	fullPath := d.fullPath(subPath)

	dir, err := os.Open(fullPath)
	if err != nil {
		if os.IsNotExist(err) {
			return nil, storagedriver.PathNotFoundError{Path: subPath}
		}
		return nil, err
	}

	defer dir.Close()

	fileNames, err := dir.Readdirnames(0)
	if err != nil {
		return nil, err
	}

	keys := make([]string, 0, len(fileNames))
	for _, fileName := range fileNames {
		keys = append(keys, path.Join(subPath, fileName))
	}

	return keys, nil
}

// Move moves an object stored at sourcePath to destPath, removing the original
// object.
func (d *driver) Move(ctx context.Context, sourcePath string, destPath string) error {
	source := d.fullPath(sourcePath)
	dest := d.fullPath(destPath)

	if _, err := os.Stat(source); os.IsNotExist(err) {
		return storagedriver.PathNotFoundError{Path: sourcePath}
	}

	if err := os.MkdirAll(path.Dir(dest), 0755); err != nil {
		return err
	}

	err := os.Rename(source, dest)
	return err
}

// Delete recursively deletes all objects stored at "path" and its subpaths.
func (d *driver) Delete(ctx context.Context, subPath string) error {
	fullPath := d.fullPath(subPath)

	_, err := os.Stat(fullPath)
	if err != nil && !os.IsNotExist(err) {
		return err
	} else if err != nil {
		return storagedriver.PathNotFoundError{Path: subPath}
	}

	err = os.RemoveAll(fullPath)
	return err
}

// URLFor returns a URL which may be used to retrieve the content stored at the given path.
// May return an UnsupportedMethodErr in certain StorageDriver implementations.
func (d *driver) URLFor(ctx context.Context, path string, options map[string]interface{}) (string, error) {
	return "", storagedriver.ErrUnsupportedMethod{}
}

// fullPath returns the absolute path of a key within the Driver's storage.
func (d *driver) fullPath(subPath string) string {
	return path.Join(d.rootDirectory, subPath)
}

type fileInfo struct {
	os.FileInfo
	path string
}

var _ storagedriver.FileInfo = fileInfo{}

// Path provides the full path of the target of this file info.
func (fi fileInfo) Path() string {
	return fi.path
}

// Size returns current length in bytes of the file. The return value can
// be used to write to the end of the file at path. The value is
// meaningless if IsDir returns true.
func (fi fileInfo) Size() int64 {
	if fi.IsDir() {
		return 0
	}

	return fi.FileInfo.Size()
}

// ModTime returns the modification time for the file. For backends that
// don't have a modification time, the creation time should be returned.
func (fi fileInfo) ModTime() time.Time {
	return fi.FileInfo.ModTime()
}

// IsDir returns true if the path is a directory.
func (fi fileInfo) IsDir() bool {
	return fi.FileInfo.IsDir()
}

type fileWriter struct {
	file      *os.File
	size      int64
	bw        *bufio.Writer
	closed    bool
	committed bool
	cancelled bool
}

func newFileWriter(file *os.File, size int64) *fileWriter {
	return &fileWriter{
		file: file,
		size: size,
		bw:   bufio.NewWriter(file),
	}
}

func (fw *fileWriter) Write(p []byte) (int, error) {
	if fw.closed {
		return 0, fmt.Errorf("already closed")
	} else if fw.committed {
		return 0, fmt.Errorf("already committed")
	} else if fw.cancelled {
		return 0, fmt.Errorf("already cancelled")
	}
	n, err := fw.bw.Write(p)
	fw.size += int64(n)
	return n, err
}

func (fw *fileWriter) Size() int64 {
	return fw.size
}

func (fw *fileWriter) Close() error {
	if fw.closed {
		return fmt.Errorf("already closed")
	}

	if err := fw.bw.Flush(); err != nil {
		return err
	}

	if err := fw.file.Sync(); err != nil {
		return err
	}

	if err := fw.file.Close(); err != nil {
		return err
	}
	fw.closed = true
	return nil
}

func (fw *fileWriter) Cancel() error {
	if fw.closed {
		return fmt.Errorf("already closed")
	}

	fw.cancelled = true
	fw.file.Close()
	return os.Remove(fw.file.Name())
}

func (fw *fileWriter) Commit() error {
	if fw.closed {
		return fmt.Errorf("already closed")
	} else if fw.committed {
		return fmt.Errorf("already committed")
	} else if fw.cancelled {
		return fmt.Errorf("already cancelled")
	}

	if err := fw.bw.Flush(); err != nil {
		return err
	}

	if err := fw.file.Sync(); err != nil {
		return err
	}

	fw.committed = true
	return nil
}
<|endoftext|>


<commit_before>package models

import (
	"encoding/json"
	"fmt"
	"gitlab.com/kanban/kanban/modules/gitlab"
	"regexp"
	"strconv"
	"strings"
)

// Card represents an card in kanban board
type Card struct {
	Id          int64       `json:"id"`
	Iid         int64       `json:"iid"`
	Assignee    *User       `json:"assignee"`
	Milestone   *Milestone  `json:"milestone"`
	Author      *User       `json:"author"`
	Description string      `json:"description"`
	Labels      []string    `json:"labels"`
	ProjectId   int64       `json:"project_id"`
	Properties  *Properties `json:"properties"`
	State       string      `json:"state"`
	Title       string      `json:"title"`
	Todo        []*Todo     `json:"todo"`
}

// CardRequest represents a card request for create, update, delete card on kanban
type CardRequest struct {
	CardId      int64             `json:"issue_id"`
	ProjectId   int64             `json:"project_id"`
	Title       string            `json:"title"`
	Description string            `json:"description"`
	AssigneeId  *int64            `json:"assignee_id"`
	MilestoneId *int64            `json:"milestone_id"`
	Labels      string            `json:"labels"`
	Properties  *Properties       `json:"properties"`
	Stage       map[string]string `json:"stage"`
	Todo        []*Todo           `json:"todo"`
}

// Properties represents a card properties
type Properties struct {
	Andon string `json:"andon"`
}

// Todo represents an todo an card
type Todo struct {
	Body    string `json:"body"`
	Checked bool   `json:"checked"`
}

var (
	regTodo = regexp.MustCompile(`[-\*]{1}\s(?P<checked>\[.\])(?P<body>.*)`)
	regProp = regexp.MustCompile(`<!--\s@KB:(.*?)\s-->`)
)

// ListCards returns list card
func ListCards(u *User, provider, board_id string) ([]*Card, error) {
	var b []*Card
	switch provider {
	case "gitlab":
		c := gitlab.NewContext(u.Credential["gitlab"].Token, u.Credential["gitlab"].PrivateToken)
		op := &gitlab.IssueListOptions{
			State: "opened",
		}
		op.Page = "1"
		op.PerPage = "200"

		r, err := c.ListIssues(board_id, op)

		if err != nil {
			return nil, err
		}

		for _, d := range r {
			b = append(b, mapCardFromGitlab(d))
		}
	}

	return b, nil
}

// CreateCard create new card on board
func CreateCard(u *User, provider string, form *CardRequest) (*Card, int, error) {
	var cr *Card
	var code int
	switch provider {
	case "gitlab":
		c := gitlab.NewContext(u.Credential["gitlab"].Token, u.Credential["gitlab"].PrivateToken)
		r, res, err := c.CreateIssue(strconv.FormatInt(form.ProjectId, 10), mapCardRequestToGitlab(form))
		if err != nil {
			return nil, res.StatusCode, err
		}

		cr = mapCardFromGitlab(r)
	}

	return cr, code, nil
}

// UpdateCard updates existing card on board
func UpdateCard(u *User, provider string, form *CardRequest) (*Card, int, error) {
	var cr *Card
	var code int
	switch provider {
	case "gitlab":
		c := gitlab.NewContext(u.Credential["gitlab"].Token, u.Credential["gitlab"].PrivateToken)
		r, res, err := c.UpdateIssue(
			strconv.FormatInt(form.ProjectId, 10),
			strconv.FormatInt(form.CardId, 10),
			mapCardRequestToGitlab(form),
		)
		if err != nil {
			return nil, res.StatusCode, err
		}

		cr = mapCardFromGitlab(r)
	}

	return cr, code, nil
}

// DeleteCard removes card from board
func DeleteCard(u *User, provider string, form *CardRequest) (*Card, int, error) {
	var cr *Card
	var code int
	switch provider {
	case "gitlab":
		c := gitlab.NewContext(u.Credential["gitlab"].Token, u.Credential["gitlab"].PrivateToken)
		foru := mapCardRequestToGitlab(form)
		foru.StateEvent = "close"
		r, res, err := c.UpdateIssue(
			strconv.FormatInt(form.ProjectId, 10),
			strconv.FormatInt(form.CardId, 10),
			foru,
		)
		if err != nil {
			return nil, res.StatusCode, err
		}

		cr = mapCardFromGitlab(r)
	}

	return cr, code, nil
}

// mapCardRequestToGitlab transforms card to gitlab issue request
func mapCardRequestToGitlab(c *CardRequest) *gitlab.IssueRequest {
	return &gitlab.IssueRequest{
		Title:       c.Title,
		Description: mapCardDescriptionToGitlab(c.Description, c.Todo, c.Properties),
		AssigneeId:  c.AssigneeId,
		MilestoneId: c.MilestoneId,
		Labels:      c.Labels,
	}
}

// mapCardDescriptionToGitlab Transforms card description to gitlab description
func mapCardDescriptionToGitlab(desc string, t []*Todo, p *Properties) string {
	var d string
	var chek string
	d = desc
	for _, v := range t {
		if v.Checked {
			chek = "x"
		} else {
			chek = " "
		}
		d = fmt.Sprintf("%s\n- [%s] %s", d, chek, v.Body)
	}

	pr, err := json.Marshal(p)

	if err == nil {
		d = fmt.Sprintf("%s\n<!-- @KB:%s -->", d, string(pr))
	}

	return strings.TrimSpace(d)
}

// mapCardFromGitlab mapped gitlab issue to kanban card
func mapCardFromGitlab(c *gitlab.Issue) *Card {
	return &Card{
		Id:          c.Id,
		Iid:         c.Iid,
		Title:       c.Title,
		State:       c.State,
		Assignee:    mapUserFromGitlab(c.Assignee),
		Author:      mapUserFromGitlab(c.Author),
		Description: mapCardDescriptionFromGitlab(c.Description),
		Milestone:   mapMilestoneFromGitlab(c.Milestone),
		Labels:      c.Labels,
		ProjectId:   c.ProjectId,
		Properties:  mapCardPropertiesFromGitlab(c.Description),
		Todo:        mapCardTodoFromGitlab(c.Description),
	}
}

// mapCardTodoFromGitlab tranforms gitlab todo to kanban todo
func mapCardTodoFromGitlab(d string) []*Todo {
	var i []*Todo
	m := regTodo.MatchString(d)

	if m {
		n := regTodo.SubexpNames()
		res := regTodo.FindAllStringSubmatch(d, -1)

		for _, r1 := range res {
			t := &Todo{}
			for i, r2 := range r1 {
				switch n[i] {
				case "checked":
					if r2 == "[x]" {
						t.Checked = true
					} else {
						t.Checked = false
					}
				case "body":
					t.Body = r2
				}
			}

			i = append(i, t)
		}
	} else {
		i = make([]*Todo, 0)
	}

	return i
}

func (c *Card) RoutingKey() string {
	return fmt.Sprintf("kanban.%d", c.ProjectId)
}

// mapCardDescriptionFromGitlab clears gitlab description to card description
func mapCardDescriptionFromGitlab(d string) string {
	var r string
	r = regTodo.ReplaceAllString(d, "")
	r = regProp.ReplaceAllString(r, "")
	return r
}

// mapCardPropertiesFromGitlab transforms gitlab description to card properties
func mapCardPropertiesFromGitlab(d string) *Properties {
	m := regProp.MatchString(d)
	var p Properties

	if m {
		an := regProp.FindStringSubmatch(d)
		json.Unmarshal([]byte(an[1]), &p)
	}

	return &p
}
<commit_msg>solved the problem of the emergence of new empty rows<commit_after>package models

import (
	"encoding/json"
	"fmt"
	"gitlab.com/kanban/kanban/modules/gitlab"
	"regexp"
	"strconv"
	"strings"
)

// Card represents an card in kanban board
type Card struct {
	Id          int64       `json:"id"`
	Iid         int64       `json:"iid"`
	Assignee    *User       `json:"assignee"`
	Milestone   *Milestone  `json:"milestone"`
	Author      *User       `json:"author"`
	Description string      `json:"description"`
	Labels      []string    `json:"labels"`
	ProjectId   int64       `json:"project_id"`
	Properties  *Properties `json:"properties"`
	State       string      `json:"state"`
	Title       string      `json:"title"`
	Todo        []*Todo     `json:"todo"`
}

// CardRequest represents a card request for create, update, delete card on kanban
type CardRequest struct {
	CardId      int64             `json:"issue_id"`
	ProjectId   int64             `json:"project_id"`
	Title       string            `json:"title"`
	Description string            `json:"description"`
	AssigneeId  *int64            `json:"assignee_id"`
	MilestoneId *int64            `json:"milestone_id"`
	Labels      string            `json:"labels"`
	Properties  *Properties       `json:"properties"`
	Stage       map[string]string `json:"stage"`
	Todo        []*Todo           `json:"todo"`
}

// Properties represents a card properties
type Properties struct {
	Andon string `json:"andon"`
}

// Todo represents an todo an card
type Todo struct {
	Body    string `json:"body"`
	Checked bool   `json:"checked"`
}

var (
	regTodo = regexp.MustCompile(`[-\*]{1}\s(?P<checked>\[.\])(?P<body>.*)`)
	regProp = regexp.MustCompile(`<!--\s@KB:(.*?)\s-->`)
)

// ListCards returns list card
func ListCards(u *User, provider, board_id string) ([]*Card, error) {
	var b []*Card
	switch provider {
	case "gitlab":
		c := gitlab.NewContext(u.Credential["gitlab"].Token, u.Credential["gitlab"].PrivateToken)
		op := &gitlab.IssueListOptions{
			State: "opened",
		}
		op.Page = "1"
		op.PerPage = "200"

		r, err := c.ListIssues(board_id, op)

		if err != nil {
			return nil, err
		}

		for _, d := range r {
			b = append(b, mapCardFromGitlab(d))
		}
	}

	return b, nil
}

// CreateCard create new card on board
func CreateCard(u *User, provider string, form *CardRequest) (*Card, int, error) {
	var cr *Card
	var code int
	switch provider {
	case "gitlab":
		c := gitlab.NewContext(u.Credential["gitlab"].Token, u.Credential["gitlab"].PrivateToken)
		r, res, err := c.CreateIssue(strconv.FormatInt(form.ProjectId, 10), mapCardRequestToGitlab(form))
		if err != nil {
			return nil, res.StatusCode, err
		}

		cr = mapCardFromGitlab(r)
	}

	return cr, code, nil
}

// UpdateCard updates existing card on board
func UpdateCard(u *User, provider string, form *CardRequest) (*Card, int, error) {
	var cr *Card
	var code int
	switch provider {
	case "gitlab":
		c := gitlab.NewContext(u.Credential["gitlab"].Token, u.Credential["gitlab"].PrivateToken)
		r, res, err := c.UpdateIssue(
			strconv.FormatInt(form.ProjectId, 10),
			strconv.FormatInt(form.CardId, 10),
			mapCardRequestToGitlab(form),
		)
		if err != nil {
			return nil, res.StatusCode, err
		}

		cr = mapCardFromGitlab(r)
	}

	return cr, code, nil
}

// DeleteCard removes card from board
func DeleteCard(u *User, provider string, form *CardRequest) (*Card, int, error) {
	var cr *Card
	var code int
	switch provider {
	case "gitlab":
		c := gitlab.NewContext(u.Credential["gitlab"].Token, u.Credential["gitlab"].PrivateToken)
		foru := mapCardRequestToGitlab(form)
		foru.StateEvent = "close"
		r, res, err := c.UpdateIssue(
			strconv.FormatInt(form.ProjectId, 10),
			strconv.FormatInt(form.CardId, 10),
			foru,
		)
		if err != nil {
			return nil, res.StatusCode, err
		}

		cr = mapCardFromGitlab(r)
	}

	return cr, code, nil
}

// mapCardRequestToGitlab transforms card to gitlab issue request
func mapCardRequestToGitlab(c *CardRequest) *gitlab.IssueRequest {
	return &gitlab.IssueRequest{
		Title:       c.Title,
		Description: mapCardDescriptionToGitlab(c.Description, c.Todo, c.Properties),
		AssigneeId:  c.AssigneeId,
		MilestoneId: c.MilestoneId,
		Labels:      c.Labels,
	}
}

// mapCardDescriptionToGitlab Transforms card description to gitlab description
func mapCardDescriptionToGitlab(desc string, t []*Todo, p *Properties) string {
	var d string
	var chek string
	d = strings.TrimSpace(desc);
	for _, v := range t {
		if v.Checked {
			chek = "x"
		} else {
			chek = " "
		}
		d = fmt.Sprintf("%s\n- [%s] %s", d, chek, v.Body)
	}

	pr, err := json.Marshal(p)

	if err == nil {
		d = fmt.Sprintf("%s\n\n<!-- @KB:%s -->", strings.TrimSpace(d), string(pr))
	}

	return strings.TrimSpace(d);
}

// mapCardFromGitlab mapped gitlab issue to kanban card
func mapCardFromGitlab(c *gitlab.Issue) *Card {
	return &Card{
		Id:          c.Id,
		Iid:         c.Iid,
		Title:       c.Title,
		State:       c.State,
		Assignee:    mapUserFromGitlab(c.Assignee),
		Author:      mapUserFromGitlab(c.Author),
		Description: mapCardDescriptionFromGitlab(c.Description),
		Milestone:   mapMilestoneFromGitlab(c.Milestone),
		Labels:      c.Labels,
		ProjectId:   c.ProjectId,
		Properties:  mapCardPropertiesFromGitlab(c.Description),
		Todo:        mapCardTodoFromGitlab(c.Description),
	}
}

// mapCardTodoFromGitlab tranforms gitlab todo to kanban todo
func mapCardTodoFromGitlab(d string) []*Todo {
	var i []*Todo
	m := regTodo.MatchString(d)

	if m {
		n := regTodo.SubexpNames()
		res := regTodo.FindAllStringSubmatch(d, -1)

		for _, r1 := range res {
			t := &Todo{}
			for i, r2 := range r1 {
				switch n[i] {
				case "checked":
					if r2 == "[x]" {
						t.Checked = true
					} else {
						t.Checked = false
					}
				case "body":
					t.Body = r2
				}
			}

			i = append(i, t)
		}
	} else {
		i = make([]*Todo, 0)
	}

	return i
}

func (c *Card) RoutingKey() string {
	return fmt.Sprintf("kanban.%d", c.ProjectId)
}

// mapCardDescriptionFromGitlab clears gitlab description to card description
func mapCardDescriptionFromGitlab(d string) string {
	var r string
	r = regTodo.ReplaceAllString(d, "")
	r = regProp.ReplaceAllString(r, "")
	return strings.TrimSpace(r)
}

// mapCardPropertiesFromGitlab transforms gitlab description to card properties
func mapCardPropertiesFromGitlab(d string) *Properties {
	m := regProp.MatchString(d)
	var p Properties

	if m {
		an := regProp.FindStringSubmatch(d)
		json.Unmarshal([]byte(an[1]), &p)
	}

	return &p
}
<|endoftext|>


<commit_before>package index

import (
	"crypto/sha1"
	"encoding/json"
	"io"
	"os"
	"path/filepath"
	"runtime"
	"sync"
	"time"

	"github.com/djherbis/times"
)

// Version stores current version of index.
const Version = 1

// Entry represents a single file registered to index.
type Entry struct {
	Name  string      `json:"name"`  // The relative name of the file.
	CTime int64       `json:"ctime"` // Metadata change time since EPOCH.
	MTime int64       `json:"mtime"` // File data change time since EPOCH.
	Mode  os.FileMode `json:"mode"`  // File mode and permission bits.
	Size  int64       `json:"size"`  // Size of the file.
	SHA1  []byte      `json:"sha1"`  // SHA-1 hash of file content.
}

// NewEntryFile creates new Entry from a file stored under path argument.
// Info is optional and, if given, should store LStat result on the given file.
func NewEntryFile(root, path string, info os.FileInfo) (e *Entry, err error) {
	if info == nil {
		if info, err = os.Lstat(path); err != nil {
			return nil, err
		}
	}

	// Get relative file name.
	name, err := filepath.Rel(root, path)
	if err != nil {
		return nil, err
	}

	// Compute file's SHA-1 sum.
	var sum []byte
	if !info.IsDir() {
		if sum, err = readSHA1(path); err != nil {
			return nil, err
		}
	}

	return &Entry{
		Name:  filepath.ToSlash(name),
		CTime: ctime(info),
		MTime: info.ModTime().UnixNano(),
		Mode:  info.Mode(),
		Size:  info.Size(),
		SHA1:  sum,
	}, nil
}

// readSHA1 computes SHA-1 sum from a given file content.
func readSHA1(path string) ([]byte, error) {
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	hash := sha1.New()
	if _, err := io.Copy(hash, file); err != nil {
		return nil, err
	}

	return hash.Sum(nil), nil
}

// ChangeMeta indicates what change has been done on a given file.
type ChangeMeta uint32

const (
	ChangeMetaUpdate ChangeMeta = 1 << iota // File was updated.
	ChangeMetaRemove                        // File was removed.
	ChangeMetaAdd                           // File was added.

	ChangeMetaLarge ChangeMeta = 1 << (8 + iota) // File size is above 4GB.
)

// Change describes single file change.
type Change struct {
	Name      string     `json:"name"`      // The relative name of the file.
	Size      uint32     `json:"size"`      // Size of the file truncated to 32 bits.
	Meta      ChangeMeta `json:"meta"`      // The type of operation made on file entry.
	CreatedAt int64      `json:"createdAt"` // Change creation time since EPOCH.
}

// ChangeSlice stores multiple changes.
type ChangeSlice []Change

func (cs ChangeSlice) Len() int           { return len(cs) }
func (cs ChangeSlice) Swap(i, j int)      { cs[i], cs[j] = cs[j], cs[i] }
func (cs ChangeSlice) Less(i, j int) bool { return cs[i].Name < cs[j].Name }

// Index stores a virtual working tree state. It recursively records objects in
// a given root path and allows to efficiently detect changes on it.
type Index struct {
	limitC chan struct{}

	mu      sync.RWMutex
	entries map[string]*Entry
}

var (
	_ json.Marshaler   = (*Index)(nil)
	_ json.Unmarshaler = (*Index)(nil)
)

// NewIndex creates the empty index object.
func NewIndex() *Index {
	return &Index{
		limitC:  make(chan struct{}, 2*runtime.NumCPU()),
		entries: make(map[string]*Entry, 0),
	}
}

// NewIndexFiles walks the given file tree roted at root and records file
// states to resulting Index object.
func NewIndexFiles(root string) (*Index, error) {
	idx := NewIndex()

	// In order to get as much entries as we can we ignore errors.
	var wg sync.WaitGroup
	walkFn := func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return nil
		}

		// Skip root path.
		if name, err := filepath.Rel(root, path); err != nil || name == "." {
			return nil
		}

		wg.Add(1)
		idx.addEntry(&wg, root, path, info)
		return nil
	}

	if err := filepath.Walk(root, walkFn); err != nil {
		return nil, err
	}

	wg.Wait()
	return idx, nil
}

// addEntry asynchronously adds new entry to index. This function has limits
// to a number of started go-routines. Errors are ignored.
func (idx *Index) addEntry(wg *sync.WaitGroup, root, path string, info os.FileInfo) {
	idx.limitC <- struct{}{}

	go func() {
		defer func() {
			<-idx.limitC
			wg.Done()
		}()

		entry, err := NewEntryFile(root, path, info)
		if err != nil {
			return
		}

		idx.mu.Lock()
		idx.entries[entry.Name] = entry
		idx.mu.Unlock()
	}()
}

// Count returns the number of entries stored in index. Only items which size is
// below provided value are counted. If provided argument is negative, this
// function will return the number of all entries.
func (idx *Index) Count(maxsize int64) (count int) {
	idx.mu.RLock()
	defer idx.mu.RUnlock()

	if maxsize < 0 {
		return len(idx.entries)
	} else if maxsize == 0 {
		return 0
	}

	for _, entry := range idx.entries {
		if entry != nil && entry.Size <= maxsize {
			count++
		}
	}

	return count
}

// DiskSize tells how much disk space would be used by entries stored in index.
// Only items which size is below provided value are counted. If provided
// argument is negative, this function will count disk size of all items.
func (idx *Index) DiskSize(maxsize int64) (size int64) {
	idx.mu.RLock()
	defer idx.mu.RUnlock()

	if maxsize == 0 {
		return 0
	}

	for _, entry := range idx.entries {
		if entry != nil && (maxsize < 0 || entry.Size <= maxsize) {
			size += entry.Size
		}
	}

	return size
}

// Compare rereads the given file tree roted at root and compares its entries
// to previous state of the index. All detected changes will be stored in
// returned Change slice.
func (idx *Index) Compare(root string) (cs ChangeSlice) {
	visited := make(map[string]struct{})

	// Walk over current root path and check it files.
	walkFn := func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return nil
		}

		name, err := filepath.Rel(root, path)
		if err != nil || name == "." {
			return nil
		}
		name = filepath.ToSlash(name)

		idx.mu.RLock()
		entry, ok := idx.entries[name]
		idx.mu.RUnlock()

		// Not found in current index - file was added.
		if !ok {
			cs = append(cs, Change{
				Name:      name,
				Size:      safeTruncate(info.Size()),
				Meta:      ChangeMetaAdd | markLargeMeta(info.Size()),
				CreatedAt: time.Now().UnixNano(),
			})
			return nil
		}

		// Entry is read only-now. Check for changes.
		visited[name] = struct{}{}
		if entry.MTime != info.ModTime().UnixNano() ||
			entry.CTime != ctime(info) ||
			entry.Size != info.Size() {
			cs = append(cs, Change{
				Name:      name,
				Size:      safeTruncate(info.Size()),
				Meta:      ChangeMetaUpdate | markLargeMeta(info.Size()),
				CreatedAt: time.Now().UnixNano(),
			})
		}

		return nil
	}

	if err := filepath.Walk(root, walkFn); err != nil {
		return nil
	}

	// Check for removes.
	idx.mu.RLock()
	for name := range idx.entries {
		if _, ok := visited[name]; !ok {
			path := filepath.Join(root, filepath.FromSlash(name))
			if _, err := os.Lstat(path); os.IsNotExist(err) {
				cs = append(cs, Change{
					Name:      name,
					Meta:      ChangeMetaRemove | markLargeMeta(idx.entries[name].Size),
					CreatedAt: time.Now().UnixNano(),
				})
			}
		}
	}
	idx.mu.RUnlock()

	return cs
}

// safeTruncate converts signed integer to unsigned one returning 0 for negative
// values of provided argument.
func safeTruncate(n int64) uint32 {
	if n < 0 {
		return 0
	}

	return uint32(n)
}

// markLargeMeta adds large file flag for files which size is over 4GiB.
func markLargeMeta(n int64) ChangeMeta {
	if n < 0 || (n>>32) == 0 {
		return 0
	}

	return ChangeMetaLarge
}

// ctime gets file's change time in UNIX Nano format.
func ctime(fi os.FileInfo) int64 {
	if tspec := times.Get(fi); tspec.HasChangeTime() {
		return tspec.ChangeTime().UnixNano()
	}

	return 0
}

// Apply modifies index according to provided changes. This function doesn't
// guarantee that changes from Compare function applied to the index will
// result in actual directory state.
func (idx *Index) Apply(root string, cs ChangeSlice) {
	var wg sync.WaitGroup

	for i := range cs {
		switch {
		case cs[i].Meta&(ChangeMetaUpdate|ChangeMetaAdd) != 0:
			// Check if the event is still valid or if it was replaced by newer
			// change.
			idx.mu.RLock()
			entry, ok := idx.entries[cs[i].Name]
			idx.mu.RUnlock()

			// Entry was updated/added after the event was created.
			if ok && entry.MTime > cs[i].CreatedAt {
				continue
			}
			fallthrough
		case cs[i].Meta&ChangeMetaRemove != 0:
			// Check if the file still exists, since it could be removed before
			// Apply was called. If the file exists, create new entry from it
			// and replace its value inside index map.
			path := filepath.Join(root, filepath.FromSlash(cs[i].Name))
			info, err := os.Lstat(path)
			if os.IsNotExist(err) {
				idx.mu.Lock()
				delete(idx.entries, cs[i].Name)
				idx.mu.Unlock()
				continue
			}

			wg.Add(1)
			idx.addEntry(&wg, root, path, info)
		}
	}

	wg.Wait()
}

// MarshalJSON satisfies json.Marshaler interface. It safely marshals index
// private data to JSON format.
func (idx *Index) MarshalJSON() ([]byte, error) {
	idx.mu.RLock()
	defer idx.mu.RUnlock()

	return json.Marshal(idx.entries)
}

// UnmarshalJSON satisfies json.Unmarshaler interface. It is used to unmarshal
// data into private index fields.
func (idx *Index) UnmarshalJSON(data []byte) error {
	idx.mu.Lock()
	defer idx.mu.Unlock()

	return json.Unmarshal(data, &idx.entries)
}
<commit_msg>klient/machine: use CRC-32 checksum instead of SHA-1<commit_after>package index

import (
	"encoding/json"
	"hash/crc32"
	"io"
	"os"
	"path/filepath"
	"runtime"
	"sync"
	"time"

	"github.com/djherbis/times"
)

// Version stores current version of index.
const Version = 1

// Entry represents a single file registered to index.
type Entry struct {
	Name  string      `json:"name"`  // The relative name of the file.
	CTime int64       `json:"ctime"` // Metadata change time since EPOCH.
	MTime int64       `json:"mtime"` // File data change time since EPOCH.
	Mode  os.FileMode `json:"mode"`  // File mode and permission bits.
	Size  int64       `json:"size"`  // Size of the file.
	SHA1  []byte      `json:"sha1"`  // SHA-1 hash of file content.
}

// NewEntryFile creates new Entry from a file stored under path argument.
// Info is optional and, if given, should store LStat result on the given file.
func NewEntryFile(root, path string, info os.FileInfo) (e *Entry, err error) {
	if info == nil {
		if info, err = os.Lstat(path); err != nil {
			return nil, err
		}
	}

	// Get relative file name.
	name, err := filepath.Rel(root, path)
	if err != nil {
		return nil, err
	}

	// Compute file's SHA-1 sum.
	var sum []byte
	if !info.IsDir() {
		if sum, err = readCRC32(path); err != nil {
			return nil, err
		}
	}

	return &Entry{
		Name:  filepath.ToSlash(name),
		CTime: ctime(info),
		MTime: info.ModTime().UnixNano(),
		Mode:  info.Mode(),
		Size:  info.Size(),
		SHA1:  sum,
	}, nil
}

// readCRC32 computes CRC-32 checksum of a given file content.
func readCRC32(path string) ([]byte, error) {
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	hash := crc32.NewIEEE()
	if _, err := io.Copy(hash, file); err != nil {
		return nil, err
	}

	return hash.Sum(nil), nil
}

// ChangeMeta indicates what change has been done on a given file.
type ChangeMeta uint32

const (
	ChangeMetaUpdate ChangeMeta = 1 << iota // File was updated.
	ChangeMetaRemove                        // File was removed.
	ChangeMetaAdd                           // File was added.

	ChangeMetaLarge ChangeMeta = 1 << (8 + iota) // File size is above 4GB.
)

// Change describes single file change.
type Change struct {
	Name      string     `json:"name"`      // The relative name of the file.
	Size      uint32     `json:"size"`      // Size of the file truncated to 32 bits.
	Meta      ChangeMeta `json:"meta"`      // The type of operation made on file entry.
	CreatedAt int64      `json:"createdAt"` // Change creation time since EPOCH.
}

// ChangeSlice stores multiple changes.
type ChangeSlice []Change

func (cs ChangeSlice) Len() int           { return len(cs) }
func (cs ChangeSlice) Swap(i, j int)      { cs[i], cs[j] = cs[j], cs[i] }
func (cs ChangeSlice) Less(i, j int) bool { return cs[i].Name < cs[j].Name }

// Index stores a virtual working tree state. It recursively records objects in
// a given root path and allows to efficiently detect changes on it.
type Index struct {
	limitC chan struct{}

	mu      sync.RWMutex
	entries map[string]*Entry
}

var (
	_ json.Marshaler   = (*Index)(nil)
	_ json.Unmarshaler = (*Index)(nil)
)

// NewIndex creates the empty index object.
func NewIndex() *Index {
	return &Index{
		limitC:  make(chan struct{}, 2*runtime.NumCPU()),
		entries: make(map[string]*Entry, 0),
	}
}

// NewIndexFiles walks the given file tree roted at root and records file
// states to resulting Index object.
func NewIndexFiles(root string) (*Index, error) {
	idx := NewIndex()

	// In order to get as much entries as we can we ignore errors.
	var wg sync.WaitGroup
	walkFn := func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return nil
		}

		// Skip root path.
		if name, err := filepath.Rel(root, path); err != nil || name == "." {
			return nil
		}

		wg.Add(1)
		idx.addEntry(&wg, root, path, info)
		return nil
	}

	if err := filepath.Walk(root, walkFn); err != nil {
		return nil, err
	}

	wg.Wait()
	return idx, nil
}

// addEntry asynchronously adds new entry to index. This function has limits
// to a number of started go-routines. Errors are ignored.
func (idx *Index) addEntry(wg *sync.WaitGroup, root, path string, info os.FileInfo) {
	idx.limitC <- struct{}{}

	go func() {
		defer func() {
			<-idx.limitC
			wg.Done()
		}()

		entry, err := NewEntryFile(root, path, info)
		if err != nil {
			return
		}

		idx.mu.Lock()
		idx.entries[entry.Name] = entry
		idx.mu.Unlock()
	}()
}

// Count returns the number of entries stored in index. Only items which size is
// below provided value are counted. If provided argument is negative, this
// function will return the number of all entries.
func (idx *Index) Count(maxsize int64) (count int) {
	idx.mu.RLock()
	defer idx.mu.RUnlock()

	if maxsize < 0 {
		return len(idx.entries)
	} else if maxsize == 0 {
		return 0
	}

	for _, entry := range idx.entries {
		if entry != nil && entry.Size <= maxsize {
			count++
		}
	}

	return count
}

// DiskSize tells how much disk space would be used by entries stored in index.
// Only items which size is below provided value are counted. If provided
// argument is negative, this function will count disk size of all items.
func (idx *Index) DiskSize(maxsize int64) (size int64) {
	idx.mu.RLock()
	defer idx.mu.RUnlock()

	if maxsize == 0 {
		return 0
	}

	for _, entry := range idx.entries {
		if entry != nil && (maxsize < 0 || entry.Size <= maxsize) {
			size += entry.Size
		}
	}

	return size
}

// Compare rereads the given file tree roted at root and compares its entries
// to previous state of the index. All detected changes will be stored in
// returned Change slice.
func (idx *Index) Compare(root string) (cs ChangeSlice) {
	visited := make(map[string]struct{})

	// Walk over current root path and check it files.
	walkFn := func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return nil
		}

		name, err := filepath.Rel(root, path)
		if err != nil || name == "." {
			return nil
		}
		name = filepath.ToSlash(name)

		idx.mu.RLock()
		entry, ok := idx.entries[name]
		idx.mu.RUnlock()

		// Not found in current index - file was added.
		if !ok {
			cs = append(cs, Change{
				Name:      name,
				Size:      safeTruncate(info.Size()),
				Meta:      ChangeMetaAdd | markLargeMeta(info.Size()),
				CreatedAt: time.Now().UnixNano(),
			})
			return nil
		}

		// Entry is read only-now. Check for changes.
		visited[name] = struct{}{}
		if entry.MTime != info.ModTime().UnixNano() ||
			entry.CTime != ctime(info) ||
			entry.Size != info.Size() {
			cs = append(cs, Change{
				Name:      name,
				Size:      safeTruncate(info.Size()),
				Meta:      ChangeMetaUpdate | markLargeMeta(info.Size()),
				CreatedAt: time.Now().UnixNano(),
			})
		}

		return nil
	}

	if err := filepath.Walk(root, walkFn); err != nil {
		return nil
	}

	// Check for removes.
	idx.mu.RLock()
	for name := range idx.entries {
		if _, ok := visited[name]; !ok {
			path := filepath.Join(root, filepath.FromSlash(name))
			if _, err := os.Lstat(path); os.IsNotExist(err) {
				cs = append(cs, Change{
					Name:      name,
					Meta:      ChangeMetaRemove | markLargeMeta(idx.entries[name].Size),
					CreatedAt: time.Now().UnixNano(),
				})
			}
		}
	}
	idx.mu.RUnlock()

	return cs
}

// safeTruncate converts signed integer to unsigned one returning 0 for negative
// values of provided argument.
func safeTruncate(n int64) uint32 {
	if n < 0 {
		return 0
	}

	return uint32(n)
}

// markLargeMeta adds large file flag for files which size is over 4GiB.
func markLargeMeta(n int64) ChangeMeta {
	if n < 0 || (n>>32) == 0 {
		return 0
	}

	return ChangeMetaLarge
}

// ctime gets file's change time in UNIX Nano format.
func ctime(fi os.FileInfo) int64 {
	if tspec := times.Get(fi); tspec.HasChangeTime() {
		return tspec.ChangeTime().UnixNano()
	}

	return 0
}

// Apply modifies index according to provided changes. This function doesn't
// guarantee that changes from Compare function applied to the index will
// result in actual directory state.
func (idx *Index) Apply(root string, cs ChangeSlice) {
	var wg sync.WaitGroup

	for i := range cs {
		switch {
		case cs[i].Meta&(ChangeMetaUpdate|ChangeMetaAdd) != 0:
			// Check if the event is still valid or if it was replaced by newer
			// change.
			idx.mu.RLock()
			entry, ok := idx.entries[cs[i].Name]
			idx.mu.RUnlock()

			// Entry was updated/added after the event was created.
			if ok && entry.MTime > cs[i].CreatedAt {
				continue
			}
			fallthrough
		case cs[i].Meta&ChangeMetaRemove != 0:
			// Check if the file still exists, since it could be removed before
			// Apply was called. If the file exists, create new entry from it
			// and replace its value inside index map.
			path := filepath.Join(root, filepath.FromSlash(cs[i].Name))
			info, err := os.Lstat(path)
			if os.IsNotExist(err) {
				idx.mu.Lock()
				delete(idx.entries, cs[i].Name)
				idx.mu.Unlock()
				continue
			}

			wg.Add(1)
			idx.addEntry(&wg, root, path, info)
		}
	}

	wg.Wait()
}

// MarshalJSON satisfies json.Marshaler interface. It safely marshals index
// private data to JSON format.
func (idx *Index) MarshalJSON() ([]byte, error) {
	idx.mu.RLock()
	defer idx.mu.RUnlock()

	return json.Marshal(idx.entries)
}

// UnmarshalJSON satisfies json.Unmarshaler interface. It is used to unmarshal
// data into private index fields.
func (idx *Index) UnmarshalJSON(data []byte) error {
	idx.mu.Lock()
	defer idx.mu.Unlock()

	return json.Unmarshal(data, &idx.entries)
}
<|endoftext|>


<commit_before>// ----------------------------------------------------------------------------
//
//     ***     AUTO GENERATED CODE    ***    AUTO GENERATED CODE     ***
//
// ----------------------------------------------------------------------------
//
//     This file is automatically generated by Magic Modules and manual
//     changes will be clobbered when the file is regenerated.
//
//     Please read more about how to change this file in
//     .github/CONTRIBUTING.md.
//
// ----------------------------------------------------------------------------

package google

import "reflect"

func GetAccessContextManagerAccessLevelCaiObject(d TerraformResourceData, config *Config) (Asset, error) {
	name, err := assetName(d, config, "//accesscontextmanager.googleapis.com/{{name}}")
	if err != nil {
		return Asset{}, err
	}
	if obj, err := GetAccessContextManagerAccessLevelApiObject(d, config); err == nil {
		return Asset{
			Name: name,
			Type: "accesscontextmanager.googleapis.com/AccessLevel",
			Resource: &AssetResource{
				Version:              "v1",
				DiscoveryDocumentURI: "https://www.googleapis.com/discovery/v1/apis/accesscontextmanager/v1/rest",
				DiscoveryName:        "AccessLevel",
				Data:                 obj,
			},
		}, nil
	} else {
		return Asset{}, err
	}
}

func GetAccessContextManagerAccessLevelApiObject(d TerraformResourceData, config *Config) (map[string]interface{}, error) {
	obj := make(map[string]interface{})
	titleProp, err := expandAccessContextManagerAccessLevelTitle(d.Get("title"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("title"); !isEmptyValue(reflect.ValueOf(titleProp)) && (ok || !reflect.DeepEqual(v, titleProp)) {
		obj["title"] = titleProp
	}
	descriptionProp, err := expandAccessContextManagerAccessLevelDescription(d.Get("description"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) {
		obj["description"] = descriptionProp
	}
	basicProp, err := expandAccessContextManagerAccessLevelBasic(d.Get("basic"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("basic"); !isEmptyValue(reflect.ValueOf(basicProp)) && (ok || !reflect.DeepEqual(v, basicProp)) {
		obj["basic"] = basicProp
	}
	parentProp, err := expandAccessContextManagerAccessLevelParent(d.Get("parent"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("parent"); !isEmptyValue(reflect.ValueOf(parentProp)) && (ok || !reflect.DeepEqual(v, parentProp)) {
		obj["parent"] = parentProp
	}
	nameProp, err := expandAccessContextManagerAccessLevelName(d.Get("name"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) {
		obj["name"] = nameProp
	}

	return resourceAccessContextManagerAccessLevelEncoder(d, config, obj)
}

func resourceAccessContextManagerAccessLevelEncoder(d TerraformResourceData, meta interface{}, obj map[string]interface{}) (map[string]interface{}, error) {
	delete(obj, "parent")
	return obj, nil
}

func expandAccessContextManagerAccessLevelTitle(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelDescription(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelBasic(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	l := v.([]interface{})
	if len(l) == 0 || l[0] == nil {
		return nil, nil
	}
	raw := l[0]
	original := raw.(map[string]interface{})
	transformed := make(map[string]interface{})

	transformedCombiningFunction, err := expandAccessContextManagerAccessLevelBasicCombiningFunction(original["combining_function"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedCombiningFunction); val.IsValid() && !isEmptyValue(val) {
		transformed["combiningFunction"] = transformedCombiningFunction
	}

	transformedConditions, err := expandAccessContextManagerAccessLevelBasicConditions(original["conditions"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedConditions); val.IsValid() && !isEmptyValue(val) {
		transformed["conditions"] = transformedConditions
	}

	return transformed, nil
}

func expandAccessContextManagerAccessLevelBasicCombiningFunction(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelBasicConditions(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	l := v.([]interface{})
	req := make([]interface{}, 0, len(l))
	for _, raw := range l {
		if raw == nil {
			continue
		}
		original := raw.(map[string]interface{})
		transformed := make(map[string]interface{})

		transformedIpSubnetworks, err := expandAccessContextManagerAccessLevelBasicConditionsIpSubnetworks(original["ip_subnetworks"], d, config)
		if err != nil {
			return nil, err
		} else if val := reflect.ValueOf(transformedIpSubnetworks); val.IsValid() && !isEmptyValue(val) {
			transformed["ipSubnetworks"] = transformedIpSubnetworks
		}

		transformedRequiredAccessLevels, err := expandAccessContextManagerAccessLevelBasicConditionsRequiredAccessLevels(original["required_access_levels"], d, config)
		if err != nil {
			return nil, err
		} else if val := reflect.ValueOf(transformedRequiredAccessLevels); val.IsValid() && !isEmptyValue(val) {
			transformed["requiredAccessLevels"] = transformedRequiredAccessLevels
		}

		transformedMembers, err := expandAccessContextManagerAccessLevelBasicConditionsMembers(original["members"], d, config)
		if err != nil {
			return nil, err
		} else if val := reflect.ValueOf(transformedMembers); val.IsValid() && !isEmptyValue(val) {
			transformed["members"] = transformedMembers
		}

		transformedNegate, err := expandAccessContextManagerAccessLevelBasicConditionsNegate(original["negate"], d, config)
		if err != nil {
			return nil, err
		} else if val := reflect.ValueOf(transformedNegate); val.IsValid() && !isEmptyValue(val) {
			transformed["negate"] = transformedNegate
		}

		transformedDevicePolicy, err := expandAccessContextManagerAccessLevelBasicConditionsDevicePolicy(original["device_policy"], d, config)
		if err != nil {
			return nil, err
		} else if val := reflect.ValueOf(transformedDevicePolicy); val.IsValid() && !isEmptyValue(val) {
			transformed["devicePolicy"] = transformedDevicePolicy
		}

		req = append(req, transformed)
	}
	return req, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsIpSubnetworks(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsRequiredAccessLevels(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsMembers(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsNegate(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsDevicePolicy(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	l := v.([]interface{})
	if len(l) == 0 || l[0] == nil {
		return nil, nil
	}
	raw := l[0]
	original := raw.(map[string]interface{})
	transformed := make(map[string]interface{})

	transformedRequireScreenLock, err := expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyRequireScreenLock(original["require_screen_lock"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedRequireScreenLock); val.IsValid() && !isEmptyValue(val) {
		transformed["requireScreenLock"] = transformedRequireScreenLock
	}

	transformedAllowedEncryptionStatuses, err := expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyAllowedEncryptionStatuses(original["allowed_encryption_statuses"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedAllowedEncryptionStatuses); val.IsValid() && !isEmptyValue(val) {
		transformed["allowedEncryptionStatuses"] = transformedAllowedEncryptionStatuses
	}

	transformedAllowedDeviceManagementLevels, err := expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyAllowedDeviceManagementLevels(original["allowed_device_management_levels"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedAllowedDeviceManagementLevels); val.IsValid() && !isEmptyValue(val) {
		transformed["allowedDeviceManagementLevels"] = transformedAllowedDeviceManagementLevels
	}

	transformedOsConstraints, err := expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyOsConstraints(original["os_constraints"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedOsConstraints); val.IsValid() && !isEmptyValue(val) {
		transformed["osConstraints"] = transformedOsConstraints
	}

	return transformed, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyRequireScreenLock(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyAllowedEncryptionStatuses(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyAllowedDeviceManagementLevels(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyOsConstraints(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	l := v.([]interface{})
	req := make([]interface{}, 0, len(l))
	for _, raw := range l {
		if raw == nil {
			continue
		}
		original := raw.(map[string]interface{})
		transformed := make(map[string]interface{})

		transformedMinimumVersion, err := expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyOsConstraintsMinimumVersion(original["minimum_version"], d, config)
		if err != nil {
			return nil, err
		} else if val := reflect.ValueOf(transformedMinimumVersion); val.IsValid() && !isEmptyValue(val) {
			transformed["minimumVersion"] = transformedMinimumVersion
		}

		transformedOsType, err := expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyOsConstraintsOsType(original["os_type"], d, config)
		if err != nil {
			return nil, err
		} else if val := reflect.ValueOf(transformedOsType); val.IsValid() && !isEmptyValue(val) {
			transformed["osType"] = transformedOsType
		}

		req = append(req, transformed)
	}
	return req, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyOsConstraintsMinimumVersion(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyOsConstraintsOsType(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelParent(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}
<commit_msg>requireAdminApproval/requireCorpOwned in AccessLevel's devicePolicy<commit_after>// ----------------------------------------------------------------------------
//
//     ***     AUTO GENERATED CODE    ***    AUTO GENERATED CODE     ***
//
// ----------------------------------------------------------------------------
//
//     This file is automatically generated by Magic Modules and manual
//     changes will be clobbered when the file is regenerated.
//
//     Please read more about how to change this file in
//     .github/CONTRIBUTING.md.
//
// ----------------------------------------------------------------------------

package google

import "reflect"

func GetAccessContextManagerAccessLevelCaiObject(d TerraformResourceData, config *Config) (Asset, error) {
	name, err := assetName(d, config, "//accesscontextmanager.googleapis.com/{{name}}")
	if err != nil {
		return Asset{}, err
	}
	if obj, err := GetAccessContextManagerAccessLevelApiObject(d, config); err == nil {
		return Asset{
			Name: name,
			Type: "accesscontextmanager.googleapis.com/AccessLevel",
			Resource: &AssetResource{
				Version:              "v1",
				DiscoveryDocumentURI: "https://www.googleapis.com/discovery/v1/apis/accesscontextmanager/v1/rest",
				DiscoveryName:        "AccessLevel",
				Data:                 obj,
			},
		}, nil
	} else {
		return Asset{}, err
	}
}

func GetAccessContextManagerAccessLevelApiObject(d TerraformResourceData, config *Config) (map[string]interface{}, error) {
	obj := make(map[string]interface{})
	titleProp, err := expandAccessContextManagerAccessLevelTitle(d.Get("title"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("title"); !isEmptyValue(reflect.ValueOf(titleProp)) && (ok || !reflect.DeepEqual(v, titleProp)) {
		obj["title"] = titleProp
	}
	descriptionProp, err := expandAccessContextManagerAccessLevelDescription(d.Get("description"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) {
		obj["description"] = descriptionProp
	}
	basicProp, err := expandAccessContextManagerAccessLevelBasic(d.Get("basic"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("basic"); !isEmptyValue(reflect.ValueOf(basicProp)) && (ok || !reflect.DeepEqual(v, basicProp)) {
		obj["basic"] = basicProp
	}
	parentProp, err := expandAccessContextManagerAccessLevelParent(d.Get("parent"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("parent"); !isEmptyValue(reflect.ValueOf(parentProp)) && (ok || !reflect.DeepEqual(v, parentProp)) {
		obj["parent"] = parentProp
	}
	nameProp, err := expandAccessContextManagerAccessLevelName(d.Get("name"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) {
		obj["name"] = nameProp
	}

	return resourceAccessContextManagerAccessLevelEncoder(d, config, obj)
}

func resourceAccessContextManagerAccessLevelEncoder(d TerraformResourceData, meta interface{}, obj map[string]interface{}) (map[string]interface{}, error) {
	delete(obj, "parent")
	return obj, nil
}

func expandAccessContextManagerAccessLevelTitle(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelDescription(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelBasic(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	l := v.([]interface{})
	if len(l) == 0 || l[0] == nil {
		return nil, nil
	}
	raw := l[0]
	original := raw.(map[string]interface{})
	transformed := make(map[string]interface{})

	transformedCombiningFunction, err := expandAccessContextManagerAccessLevelBasicCombiningFunction(original["combining_function"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedCombiningFunction); val.IsValid() && !isEmptyValue(val) {
		transformed["combiningFunction"] = transformedCombiningFunction
	}

	transformedConditions, err := expandAccessContextManagerAccessLevelBasicConditions(original["conditions"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedConditions); val.IsValid() && !isEmptyValue(val) {
		transformed["conditions"] = transformedConditions
	}

	return transformed, nil
}

func expandAccessContextManagerAccessLevelBasicCombiningFunction(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelBasicConditions(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	l := v.([]interface{})
	req := make([]interface{}, 0, len(l))
	for _, raw := range l {
		if raw == nil {
			continue
		}
		original := raw.(map[string]interface{})
		transformed := make(map[string]interface{})

		transformedIpSubnetworks, err := expandAccessContextManagerAccessLevelBasicConditionsIpSubnetworks(original["ip_subnetworks"], d, config)
		if err != nil {
			return nil, err
		} else if val := reflect.ValueOf(transformedIpSubnetworks); val.IsValid() && !isEmptyValue(val) {
			transformed["ipSubnetworks"] = transformedIpSubnetworks
		}

		transformedRequiredAccessLevels, err := expandAccessContextManagerAccessLevelBasicConditionsRequiredAccessLevels(original["required_access_levels"], d, config)
		if err != nil {
			return nil, err
		} else if val := reflect.ValueOf(transformedRequiredAccessLevels); val.IsValid() && !isEmptyValue(val) {
			transformed["requiredAccessLevels"] = transformedRequiredAccessLevels
		}

		transformedMembers, err := expandAccessContextManagerAccessLevelBasicConditionsMembers(original["members"], d, config)
		if err != nil {
			return nil, err
		} else if val := reflect.ValueOf(transformedMembers); val.IsValid() && !isEmptyValue(val) {
			transformed["members"] = transformedMembers
		}

		transformedNegate, err := expandAccessContextManagerAccessLevelBasicConditionsNegate(original["negate"], d, config)
		if err != nil {
			return nil, err
		} else if val := reflect.ValueOf(transformedNegate); val.IsValid() && !isEmptyValue(val) {
			transformed["negate"] = transformedNegate
		}

		transformedDevicePolicy, err := expandAccessContextManagerAccessLevelBasicConditionsDevicePolicy(original["device_policy"], d, config)
		if err != nil {
			return nil, err
		} else if val := reflect.ValueOf(transformedDevicePolicy); val.IsValid() && !isEmptyValue(val) {
			transformed["devicePolicy"] = transformedDevicePolicy
		}

		req = append(req, transformed)
	}
	return req, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsIpSubnetworks(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsRequiredAccessLevels(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsMembers(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsNegate(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsDevicePolicy(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	l := v.([]interface{})
	if len(l) == 0 || l[0] == nil {
		return nil, nil
	}
	raw := l[0]
	original := raw.(map[string]interface{})
	transformed := make(map[string]interface{})

	transformedRequireScreenLock, err := expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyRequireScreenLock(original["require_screen_lock"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedRequireScreenLock); val.IsValid() && !isEmptyValue(val) {
		transformed["requireScreenLock"] = transformedRequireScreenLock
	}

	transformedAllowedEncryptionStatuses, err := expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyAllowedEncryptionStatuses(original["allowed_encryption_statuses"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedAllowedEncryptionStatuses); val.IsValid() && !isEmptyValue(val) {
		transformed["allowedEncryptionStatuses"] = transformedAllowedEncryptionStatuses
	}

	transformedAllowedDeviceManagementLevels, err := expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyAllowedDeviceManagementLevels(original["allowed_device_management_levels"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedAllowedDeviceManagementLevels); val.IsValid() && !isEmptyValue(val) {
		transformed["allowedDeviceManagementLevels"] = transformedAllowedDeviceManagementLevels
	}

	transformedOsConstraints, err := expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyOsConstraints(original["os_constraints"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedOsConstraints); val.IsValid() && !isEmptyValue(val) {
		transformed["osConstraints"] = transformedOsConstraints
	}

	transformedRequireAdminApproval, err := expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyRequireAdminApproval(original["require_admin_approval"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedRequireAdminApproval); val.IsValid() && !isEmptyValue(val) {
		transformed["requireAdminApproval"] = transformedRequireAdminApproval
	}

	transformedRequireCorpOwned, err := expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyRequireCorpOwned(original["require_corp_owned"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedRequireCorpOwned); val.IsValid() && !isEmptyValue(val) {
		transformed["requireCorpOwned"] = transformedRequireCorpOwned
	}

	return transformed, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyRequireScreenLock(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyAllowedEncryptionStatuses(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyAllowedDeviceManagementLevels(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyOsConstraints(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	l := v.([]interface{})
	req := make([]interface{}, 0, len(l))
	for _, raw := range l {
		if raw == nil {
			continue
		}
		original := raw.(map[string]interface{})
		transformed := make(map[string]interface{})

		transformedMinimumVersion, err := expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyOsConstraintsMinimumVersion(original["minimum_version"], d, config)
		if err != nil {
			return nil, err
		} else if val := reflect.ValueOf(transformedMinimumVersion); val.IsValid() && !isEmptyValue(val) {
			transformed["minimumVersion"] = transformedMinimumVersion
		}

		transformedOsType, err := expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyOsConstraintsOsType(original["os_type"], d, config)
		if err != nil {
			return nil, err
		} else if val := reflect.ValueOf(transformedOsType); val.IsValid() && !isEmptyValue(val) {
			transformed["osType"] = transformedOsType
		}

		req = append(req, transformed)
	}
	return req, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyOsConstraintsMinimumVersion(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyOsConstraintsOsType(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyRequireAdminApproval(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelBasicConditionsDevicePolicyRequireCorpOwned(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelParent(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandAccessContextManagerAccessLevelName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}
<|endoftext|>