<commit_before>package packager

import(
	tp "tritium/proto"
	proto "goprotobuf.googlecode.com/hg/proto"
	api "tritium/api"
	"strings"
	"path/filepath"
	"log4go"
	"os"
)

type Package struct {
	loaded []*PackageInfo
	location string
	LoadPath string
	FallbackPath string
	OutputFile string
	Log log4go.Logger
	*tp.Package
	Options PackageOptions
}

type PackageInfo struct {
	Name string
	Dependencies []string
	Types []string
}

var DefaultPackagePath = "packages"

func LoadDefaultPackage(path *string) (*Package) {
	if path == nil {
		if os.ShellExpand("$TRITIUM_PACKAGES") != "" {
			DefaultPackagePath = os.ShellExpand("$TRITIUM_PACKAGES")
		}
		path = &DefaultPackagePath
	}

	return buildPackage(*path, nil)
}

func OutputDefaultPackage(path string) (pkg *Package, newFilePath string) {
	pkg = BuildDefaultPackage()

	_, err := os.Stat(path)

	if err != nil {
		creationErr := os.MkdirAll(path, uint32(0777) )
		if creationErr != nil {
			panic("Could not make path(" + path + "). Error:" + creationErr.String())
		}
	}

	_, name := filepath.Split(pkg.OutputFile)
	newOutputFile := filepath.Join(path, name)

	os.Rename(pkg.OutputFile, newOutputFile)

	return pkg, newOutputFile
}

func BuildDefaultPackage() (*Package) {
	options := BuildOptions()
	return buildPackage(DefaultPackagePath, options)
}

func buildPackage(path string, options PackageOptions) (*Package) {
	// Terrible directory handling here... has to be executed from Tritium root

	pkg := NewPackage(path, options)
	pkg.Load("libxml")

	return pkg
}

func mergeOptions(options PackageOptions) PackageOptions {
	defaults := fetchDefaultOptions()

	if options == nil {
		return defaults
	}

	for k, _ := range defaults {
		_, ok := options[k]

		if !ok {
			options[k] = defaults[k]
		}
	}

	return options
}

func NewPackage(loadPath string, options PackageOptions) (*Package){
	options = mergeOptions(options)

	return &Package{
		Package: &tp.Package{
			Name: proto.String("combined"),
			Functions: make([]*tp.Function, 0),
			Types: make([]*tp.Type, 0),
		},
		loaded: make([]*PackageInfo, 0),
  	        Log: newLog(),
		LoadPath: loadPath,
	        Options: options,
	}
}

func (pkg *Package) BuildUserPackage(loadPath *string, fallbackPath *string) {
	userPackage := NewUserPackage(loadPath, fallbackPath)
	pkg.Merge(userPackage.Package)
}

func NewUserPackage(loadPath *string, fallbackPath *string) (*Package) {
	//TODO : Check for user-defined feature support

	userPackage := NewPackage(*loadPath, PackageOptions{"stdout" : false,"output_tpkg" : false,"use_tpkg" : false})

	userPackage.FallbackPath = *fallbackPath

	userPackages, _ := filepath.Glob(filepath.Join(userPackage.LoadPath, "*"))

	for _, path := range(userPackages) {
		components := strings.Split(path, "/")
		name := components[len(components)-1]
		userPackage.Load(name)
	}

	return userPackage
}

func newLog() (log4go.Logger) {
	pkgLog := make(log4go.Logger)
	os.Mkdir("tmp", uint32(0777) )

	pkgLog.AddFilter("file", log4go.FINE, log4go.NewFileLogWriter("tmp/packager.log", false))
	return pkgLog
}

func (pkg *Package)Load(packageName string) {

	user := api.FetchSessionUser()
	approved := user.RequestFeature("package:" + packageName)

	if !approved {
		panic("Package " + packageName + " not approved for use.")
	}

	err := pkg.loadFromPath(pkg.LoadPath, packageName)

	if err != nil && len(pkg.FallbackPath) != 0 {
		err = pkg.loadFromPath(pkg.FallbackPath, packageName)
	}

	if err != nil {
		panic(*err)
	}

}

func (pkg *Package)loadFromPath(path string, name string) (err *string) {
	pkg.Println(path + ":" + name)
	pkg.Log.Info("\n\n\n\nLoading:%v", path + ":" + name)

	if pkg.Options["use_tpkg"] {
		pkg.open(path, name)
		return nil
	}

	location := filepath.Join(path, name)

	old_location := pkg.location
	pkg.location = location
	info, err := readPackageInfoFile(location)

	if err != nil {
		return err
	}

	if len(info.Dependencies) > 0 {

		for _, dependency := range(info.Dependencies) {
			pkg.loadPackageDependency(dependency)
		}

	}

	for _, typeName := range(info.Types) {
		split := strings.Split(typeName, " < ")
		typeObj := &tp.Type{}
		if len(split) == 2 {
			typeName = split[0]
			index := pkg.findTypeIndex(split[1])

			typeObj.Implements = proto.Int32(int32(index))
		}
		typeObj.Name = proto.String(typeName)
		pkg.Types = append(pkg.Types, typeObj)
	}

	pkg.readHeaderFile(location)

	pkg.readPackageDefinitions(location)

	pkg.inheritFunctions()

	if pkg.Options["output_tpkg"] {
		pkg.write()
	}

	pkg.Println(" -- done")
	pkg.Log.Close()

	// TODO(SJ) : Kind of lame. Ideally I think we load other packages as whole packages and write a *.Merge method
	pkg.location = old_location

	return nil
}

<commit_msg>I'll leave this to Sean...<commit_after>package packager

import(
	tp "tritium/proto"
	proto "goprotobuf.googlecode.com/hg/proto"
	api "tritium/api"
	"strings"
	"path/filepath"
	"log4go"
	"os"
)

type Package struct {
	loaded []*PackageInfo
	location string
	LoadPath string
	FallbackPath string
	OutputFile string
	Log log4go.Logger
	*tp.Package
	Options PackageOptions
}

type PackageInfo struct {
	Name string
	Dependencies []string
	Types []string
}

var DefaultPackagePath = "packages"

func LoadDefaultPackage(path *string) (*Package) {
	if path == nil {
		path = &DefaultPackagePath
	}

	return buildPackage(*path, nil)
}

func OutputDefaultPackage(path string) (pkg *Package, newFilePath string) {
	pkg = BuildDefaultPackage()

	_, err := os.Stat(path)

	if err != nil {
		creationErr := os.MkdirAll(path, uint32(0777) )
		if creationErr != nil {
			panic("Could not make path(" + path + "). Error:" + creationErr.String())
		}
	}

	_, name := filepath.Split(pkg.OutputFile)
	newOutputFile := filepath.Join(path, name)

	os.Rename(pkg.OutputFile, newOutputFile)

	return pkg, newOutputFile
}

func BuildDefaultPackage() (*Package) {
	options := BuildOptions()
	return buildPackage(DefaultPackagePath, options)
}

func buildPackage(path string, options PackageOptions) (*Package) {
	// Terrible directory handling here... has to be executed from Tritium root

	pkg := NewPackage(path, options)
	pkg.Load("libxml")

	return pkg
}

func mergeOptions(options PackageOptions) PackageOptions {
	defaults := fetchDefaultOptions()

	if options == nil {
		return defaults
	}

	for k, _ := range defaults {
		_, ok := options[k]

		if !ok {
			options[k] = defaults[k]
		}
	}

	return options
}

func NewPackage(loadPath string, options PackageOptions) (*Package){
	options = mergeOptions(options)

	return &Package{
		Package: &tp.Package{
			Name: proto.String("combined"),
			Functions: make([]*tp.Function, 0),
			Types: make([]*tp.Type, 0),
		},
		loaded: make([]*PackageInfo, 0),
  	        Log: newLog(),
		LoadPath: loadPath,
	        Options: options,
	}
}

func (pkg *Package) BuildUserPackage(loadPath *string, fallbackPath *string) {
	userPackage := NewUserPackage(loadPath, fallbackPath)
	pkg.Merge(userPackage.Package)
}

func NewUserPackage(loadPath *string, fallbackPath *string) (*Package) {
	//TODO : Check for user-defined feature support

	userPackage := NewPackage(*loadPath, PackageOptions{"stdout" : false,"output_tpkg" : false,"use_tpkg" : false})

	userPackage.FallbackPath = *fallbackPath

	userPackages, _ := filepath.Glob(filepath.Join(userPackage.LoadPath, "*"))

	for _, path := range(userPackages) {
		components := strings.Split(path, "/")
		name := components[len(components)-1]
		userPackage.Load(name)
	}

	return userPackage
}

func newLog() (log4go.Logger) {
	pkgLog := make(log4go.Logger)
	os.Mkdir("tmp", uint32(0777) )

	pkgLog.AddFilter("file", log4go.FINE, log4go.NewFileLogWriter("tmp/packager.log", false))
	return pkgLog
}

func (pkg *Package)Load(packageName string) {

	user := api.FetchSessionUser()
	approved := user.RequestFeature("package:" + packageName)

	if !approved {
		panic("Package " + packageName + " not approved for use.")
	}

	err := pkg.loadFromPath(pkg.LoadPath, packageName)

	if err != nil && len(pkg.FallbackPath) != 0 {
		err = pkg.loadFromPath(pkg.FallbackPath, packageName)
	}

	if err != nil {
		panic(*err)
	}

}

func (pkg *Package)loadFromPath(path string, name string) (err *string) {
	pkg.Println(path + ":" + name)
	pkg.Log.Info("\n\n\n\nLoading:%v", path + ":" + name)

	if pkg.Options["use_tpkg"] {
		pkg.open(path, name)
		return nil
	}

	location := filepath.Join(path, name)

	old_location := pkg.location
	pkg.location = location
	info, err := readPackageInfoFile(location)

	if err != nil {
		return err
	}

	if len(info.Dependencies) > 0 {

		for _, dependency := range(info.Dependencies) {
			pkg.loadPackageDependency(dependency)
		}

	}

	for _, typeName := range(info.Types) {
		split := strings.Split(typeName, " < ")
		typeObj := &tp.Type{}
		if len(split) == 2 {
			typeName = split[0]
			index := pkg.findTypeIndex(split[1])

			typeObj.Implements = proto.Int32(int32(index))
		}
		typeObj.Name = proto.String(typeName)
		pkg.Types = append(pkg.Types, typeObj)
	}

	pkg.readHeaderFile(location)

	pkg.readPackageDefinitions(location)

	pkg.inheritFunctions()

	if pkg.Options["output_tpkg"] {
		pkg.write()
	}

	pkg.Println(" -- done")
	pkg.Log.Close()

	// TODO(SJ) : Kind of lame. Ideally I think we load other packages as whole packages and write a *.Merge method
	pkg.location = old_location

	return nil
}

<|endoftext|>


<commit_before>package importing

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	_ "github.com/mattn/go-sqlite3"
	"io"
	"os"
)

type ImportDb struct {
	requireRebuild bool
	dsn            string
	db             *sql.DB

	OpenDb               func(dsn string) (*sql.DB, error)
	Db                   func() (*sql.DB, error)
	SetIgnoreForeignKeys func(ignore bool) error
}

func (i ImportDb) RequireRebuild() bool {
	return i.requireRebuild
}

func Connect(dbType, dsn string) (*ImportDb, error) {
	var db ImportDb
	switch dbType {
	case "sqlite3":
		db.OpenDb = func(dsn string) (*sql.DB, error) {
			db.dsn = dsn
			dbFileInfo, err := os.Stat(dsn)
			if err != nil && !os.IsNotExist(err) {
				return nil, fmt.Errorf("Error on stat db: %v", err)
			}
			// force rebuild on new db
			if os.IsNotExist(err) {
				db.requireRebuild = true
			} else {
				if dbFileInfo.IsDir() {
					return nil, fmt.Errorf("Db is a directory.")
				}
			}
			sqlite, err := sql.Open("sqlite3", dsn)
			if err != nil {
				return nil, fmt.Errorf("Error opening db: %v", err)
			}
			return sqlite, err
		}
		db.Db = func() (*sql.DB, error) {
			return sql.Open("sqlite3", "file:"+db.dsn+"?cache=shared")
		}
		db.SetIgnoreForeignKeys = func(ignore bool) error {
			return nil
		}
	case "mysql":
		db.OpenDb = func(dsn string) (*sql.DB, error) {
			var err error
			db.dsn = dsn
			db.db, err = sql.Open("mysql", dsn)
			if err != nil {
				return nil, fmt.Errorf("Error connecting to MySQL: %v", err)
			}
			return db.db, nil
		}
		db.Db = func() (*sql.DB, error) {
			if db.db == nil {
				return nil, fmt.Errorf("No MySQL connection. Call OpenDb() first.")
			}
			return db.db, nil
		}
		db.SetIgnoreForeignKeys = func(ignore bool) error {
			if db.db == nil {
				return fmt.Errorf("No MySQL connection. Call OpenDb() first.")
			}
			if ignore {
				_, err := db.db.Exec("SET FOREIGN_KEY_CHECKS=0")
				if err != nil {
					return fmt.Errorf("Error ignoring foreign keys: %v", err)
				}
			} else {
				_, err := db.db.Exec("SET FOREIGN_KEY_CHECKS=1")
				if err != nil {
					return fmt.Errorf("Error set foreign keys: %v", err)
				}
			}
			return nil
		}
	default:
		return nil, fmt.Errorf("Invalid db type: %s", dbType)
	}
	return &db, nil
}

func BackupDb(fileName string) error {
	info, err := os.Stat(fileName)
	if err != nil && !os.IsNotExist(err) {
		return fmt.Errorf("Error backing up db stat: %v", err)
	}
	if os.IsNotExist(err) {
		return nil
	}
	if info.IsDir() {
		return fmt.Errorf("DB file is a directory. Cannot continue.")
	}
	orig, err := os.Open(fileName)
	if err != nil {
		return fmt.Errorf("Could not open db: %v", err)
	}
	defer orig.Close()
	bak, err := os.Create(fileName + ".bak")
	if err != nil {
		return fmt.Errorf("Error creating backup file: %v", err)
	}
	defer bak.Close()
	_, err = io.Copy(bak, orig)
	return nil
}
<commit_msg>sqlite3 PRAGMA for foreign keys<commit_after>package importing

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	_ "github.com/mattn/go-sqlite3"
	"io"
	"os"
)

type ImportDb struct {
	requireRebuild bool
	dsn            string
	db             *sql.DB

	OpenDb               func(dsn string) (*sql.DB, error)
	Db                   func() (*sql.DB, error)
	SetIgnoreForeignKeys func(ignore bool) error
}

func (i ImportDb) RequireRebuild() bool {
	return i.requireRebuild
}

func Connect(dbType, dsn string) (*ImportDb, error) {
	var db ImportDb
	switch dbType {
	case "sqlite3":
		db.OpenDb = func(dsn string) (*sql.DB, error) {
			db.dsn = dsn
			dbFileInfo, err := os.Stat(dsn)
			if err != nil && !os.IsNotExist(err) {
				return nil, fmt.Errorf("Error on stat db: %v", err)
			}
			// force rebuild on new db
			if os.IsNotExist(err) {
				db.requireRebuild = true
			} else {
				if dbFileInfo.IsDir() {
					return nil, fmt.Errorf("Db is a directory.")
				}
			}
			sqlite, err := sql.Open("sqlite3", dsn)
			if err != nil {
				return nil, fmt.Errorf("Error opening db: %v", err)
			}
			return sqlite, err
		}
		db.Db = func() (*sql.DB, error) {
			return sql.Open("sqlite3", "file:"+db.dsn+"?cache=shared")
		}
		db.SetIgnoreForeignKeys = func(ignore bool) error {
			db, err := sql.Open("sqlite3", "file:"+db.dsn+"?cache=shared")
			if err != nil {
				return err
			}
			if ignore {
				_, err = db.Exec("PRAGMA foreign_keys = OFF")
			} else {
				_, err = db.Exec("PRAGMA foreign_keys = ON")
			}
			if err != nil {
				return err
			}
			return nil
		}
	case "mysql":
		db.OpenDb = func(dsn string) (*sql.DB, error) {
			var err error
			db.dsn = dsn
			db.db, err = sql.Open("mysql", dsn)
			if err != nil {
				return nil, fmt.Errorf("Error connecting to MySQL: %v", err)
			}
			return db.db, nil
		}
		db.Db = func() (*sql.DB, error) {
			if db.db == nil {
				return nil, fmt.Errorf("No MySQL connection. Call OpenDb() first.")
			}
			return db.db, nil
		}
		db.SetIgnoreForeignKeys = func(ignore bool) error {
			if db.db == nil {
				return fmt.Errorf("No MySQL connection. Call OpenDb() first.")
			}
			if ignore {
				_, err := db.db.Exec("SET FOREIGN_KEY_CHECKS=0")
				if err != nil {
					return fmt.Errorf("Error ignoring foreign keys: %v", err)
				}
			} else {
				_, err := db.db.Exec("SET FOREIGN_KEY_CHECKS=1")
				if err != nil {
					return fmt.Errorf("Error set foreign keys: %v", err)
				}
			}
			return nil
		}
	default:
		return nil, fmt.Errorf("Invalid db type: %s", dbType)
	}
	return &db, nil
}

func BackupDb(fileName string) error {
	info, err := os.Stat(fileName)
	if err != nil && !os.IsNotExist(err) {
		return fmt.Errorf("Error backing up db stat: %v", err)
	}
	if os.IsNotExist(err) {
		return nil
	}
	if info.IsDir() {
		return fmt.Errorf("DB file is a directory. Cannot continue.")
	}
	orig, err := os.Open(fileName)
	if err != nil {
		return fmt.Errorf("Could not open db: %v", err)
	}
	defer orig.Close()
	bak, err := os.Create(fileName + ".bak")
	if err != nil {
		return fmt.Errorf("Error creating backup file: %v", err)
	}
	defer bak.Close()
	_, err = io.Copy(bak, orig)
	return nil
}
<|endoftext|>


<commit_before>package storage

import (
	"github.com/docker/distribution"
	"github.com/docker/distribution/context"
	"github.com/docker/distribution/reference"
	"github.com/docker/distribution/registry/storage/cache"
	storagedriver "github.com/docker/distribution/registry/storage/driver"
)

// registry is the top-level implementation of Registry for use in the storage
// package. All instances should descend from this object.
type registry struct {
	blobStore                   *blobStore
	blobServer                  *blobServer
	statter                     *blobStatter // global statter service.
	blobDescriptorCacheProvider cache.BlobDescriptorCacheProvider
	deleteEnabled               bool
	resumableDigestEnabled      bool
}

// RegistryOption is the type used for functional options for NewRegistry.
type RegistryOption func(*registry) error

// EnableRedirect is a functional option for NewRegistry. It causes the backend
// blob server to attempt using (StorageDriver).URLFor to serve all blobs.
func EnableRedirect(registry *registry) error {
	registry.blobServer.redirect = true
	return nil
}

// EnableDelete is a functional option for NewRegistry. It enables deletion on
// the registry.
func EnableDelete(registry *registry) error {
	registry.deleteEnabled = true
	return nil
}

// DisableDigestResumption is a functional option for NewRegistry. It should be
// used if the registry is acting as a caching proxy.
func DisableDigestResumption(registry *registry) error {
	registry.resumableDigestEnabled = false
	return nil
}

// BlobDescriptorCacheProvider returns a functional option for
// NewRegistry. It creates a cached blob statter for use by the
// registry.
func BlobDescriptorCacheProvider(blobDescriptorCacheProvider cache.BlobDescriptorCacheProvider) RegistryOption {
	// TODO(aaronl): The duplication of statter across several objects is
	// ugly, and prevents us from using interface types in the registry
	// struct. Ideally, blobStore and blobServer should be lazily
	// initialized, and use the current value of
	// blobDescriptorCacheProvider.
	return func(registry *registry) error {
		if blobDescriptorCacheProvider != nil {
			statter := cache.NewCachedBlobStatter(blobDescriptorCacheProvider, registry.statter)
			registry.blobStore.statter = statter
			registry.blobServer.statter = statter
			registry.blobDescriptorCacheProvider = blobDescriptorCacheProvider
		}
		return nil
	}
}

// NewRegistry creates a new registry instance from the provided driver. The
// resulting registry may be shared by multiple goroutines but is cheap to
// allocate. If the Redirect option is specified, the backend blob server will
// attempt to use (StorageDriver).URLFor to serve all blobs.
func NewRegistry(ctx context.Context, driver storagedriver.StorageDriver, options ...RegistryOption) (distribution.Namespace, error) {
	// create global statter
	statter := &blobStatter{
		driver: driver,
	}

	bs := &blobStore{
		driver:  driver,
		statter: statter,
	}

	registry := &registry{
		blobStore: bs,
		blobServer: &blobServer{
			driver:  driver,
			statter: statter,
			pathFn:  bs.path,
		},
		statter:                statter,
		resumableDigestEnabled: true,
	}

	for _, option := range options {
		if err := option(registry); err != nil {
			return nil, err
		}
	}

	return registry, nil
}

// Scope returns the namespace scope for a registry. The registry
// will only serve repositories contained within this scope.
func (reg *registry) Scope() distribution.Scope {
	return distribution.GlobalScope
}

// Repository returns an instance of the repository tied to the registry.
// Instances should not be shared between goroutines but are cheap to
// allocate. In general, they should be request scoped.
func (reg *registry) Repository(ctx context.Context, canonicalName string) (distribution.Repository, error) {
	if _, err := reference.ParseNamed(canonicalName); err != nil {
		return nil, distribution.ErrRepositoryNameInvalid{
			Name:   canonicalName,
			Reason: err,
		}
	}

	var descriptorCache distribution.BlobDescriptorService
	if reg.blobDescriptorCacheProvider != nil {
		var err error
		descriptorCache, err = reg.blobDescriptorCacheProvider.RepositoryScoped(canonicalName)
		if err != nil {
			return nil, err
		}
	}

	return &repository{
		ctx:             ctx,
		registry:        reg,
		name:            canonicalName,
		descriptorCache: descriptorCache,
	}, nil
}

// repository provides name-scoped access to various services.
type repository struct {
	*registry
	ctx             context.Context
	name            string
	descriptorCache distribution.BlobDescriptorService
}

// Name returns the name of the repository.
func (repo *repository) Name() string {
	return repo.name
}

// Manifests returns an instance of ManifestService. Instantiation is cheap and
// may be context sensitive in the future. The instance should be used similar
// to a request local.
func (repo *repository) Manifests(ctx context.Context, options ...distribution.ManifestServiceOption) (distribution.ManifestService, error) {
	manifestLinkPathFns := []linkPathFunc{
		// NOTE(stevvooe): Need to search through multiple locations since
		// 2.1.0 unintentionally linked into  _layers.
		manifestRevisionLinkPath,
		blobLinkPath,
	}

	ms := &manifestStore{
		ctx:        ctx,
		repository: repo,
		revisionStore: &revisionStore{
			ctx:        ctx,
			repository: repo,
			blobStore: &linkedBlobStore{
				ctx:           ctx,
				blobStore:     repo.blobStore,
				repository:    repo,
				deleteEnabled: repo.registry.deleteEnabled,
				blobAccessController: &linkedBlobStatter{
					blobStore:   repo.blobStore,
					repository:  repo,
					linkPathFns: manifestLinkPathFns,
				},

				// TODO(stevvooe): linkPath limits this blob store to only
				// manifests. This instance cannot be used for blob checks.
				linkPathFns: manifestLinkPathFns,
			},
		},
		tagStore: &tagStore{
			ctx:        ctx,
			repository: repo,
			blobStore:  repo.registry.blobStore,
		},
	}

	// Apply options
	for _, option := range options {
		err := option(ms)
		if err != nil {
			return nil, err
		}
	}

	return ms, nil
}

// Blobs returns an instance of the BlobStore. Instantiation is cheap and
// may be context sensitive in the future. The instance should be used similar
// to a request local.
func (repo *repository) Blobs(ctx context.Context) distribution.BlobStore {
	var statter distribution.BlobDescriptorService = &linkedBlobStatter{
		blobStore:   repo.blobStore,
		repository:  repo,
		linkPathFns: []linkPathFunc{blobLinkPath},
	}

	if repo.descriptorCache != nil {
		statter = cache.NewCachedBlobStatter(repo.descriptorCache, statter)
	}

	return &linkedBlobStore{
		blobStore:            repo.blobStore,
		blobServer:           repo.blobServer,
		blobAccessController: statter,
		repository:           repo,
		ctx:                  ctx,

		// TODO(stevvooe): linkPath limits this blob store to only layers.
		// This instance cannot be used for manifest checks.
		linkPathFns:   []linkPathFunc{blobLinkPath},
		deleteEnabled: repo.registry.deleteEnabled,
	}
}

func (repo *repository) Signatures() distribution.SignatureService {
	return &signatureStore{
		repository: repo,
		blobStore:  repo.blobStore,
		ctx:        repo.ctx,
	}
}
<commit_msg>Redundant digest verification in validateBlob<commit_after>package storage

import (
	"github.com/docker/distribution"
	"github.com/docker/distribution/context"
	"github.com/docker/distribution/reference"
	"github.com/docker/distribution/registry/storage/cache"
	storagedriver "github.com/docker/distribution/registry/storage/driver"
)

// registry is the top-level implementation of Registry for use in the storage
// package. All instances should descend from this object.
type registry struct {
	blobStore                   *blobStore
	blobServer                  *blobServer
	statter                     *blobStatter // global statter service.
	blobDescriptorCacheProvider cache.BlobDescriptorCacheProvider
	deleteEnabled               bool
	resumableDigestEnabled      bool
}

// RegistryOption is the type used for functional options for NewRegistry.
type RegistryOption func(*registry) error

// EnableRedirect is a functional option for NewRegistry. It causes the backend
// blob server to attempt using (StorageDriver).URLFor to serve all blobs.
func EnableRedirect(registry *registry) error {
	registry.blobServer.redirect = true
	return nil
}

// EnableDelete is a functional option for NewRegistry. It enables deletion on
// the registry.
func EnableDelete(registry *registry) error {
	registry.deleteEnabled = true
	return nil
}

// DisableDigestResumption is a functional option for NewRegistry. It should be
// used if the registry is acting as a caching proxy.
func DisableDigestResumption(registry *registry) error {
	registry.resumableDigestEnabled = false
	return nil
}

// BlobDescriptorCacheProvider returns a functional option for
// NewRegistry. It creates a cached blob statter for use by the
// registry.
func BlobDescriptorCacheProvider(blobDescriptorCacheProvider cache.BlobDescriptorCacheProvider) RegistryOption {
	// TODO(aaronl): The duplication of statter across several objects is
	// ugly, and prevents us from using interface types in the registry
	// struct. Ideally, blobStore and blobServer should be lazily
	// initialized, and use the current value of
	// blobDescriptorCacheProvider.
	return func(registry *registry) error {
		if blobDescriptorCacheProvider != nil {
			statter := cache.NewCachedBlobStatter(blobDescriptorCacheProvider, registry.statter)
			registry.blobStore.statter = statter
			registry.blobServer.statter = statter
			registry.blobDescriptorCacheProvider = blobDescriptorCacheProvider
		}
		return nil
	}
}

// NewRegistry creates a new registry instance from the provided driver. The
// resulting registry may be shared by multiple goroutines but is cheap to
// allocate. If the Redirect option is specified, the backend blob server will
// attempt to use (StorageDriver).URLFor to serve all blobs.
func NewRegistry(ctx context.Context, driver storagedriver.StorageDriver, options ...RegistryOption) (distribution.Namespace, error) {
	// create global statter
	statter := &blobStatter{
		driver: driver,
	}

	bs := &blobStore{
		driver:  driver,
		statter: statter,
	}

	registry := &registry{
		blobStore: bs,
		blobServer: &blobServer{
			driver:  driver,
			statter: statter,
			pathFn:  bs.path,
		},
		statter:                statter,
		resumableDigestEnabled: true,
	}

	for _, option := range options {
		if err := option(registry); err != nil {
			return nil, err
		}
	}

	return registry, nil
}

// Scope returns the namespace scope for a registry. The registry
// will only serve repositories contained within this scope.
func (reg *registry) Scope() distribution.Scope {
	return distribution.GlobalScope
}

// Repository returns an instance of the repository tied to the registry.
// Instances should not be shared between goroutines but are cheap to
// allocate. In general, they should be request scoped.
func (reg *registry) Repository(ctx context.Context, canonicalName string) (distribution.Repository, error) {
	if _, err := reference.ParseNamed(canonicalName); err != nil {
		return nil, distribution.ErrRepositoryNameInvalid{
			Name:   canonicalName,
			Reason: err,
		}
	}

	var descriptorCache distribution.BlobDescriptorService
	if reg.blobDescriptorCacheProvider != nil {
		var err error
		descriptorCache, err = reg.blobDescriptorCacheProvider.RepositoryScoped(canonicalName)
		if err != nil {
			return nil, err
		}
	}

	return &repository{
		ctx:             ctx,
		registry:        reg,
		name:            canonicalName,
		descriptorCache: descriptorCache,
	}, nil
}

// repository provides name-scoped access to various services.
type repository struct {
	*registry
	ctx             context.Context
	name            string
	descriptorCache distribution.BlobDescriptorService
}

// Name returns the name of the repository.
func (repo *repository) Name() string {
	return repo.name
}

// Manifests returns an instance of ManifestService. Instantiation is cheap and
// may be context sensitive in the future. The instance should be used similar
// to a request local.
func (repo *repository) Manifests(ctx context.Context, options ...distribution.ManifestServiceOption) (distribution.ManifestService, error) {
	manifestLinkPathFns := []linkPathFunc{
		// NOTE(stevvooe): Need to search through multiple locations since
		// 2.1.0 unintentionally linked into  _layers.
		manifestRevisionLinkPath,
		blobLinkPath,
	}

	ms := &manifestStore{
		ctx:        ctx,
		repository: repo,
		revisionStore: &revisionStore{
			ctx:        ctx,
			repository: repo,
			blobStore: &linkedBlobStore{
				ctx:           ctx,
				blobStore:     repo.blobStore,
				repository:    repo,
				deleteEnabled: repo.registry.deleteEnabled,
				blobAccessController: &linkedBlobStatter{
					blobStore:   repo.blobStore,
					repository:  repo,
					linkPathFns: manifestLinkPathFns,
				},

				// TODO(stevvooe): linkPath limits this blob store to only
				// manifests. This instance cannot be used for blob checks.
				linkPathFns:            manifestLinkPathFns,
				resumableDigestEnabled: repo.resumableDigestEnabled,
			},
		},
		tagStore: &tagStore{
			ctx:        ctx,
			repository: repo,
			blobStore:  repo.registry.blobStore,
		},
	}

	// Apply options
	for _, option := range options {
		err := option(ms)
		if err != nil {
			return nil, err
		}
	}

	return ms, nil
}

// Blobs returns an instance of the BlobStore. Instantiation is cheap and
// may be context sensitive in the future. The instance should be used similar
// to a request local.
func (repo *repository) Blobs(ctx context.Context) distribution.BlobStore {
	var statter distribution.BlobDescriptorService = &linkedBlobStatter{
		blobStore:   repo.blobStore,
		repository:  repo,
		linkPathFns: []linkPathFunc{blobLinkPath},
	}

	if repo.descriptorCache != nil {
		statter = cache.NewCachedBlobStatter(repo.descriptorCache, statter)
	}

	return &linkedBlobStore{
		blobStore:            repo.blobStore,
		blobServer:           repo.blobServer,
		blobAccessController: statter,
		repository:           repo,
		ctx:                  ctx,

		// TODO(stevvooe): linkPath limits this blob store to only layers.
		// This instance cannot be used for manifest checks.
		linkPathFns:            []linkPathFunc{blobLinkPath},
		deleteEnabled:          repo.registry.deleteEnabled,
		resumableDigestEnabled: repo.resumableDigestEnabled,
	}
}

func (repo *repository) Signatures() distribution.SignatureService {
	return &signatureStore{
		repository: repo,
		blobStore:  repo.blobStore,
		ctx:        repo.ctx,
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 AFP Authors
// This source code is released under the terms of the
// MIT license. Please see the file LICENSE for license details.

//inspired by http://www.musicdsp.org/

package echo

import (
    "afp"
    "os"
)

type EchoFilter struct {
    context *afp.Context
    header afp.StreamHeader
    decay float32 //decay factor: between 0 and 1
}

func (self *EchoFilter) GetType() int {
    return afp.PIPE_LINK
}

func NewEchoFilter() afp.Filter {
    return &EchoFilter{}
}

func (self *EchoFilter) Usage() {
    //TODO: add usage
}

func (self *EchoFilter) Init(ctx *afp.Context, args []string) os.Error {
    self.context = ctx
    //TODO: add argument parsing for decay rate
    self.decay = .2
    return nil
}

func (self *EchoFilter) Start() {
    self.header = <-self.context.HeaderSource
    self.context.HeaderSink <- self.header

    //delay offsets for 3 reflections
    offset1 := 20 //magic number
    offset2 := 35 //magic number
    offset3 := 42 //magic number

    drySignal := <-self.context.Source
    frameSize := len(drySignal)
    //make the dry signal buffer twice the frame size
    drySignal = append(drySignal, <-self.context.Source...)
    length := len(drySignal)

    reflect1 := make([][]float32, length)
    reflect2 := make([][]float32, length)
    reflect3 := make([][]float32, length)
    wetSignal := make([][]float32, length)

    //a couple of empty buffers
    var zero float32[]
    for _, _ := range drySignal[0] {//we don't care about the data, just the dimensions
        zero = append(zero, 0)
    }
    var zeros float32[][]
    for i := 0; i < frameSize; i++ {
        zeros = append(zeros, zero)
    }

    //initialize our reflection buffers with silence
    for i := 0; i < offset1; i++ {
        reflect1[i] = zero
        reflect2[i] = zero
        reflect3[i] = zero
    } for i < offset2 {
        reflect2[i] = zero
        reflect3[i] = zero
        i++
    } for i < offset3 {
        reflect3[i] = zero
        i++
    }

    for nextFrame := range self.context.Source {

        for i := 0; i < frameSize; i++ {
            for j := int8(0); j < self.header.Channels; j++ {
                //ECHO, Echo, echo...

                reflect1[i+offset1][j] = drySignal[i][j] * self.decay
                reflect2[i+offset2][j] = drySignal[i][j] * self.decay
                reflect3[i+offset3][j] = drySignal[i][j] * self.decay

                wetSignal[i][j] = reflect1[i] + reflect2[i] + reflect3[i]
            }
        }

        self.context.Sink <- wetSignal[0:frameSize]
        wetSignal = wetSignal[frameSize:]
        wetSignal = append(wetSignal, zeros)

        drySignal = drySignal[frameSize:]
        drySignal = append(drySignal, nextFrame...)
    }

    //TODO: pad with silence

    //flush the signals
    for i := 0; i < length; i++ {
        //apply echo/reverb
        for j := int8(0); j < self.header.Channels; j++ {
            reflect1[i+offset1][j] = drySignal[i][j] * self.decay
            reflect2[i+offset2][j] = drySignal[i][j] * self.decay
            reflect3[i+offset3][j] = drySignal[i][j] * self.decay

            wetSignal[i][j] = reflect1[i] + reflect2[i] + reflect3[i]
        }

        //wrap
        if i == frameSize {
            self.context.Sink <- wetSignal[0:frameSize]
            wetSignal = wetSignal[frameSize:]
            drySignal = drySignal[frameSize:]
            i = 0
            length -= frameSize
        }
    }
}

func (self *EchoFilter) Stop() os.Error {
    //TODO
    return nil
}
<commit_msg>That de-typo-matic 3000 sure comes in handy ;)<commit_after>// Copyright (c) 2010 AFP Authors
// This source code is released under the terms of the
// MIT license. Please see the file LICENSE for license details.

//inspired by http://www.musicdsp.org/

package echo

import (
    "afp"
    "os"
)

type EchoFilter struct {
    context *afp.Context
    header afp.StreamHeader
    decay float32 //decay factor: between 0 and 1
}

func (self *EchoFilter) GetType() int {
    return afp.PIPE_LINK
}

func NewEchoFilter() afp.Filter {
    return &EchoFilter{}
}

func (self *EchoFilter) Usage() {
    //TODO: add usage
}

func (self *EchoFilter) Init(ctx *afp.Context, args []string) os.Error {
    self.context = ctx
    //TODO: add argument parsing for decay rate
    self.decay = .2
    return nil
}

func (self *EchoFilter) Start() {
    self.header = <-self.context.HeaderSource
    self.context.HeaderSink <- self.header

    //delay offsets for 3 reflections
    offset1 := 20 //magic number
    offset2 := 35 //magic number
    offset3 := 42 //magic number

    drySignal := <-self.context.Source
    frameSize := len(drySignal)
    //make the dry signal buffer twice the frame size
    drySignal = append(drySignal, <-self.context.Source...)
    length := len(drySignal)

    reflect1 := make([][]float32, length)
    reflect2 := make([][]float32, length)
    reflect3 := make([][]float32, length)
    wetSignal := make([][]float32, length)

    //a couple of empty buffers
    var zero []float32
    for _, _ = range drySignal[0] {//we don't care about the data, just the dimensions
        zero = append(zero, 0)
    }
    var zeros [][]float32
    for i := 0; i < frameSize; i++ {
        zeros = append(zeros, zero)
    }

    //initialize our reflection buffers with silence
    for i := 0; i < offset1; i++ {
        reflect1[i] = zero
        reflect2[i] = zero
        reflect3[i] = zero
    }
    for i := offset1; i < offset2; i++ {
        reflect2[i] = zero
        reflect3[i] = zero
    }
    for i := offset2; i < offset3; i++ {
        reflect3[i] = zero
    }

    for nextFrame := range self.context.Source {

        for i := 0; i < frameSize; i++ {
            for j := int8(0); j < self.header.Channels; j++ {
                //ECHO, Echo, echo...

                reflect1[i+offset1][j] = drySignal[i][j] * self.decay
                reflect2[i+offset2][j] = drySignal[i][j] * self.decay
                reflect3[i+offset3][j] = drySignal[i][j] * self.decay

                wetSignal[i][j] = reflect1[i][j] + reflect2[i][j] + reflect3[i][j]
            }
        }

        self.context.Sink <- wetSignal[0:frameSize]
        wetSignal = wetSignal[frameSize:]
        wetSignal = append(wetSignal, zeros...)

        drySignal = drySignal[frameSize:]
        drySignal = append(drySignal, nextFrame...)
    }

    //TODO: pad with silence

    //flush the signals
    for i := 0; i < length; i++ {
        //apply echo/reverb
        for j := int8(0); j < self.header.Channels; j++ {
            reflect1[i+offset1][j] = drySignal[i][j] * self.decay
            reflect2[i+offset2][j] = drySignal[i][j] * self.decay
            reflect3[i+offset3][j] = drySignal[i][j] * self.decay

            wetSignal[i][j] = reflect1[i][j] + reflect2[i][j] + reflect3[i][j]
        }

        //wrap
        if i == frameSize {
            self.context.Sink <- wetSignal[0:frameSize]
            wetSignal = wetSignal[frameSize:]
            drySignal = drySignal[frameSize:]
            i = 0
            length -= frameSize
        }
    }
}

func (self *EchoFilter) Stop() os.Error {
    //TODO
    return nil
}
<|endoftext|>


<commit_before>// Package add implements functions for adding a dependency
package add

// Copyright 2013 Vubeology, Inc.

import (
	"fmt"
	"strings"

	"github.com/vube/depman/colors"
	"github.com/vube/depman/dep"
	"github.com/vube/depman/install"
	"github.com/vube/depman/util"
)

// Add interactively prompts the user for details of a dependency, adds it to deps.json, and writes out the file
func Add(deps dep.DependencyMap, name string) {
	var cont = true
	_, exists := deps.Map[name]
	if exists {
		util.Fatal(colors.Red("Dependency '" + name + "'' is already defined, pick another name."))
	}

	util.Print(colors.Blue("Adding: ") + name)

	for cont {
		d := new(dep.Dependency)
		d.Type = promptType("Type", "git, git-clone, hg, bzr")
		if d.Type == dep.TypeGitClone {
			d.Repo = promptString("Repo", "git url")
		} else {
			d.Repo = promptString("Repo", "go import")
		}
		d.Version = promptString("Version", "hash, branch, or tag")
		if d.Type == dep.TypeGitClone {
			d.Alias = promptString("Alias", "where to install the repo")
		}
		deps.Map[name] = d
		cont = promptBool("Add another", "y/N")
	}

	for name, d := range deps.Map {
		err := d.SetupVCS(name)
		if err != nil {
			delete(deps.Map, name)
		}

	}

	err := deps.Write()
	if err != nil {
		util.Fatal(colors.Red("Error Writing " + deps.Path + ": " + err.Error()))
	}

	install.Install(deps)

	return
}

// Promt the user with question and return a string answer
func promptString(question string, details string) (answer string) {
	fmt.Print(colors.Blue(question) + " (" + details + "): ")
	fmt.Scanln(&answer)
	return
}

// Prompt the user with question and return a bool answer
func promptBool(question string, details string) (answer bool) {
	str := promptString(question, details)

	switch str {
	case "y", "yes":
		answer = true
	default:
		answer = false
	}

	return
}

// Prompt the user with question check that the answer is a valid dep type and then return it
func promptType(question string, details string) (t string) {
	for {
		t = promptString(question, details)
		t = strings.TrimSpace(t)
		switch t {
		case dep.TypeBzr, dep.TypeGit, dep.TypeHg, dep.TypeGitClone:
			return
		default:
			util.Print(colors.Red("Invalid Type, try again..."))
		}
	}
}
<commit_msg>add: Cleanup and bug fix<commit_after>// Package add implements functions for interactively adding a dependency
package add

// Copyright 2014 Vubeology, Inc.

import (
	"fmt"
	"strings"

	"github.com/vube/depman/colors"
	"github.com/vube/depman/dep"
	"github.com/vube/depman/install"
	"github.com/vube/depman/util"
)

// Add interactively prompts the user for details of a dependency, adds it to deps.json, writes out the file, and installs the dependencies
func Add(deps dep.DependencyMap, name string) {
	_, exists := deps.Map[name]
	if exists {
		util.Fatal(colors.Red("Dependency '" + name + "'' is already defined, pick another name."))
	}

	util.Print(colors.Blue("Adding: ") + name)

	d := new(dep.Dependency)
	d.Type = promptType("Type", "git, git-clone, hg, bzr")

	if d.Type == dep.TypeGitClone {
		d.Repo = promptString("Repo", "git url")
	} else {
		d.Repo = promptString("Repo", "go import")
	}

	d.Version = promptString("Version", "hash, branch, or tag")

	if d.Type == dep.TypeGitClone {
		d.Alias = promptString("Alias", "where to install the repo")
	}

	deps.Map[name] = d

	for name, d := range deps.Map {
		err := d.SetupVCS(name)
		if err != nil {
			delete(deps.Map, name)
		}
	}

	err := deps.Write()
	if err != nil {
		util.Fatal(colors.Red("Error Writing " + deps.Path + ": " + err.Error()))
	}

	install.Install(deps)

	return
}

// promptString prompts the user with question and returns a string answer
func promptString(question string, details string) (answer string) {
	fmt.Print(colors.Blue(question) + " (" + details + "): ")
	fmt.Scanln(&answer)
	return
}

// promptType prompts the user with question, checks that the answer is a valid dep type and then return it
func promptType(question string, details string) (t string) {
	for {
		t = promptString(question, details)
		t = strings.TrimSpace(t)
		switch t {
		case dep.TypeBzr, dep.TypeGit, dep.TypeHg, dep.TypeGitClone:
			return
		default:
			util.Print(colors.Red("Invalid Type, try again..."))
		}
	}
}
<|endoftext|>


<commit_before>package flagfile

import (
	"flag"
	"fmt"
	"io"
	"net/url"
	"os"
	"path/filepath"
	"reflect"
	"strings"
)

// FlagSet is a subset of methods of *flag.FlagSet
type FlagSet interface {
	Parse([]string) error
	Set(name, value string) error
}

// Loader loads structured data from r.
// The fragment may point to a partial of the content.
//
// The output is expected to be:
// - a slice of strings
// - a map where keys are strings and valuer are either string or slice of strings
type Loader func(r io.Reader, fragment string) (interface{}, error)

type file struct {
	flagset    FlagSet
	load       Loader
	contextDir []string
}

// File allows to define a command-line flag that gives a path to a structured
// file whose content will be expanded as command-line arguments and injected into flagset.
//
// The structured data may be:
// - an array of strings given to flagset.Parse
// - a map where keys are argument names (without leading '-') and keys are values
//   or arrays of values
//
// This flag is reentrant, so the file may refer to (include) other files by reusing the
// same flag.
func File(flagset FlagSet, loader Loader) flag.Value {
	return &file{
		flagset: flagset,
		load:    loader,
	}
}

func (file) String() string { return "" }

// Set loads the given file, decodes it and interprets
// its structured data as a list of arguments.
//
// Set is part of the flag.Value interface.
func (f *file) Set(path string) error {
	var fragment string
	if i := strings.IndexByte(path, '#'); i > 0 {
		var err error
		if fragment, err = url.QueryUnescape(path[i+1:]); err != nil {
			return fmt.Errorf("invalid fragment %q", path[i+1:])
		}
		path = path[:i]
	}

	// Resolve the path to an absolute path using either the path of the enclosing file
	// or the current working directory.
	if !filepath.IsAbs(path) {
		var ctxDir string
		if len(f.contextDir) == 0 {
			var e error
			ctxDir, e = os.Getwd()
			if e != nil {
				return e
			}
		} else {
			ctxDir = f.contextDir[len(f.contextDir)-1]
		}
		path = filepath.Join(ctxDir, path)
	}

	r, err := os.Open(path)
	if err != nil {
		// TODO return a structured error to allow l18n
		return fmt.Errorf("%s: %s", path, err)
	}

	v, err := func(r *os.File, load Loader) (interface{}, error) {
		defer r.Close()
		return load(r, fragment)
	}(r, f.load)
	if err != nil {
		// TODO return a structured error to allow l18n
		return fmt.Errorf("%s: can't decode: %s", path, err)
	}

	// push directory of the path
	f.contextDir = append(f.contextDir, filepath.Dir(path))
	defer func() {
		// pop contextDir
		f.contextDir = f.contextDir[:len(f.contextDir)-1]
	}()

	switch v := v.(type) {
	case nil: // NOOP
	case []interface{}:
		if len(v) == 0 {
			break
		}
		args := make([]string, 0, len(v))
		for _, arg := range v {
			args = append(args, fmt.Sprint(arg))
		}
		err = f.flagset.Parse(args)
	case []string:
		if len(v) > 0 {
			err = f.flagset.Parse(v)
		}
	case map[string]interface{}:
		err = parseObject(f.flagset, v)
		// TODO map[string]string
		// TODO map[string][]string
	default:
		return fmt.Errorf("unexpected type %T", v)
	}
	if err != nil {
		err = fmt.Errorf("%s#%s", path, err)
	}
	return err
}

func parseObject(flagset FlagSet, m map[string]interface{}) error {
	for k, v := range m {
		var err error
		switch v := v.(type) {
		case string:
			err = flagset.Set(k, v)
		case []string:
			for i, v := range v {
				err = flagset.Set(k, v)
				if err != nil {
					return fmt.Errorf("/%s/%d: %s", k, i, err)
				}
			}
		default:
			rv := reflect.ValueOf(v)
			if rv.Kind() == reflect.Array || rv.Kind() == reflect.Slice {
				for i := 0; i < rv.Len(); i++ {
					err = flagset.Set(k, fmt.Sprint(rv.Index(i).Interface()))
					if err != nil {
						return fmt.Errorf("/%s/%d: %s", k, i, err)
					}
				}
			} else {
				err = flagset.Set(k, fmt.Sprint(v))
			}
		}
		if err != nil {
			return fmt.Errorf("/%s: %s", k, err)
		}
	}

	return nil
}
<commit_msg>flagfile: fix recursive parsing of flags<commit_after>package flagfile

import (
	"flag"
	"fmt"
	"io"
	"net/url"
	"os"
	"path/filepath"
	"reflect"
	"strings"
)

// FlagSet is a subset of methods of *flag.FlagSet
type FlagSet interface {
	Parse([]string) error
	Args() []string
	Set(name, value string) error
}

// Loader loads structured data from r.
// The fragment may point to a partial of the content.
//
// The output is expected to be:
// - a slice of strings
// - a map where keys are strings and valuer are either string or slice of strings
type Loader func(r io.Reader, fragment string) (interface{}, error)

type file struct {
	flagset    FlagSet
	load       Loader
	contextDir []string
}

// File allows to define a command-line flag that gives a path to a structured
// file whose content will be expanded as command-line arguments and injected into flagset.
//
// The structured data may be:
// - an array of strings given to flagset.Parse
// - a map where keys are argument names (without leading '-') and keys are values
//   or arrays of values
//
// This flag is reentrant, so the file may refer to (include) other files by reusing the
// same flag.
func File(flagset FlagSet, loader Loader) flag.Value {
	return &file{
		flagset: flagset,
		load:    loader,
	}
}

func (file) String() string { return "" }

// Set loads the given file, decodes it and interprets
// its structured data as a list of arguments.
//
// Set is part of the flag.Value interface.
func (f *file) Set(path string) error {
	var fragment string
	if i := strings.IndexByte(path, '#'); i > 0 {
		var err error
		if fragment, err = url.QueryUnescape(path[i+1:]); err != nil {
			return fmt.Errorf("invalid fragment %q", path[i+1:])
		}
		path = path[:i]
	}

	// Resolve the path to an absolute path using either the path of the enclosing file
	// or the current working directory.
	if !filepath.IsAbs(path) {
		var ctxDir string
		if len(f.contextDir) == 0 {
			var e error
			ctxDir, e = os.Getwd()
			if e != nil {
				return e
			}
		} else {
			ctxDir = f.contextDir[len(f.contextDir)-1]
		}
		path = filepath.Join(ctxDir, path)
	}

	r, err := os.Open(path)
	if err != nil {
		// TODO return a structured error to allow l18n
		return fmt.Errorf("%s: %s", path, err)
	}

	v, err := func(r *os.File, load Loader) (interface{}, error) {
		defer r.Close()
		return load(r, fragment)
	}(r, f.load)
	if err != nil {
		// TODO return a structured error to allow l18n
		return fmt.Errorf("%s: can't decode: %s", path, err)
	}

	// push directory of the path
	f.contextDir = append(f.contextDir, filepath.Dir(path))
	defer func() {
		// pop contextDir
		f.contextDir = f.contextDir[:len(f.contextDir)-1]
	}()

	switch v := v.(type) {
	case nil: // NOOP
	case []interface{}:
		if len(v) == 0 {
			break
		}
		args := make([]string, 0, len(v))
		for _, arg := range v {
			args = append(args, fmt.Sprint(arg))
		}
		remaining := f.flagset.Args()
		err = f.flagset.Parse(args)
		if err != nil {
			return err
		}
		err = f.flagset.Parse(remaining)
	case []string:
		if len(v) > 0 {
			remaining := f.flagset.Args()
			err = f.flagset.Parse(v)
			if err != nil {
				return err
			}
			err = f.flagset.Parse(remaining)
		}
	case map[string]interface{}:
		err = parseObject(f.flagset, v)
		// TODO map[string]string
		// TODO map[string][]string
	default:
		return fmt.Errorf("unexpected type %T", v)
	}
	if err != nil {
		err = fmt.Errorf("%s#%s", path, err)
	}
	return err
}

func parseObject(flagset FlagSet, m map[string]interface{}) error {
	for k, v := range m {
		var err error
		switch v := v.(type) {
		case string:
			err = flagset.Set(k, v)
		case []string:
			for i, v := range v {
				err = flagset.Set(k, v)
				if err != nil {
					return fmt.Errorf("/%s/%d: %s", k, i, err)
				}
			}
		default:
			rv := reflect.ValueOf(v)
			if rv.Kind() == reflect.Array || rv.Kind() == reflect.Slice {
				for i := 0; i < rv.Len(); i++ {
					err = flagset.Set(k, fmt.Sprint(rv.Index(i).Interface()))
					if err != nil {
						return fmt.Errorf("/%s/%d: %s", k, i, err)
					}
				}
			} else {
				err = flagset.Set(k, fmt.Sprint(v))
			}
		}
		if err != nil {
			return fmt.Errorf("/%s: %s", k, err)
		}
	}

	return nil
}
<|endoftext|>


<commit_before>package terraform

import (
	"reflect"
	"testing"
)

func TestEvalConfigProvider_impl(t *testing.T) {
	var _ EvalNode = new(EvalConfigProvider)
}

func TestEvalConfigProvider(t *testing.T) {
	config := testResourceConfig(t, map[string]interface{}{})
	provider := &MockResourceProvider{}
	n := &EvalConfigProvider{}

	ctx := &MockEvalContext{ProviderProvider: provider}
	args := []interface{}{config}
	if actual, err := n.Eval(ctx, args); err != nil {
		t.Fatalf("err: %s", err)
	} else if actual != nil {
		t.Fatalf("bad: %#v", actual)
	}

	if !provider.ConfigureCalled {
		t.Fatal("should be called")
	}
	if !reflect.DeepEqual(provider.ConfigureConfig, config) {
		t.Fatalf("bad: %#v", provider.ConfigureConfig)
	}
}

func TestEvalConfigProvider_args(t *testing.T) {
	config := testResourceConfig(t, map[string]interface{}{})
	configNode := &EvalLiteral{Value: config}
	n := &EvalConfigProvider{Provider: "foo", Config: configNode}

	args, types := n.Args()
	expectedArgs := []EvalNode{configNode}
	expectedTypes := []EvalType{EvalTypeConfig}
	if !reflect.DeepEqual(args, expectedArgs) {
		t.Fatalf("bad: %#v", args)
	}
	if !reflect.DeepEqual(types, expectedTypes) {
		t.Fatalf("bad: %#v", args)
	}
}

func TestEvalInitProvider_impl(t *testing.T) {
	var _ EvalNode = new(EvalInitProvider)
}

func TestEvalInitProvider(t *testing.T) {
	n := &EvalInitProvider{Name: "foo"}
	provider := &MockResourceProvider{}
	ctx := &MockEvalContext{InitProviderProvider: provider}
	if actual, err := n.Eval(ctx, nil); err != nil {
		t.Fatalf("err: %s", err)
	} else if actual != provider {
		t.Fatalf("bad: %#v", actual)
	}

	if !ctx.InitProviderCalled {
		t.Fatal("should be called")
	}
	if ctx.InitProviderName != "foo" {
		t.Fatalf("bad: %#v", ctx.InitProviderName)
	}
}

func TestEvalGetProvider_impl(t *testing.T) {
	var _ EvalNode = new(EvalGetProvider)
}

func TestEvalGetProvider(t *testing.T) {
	n := &EvalGetProvider{Name: "foo"}
	provider := &MockResourceProvider{}
	ctx := &MockEvalContext{ProviderProvider: provider}
	if actual, err := n.Eval(ctx, nil); err != nil {
		t.Fatalf("err: %s", err)
	} else if actual != provider {
		t.Fatalf("bad: %#v", actual)
	}

	if !ctx.ProviderCalled {
		t.Fatal("should be called")
	}
	if ctx.ProviderName != "foo" {
		t.Fatalf("bad: %#v", ctx.ProviderName)
	}
}
<commit_msg>terraform: fix failing tests<commit_after>package terraform

import (
	"reflect"
	"testing"
)

func TestEvalConfigProvider_impl(t *testing.T) {
	var _ EvalNode = new(EvalConfigProvider)
}

func TestEvalConfigProvider(t *testing.T) {
	config := testResourceConfig(t, map[string]interface{}{})
	provider := &MockResourceProvider{}
	n := &EvalConfigProvider{}

	ctx := &MockEvalContext{ProviderProvider: provider}
	args := []interface{}{config}
	if actual, err := n.Eval(ctx, args); err != nil {
		t.Fatalf("err: %s", err)
	} else if actual != nil {
		t.Fatalf("bad: %#v", actual)
	}

	if !ctx.ConfigureProviderCalled {
		t.Fatal("should be called")
	}
	if !reflect.DeepEqual(ctx.ConfigureProviderConfig, config) {
		t.Fatalf("bad: %#v", ctx.ConfigureProviderConfig)
	}
}

func TestEvalConfigProvider_args(t *testing.T) {
	config := testResourceConfig(t, map[string]interface{}{})
	configNode := &EvalLiteral{Value: config}
	n := &EvalConfigProvider{Provider: "foo", Config: configNode}

	args, types := n.Args()
	expectedArgs := []EvalNode{configNode}
	expectedTypes := []EvalType{EvalTypeConfig}
	if !reflect.DeepEqual(args, expectedArgs) {
		t.Fatalf("bad: %#v", args)
	}
	if !reflect.DeepEqual(types, expectedTypes) {
		t.Fatalf("bad: %#v", args)
	}
}

func TestEvalInitProvider_impl(t *testing.T) {
	var _ EvalNode = new(EvalInitProvider)
}

func TestEvalInitProvider(t *testing.T) {
	n := &EvalInitProvider{Name: "foo"}
	provider := &MockResourceProvider{}
	ctx := &MockEvalContext{InitProviderProvider: provider}
	if actual, err := n.Eval(ctx, nil); err != nil {
		t.Fatalf("err: %s", err)
	} else if actual != provider {
		t.Fatalf("bad: %#v", actual)
	}

	if !ctx.InitProviderCalled {
		t.Fatal("should be called")
	}
	if ctx.InitProviderName != "foo" {
		t.Fatalf("bad: %#v", ctx.InitProviderName)
	}
}

func TestEvalGetProvider_impl(t *testing.T) {
	var _ EvalNode = new(EvalGetProvider)
}

func TestEvalGetProvider(t *testing.T) {
	n := &EvalGetProvider{Name: "foo"}
	provider := &MockResourceProvider{}
	ctx := &MockEvalContext{ProviderProvider: provider}
	if actual, err := n.Eval(ctx, nil); err != nil {
		t.Fatalf("err: %s", err)
	} else if actual != provider {
		t.Fatalf("bad: %#v", actual)
	}

	if !ctx.ProviderCalled {
		t.Fatal("should be called")
	}
	if ctx.ProviderName != "foo" {
		t.Fatalf("bad: %#v", ctx.ProviderName)
	}
}
<|endoftext|>


<commit_before>// Copyright © 2016 Peter Teich <mail@pteich.xyz>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package cmd

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var cfgFile string

// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
	Use:   "fofiwano",
	Short: "FoFiWaNo - Folder Files Watcher Notification",
	Long: `Fofiwano is a CLI tool to watch folders or files for modifications like added, deleted or changed files.
It then sends a notification to a specific endpoint, e.g. a Slack channel, an URI (HTTP-Request) or executes a command.
`,
}

func Execute() {
	if err := RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}

func init() {
	cobra.OnInitialize(initConfig)

	RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.fofiwano.yaml)")
}

// initConfig reads in config file and ENV variables if set.
func initConfig() {
	if cfgFile != "" {
		viper.SetConfigFile(cfgFile)
	}

	viper.SetConfigName(".fofiwano")
	viper.AddConfigPath(os.Getenv("HOME"))
	viper.AddConfigPath(".")
	viper.SetEnvPrefix("fofiwano")
	viper.AutomaticEnv()

	if err := viper.ReadInConfig(); err == nil {
		fmt.Println("Using config file:", viper.ConfigFileUsed())
	}
}
<commit_msg>changed usage of fmt to log<commit_after>// Copyright © 2016 Peter Teich <mail@pteich.xyz>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package cmd

import (
	"fmt"
	"os"

	"log"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var cfgFile string

// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
	Use:   "fofiwano",
	Short: "FoFiWaNo - Folder Files Watcher Notification",
	Long: `Fofiwano is a CLI tool to watch folders or files for modifications like added, deleted or changed files.
It then sends a notification to a specific endpoint, e.g. a Slack channel, an URI (HTTP-Request) or executes a command.
`,
}

func Execute() {
	if err := RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}

func init() {
	cobra.OnInitialize(initConfig)

	RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.fofiwano.yaml)")
}

// initConfig reads in config file and ENV variables if set.
func initConfig() {
	if cfgFile != "" {
		viper.SetConfigFile(cfgFile)
	}

	viper.SetConfigName(".fofiwano")
	viper.AddConfigPath(os.Getenv("HOME"))
	viper.AddConfigPath(".")
	viper.SetEnvPrefix("fofiwano")
	viper.AutomaticEnv()

	if err := viper.ReadInConfig(); err == nil {
		log.Println("Using config file:", viper.ConfigFileUsed())
	}
}
<|endoftext|>


<commit_before>package dsl_test

import (
	"testing"

	"reflect"

	"github.com/goadesign/goa/design"
	. "github.com/goadesign/goa/design/dsl"
	"github.com/goadesign/goa/eval"
)

func TestEndpoint(t *testing.T) {
	cases := map[string]struct {
		Expr   eval.Expression
		DSL    func()
		Assert func(t *testing.T, s []*design.EndpointExpr)
	}{
		"basic_usage": {
			&design.ServiceExpr{},
			func() {
				Endpoint("basic", func() {
					Description("Optional description")
					// Docs allows linking to external documentation.
					Docs(func() {
						Description("Optional description")
						URL("https://goa.design")
					})
					Request(func() {
						Description("Optional description")
						Attribute("required", design.String)
						Required("required")
					})
					Response(func() {
						Description("Optional description")
						Attribute("required", design.String)
						Required("required")
					})
					Error("basic_error")
					Error("basic_media_error", design.ErrorMedia)
					Metadata("name", "some value", "some other value")
				})
				Endpoint("another", func() {
					// Docs allows linking to external documentation.
					Docs(func() {
						Description("Optional description")
						URL("https://goa.design")
					})
					Request(design.String)
					Response(design.String)
					Error("basic_media_error", design.ErrorMedia)
				})
			},
			func(t *testing.T, endpoints []*design.EndpointExpr) {
				if len(endpoints) != 2 {
					t.Errorf("expected 2 endpoints but got %d ", len(endpoints))
				}
				for i, e := range endpoints {
					assertEndpointDocs(t, e.Docs, "https://goa.design", "Optional description")
					//assert on first endpoint
					if i == 0 {
						if len(e.Errors) != 2 {
							t.Errorf("expected %d error definitions but got %d ", 2, len(e.Errors))
						}
						assertEndpointDescription(t, "Optional description", e.Description)
						assertEndpointError(t, e.Errors[0], "basic_error", design.ErrorMedia)
						assertEndpointError(t, e.Errors[1], "basic_media_error", design.ErrorMedia)
						expectedMeta := design.MetadataExpr{
							"name": []string{"some value", "some other value"},
						}
						assertEndpointMetaData(t, e.Metadata, expectedMeta)
						expectedReq := &design.UserTypeExpr{
							TypeName:      "BasicRequest",
							AttributeExpr: &design.AttributeExpr{Description: "Optional description", Type: &design.Object{}}}
						assertEndpointRequestResponse(t, "Request", e.Request, expectedReq)
						expectedRes := &design.UserTypeExpr{
							TypeName:      "BasicResponse",
							AttributeExpr: &design.AttributeExpr{Description: "Optional description", Type: &design.Object{}}}
						assertEndpointRequestResponse(t, "Response", e.Response, expectedRes)
					} else {
						//assert on second endpoint
						if len(e.Errors) != 1 {
							t.Errorf("expected %d error definitions but got %d ", 1, len(e.Errors))
						}
						if e.Description != "" {
							t.Errorf("no endpoint Description was defined expected an empty Description but got %s", e.Description)
						}
						if len(e.Metadata) != 0 {
							t.Errorf("no endpoint Metadata defined expected an empty Metadata but got %v ", e.Metadata)
						}
						assertEndpointError(t, e.Errors[0], "basic_media_error", design.ErrorMedia)
						expectedReq := &design.UserTypeExpr{TypeName: "AnotherRequest", AttributeExpr: &design.AttributeExpr{Type: design.String}}
						assertEndpointRequestResponse(t, "Request", e.Request, expectedReq)
						expectedRes := &design.UserTypeExpr{TypeName: "AnotherResponse", AttributeExpr: &design.AttributeExpr{Type: design.String}}
						assertEndpointRequestResponse(t, "Response", e.Response, expectedRes)
					}
				}
			},
		},
	}
	//Run our tests
	for k, tc := range cases {
		t.Run(k, func(t *testing.T) {
			eval.Context = &eval.DSLContext{}
			eval.Execute(tc.DSL, tc.Expr)
			evalService := tc.Expr.(*design.ServiceExpr)
			if eval.Context.Errors != nil {
				t.Errorf("%s: Endpoint failed unexpectedly with %s", k, eval.Context.Errors)
			}
			tc.Assert(t, evalService.Endpoints)
		})
	}
}

//helper funcs
func assertEndpointDocs(t *testing.T, doc *design.DocsExpr, url, desc string) {
	if doc.Description != desc {
		t.Errorf("expected docs description '%s' to match '%s' ", desc, doc.Description)
	}
	if doc.URL != url {
		t.Errorf("expected docs url '%s' to match '%s' ", url, doc.URL)
	}
}

func assertEndpointDescription(t *testing.T, expectedDesc, actualDesc string) {
	if expectedDesc != actualDesc {
		t.Errorf("expected description '%s' to match '%s' ", actualDesc, expectedDesc)
	}
}

func assertEndpointError(t *testing.T, actual *design.ErrorExpr, name string, dt design.DataType) {
	if actual.Name != name {
		t.Errorf("expected error to have name %s but got %s ", name, actual.Name)
	}

	if actual.AttributeExpr.Type != dt {
		t.Errorf("expected the error DataType to be %v but got %v ", dt, actual.AttributeExpr.Type)
	}
}

func assertEndpointMetaData(t *testing.T, actual design.MetadataExpr, expected design.MetadataExpr) {
	for key, val := range actual {
		vals, ok := expected[key]
		if !ok {
			t.Errorf("metaData was missing expected key %s ", key)
			continue
		}
		for _, metaVal := range val {
			if !hasValue(vals, metaVal) {
				t.Errorf("metaData was missing expected value %s ", metaVal)
			}
		}
	}
}

func assertEndpointRequestResponse(t *testing.T, assertType string, actual design.DataType, expected *design.UserTypeExpr) {
	ut, ok := actual.(*design.UserTypeExpr)
	if !ok || ut == nil {
		t.Errorf("expected endpoint %s to be a *UserTypeExpr but got %v", assertType, reflect.TypeOf(ut))
		return
	}
	if ut.Name() != expected.Name() {
		t.Errorf("expected endpoint %s name %s to match %s", assertType, ut.Name(), expected.Name())
	}
	if ut.AttributeExpr.Type.Name() != expected.Type.Name() {
		t.Errorf("expected endpoint %s TypeName %s to match %s ", assertType, ut.Type.Name(), expected.Type.Name())
	}
	if ut.Description != expected.Description {
		t.Errorf("expected endpoint %s description %s to match %s", assertType, ut.Description, expected.Description)
	}

}
<commit_msg>remove for loop and expression<commit_after>package dsl_test

import (
	"testing"

	"reflect"

	"github.com/goadesign/goa/design"
	. "github.com/goadesign/goa/design/dsl"
	"github.com/goadesign/goa/eval"
)

func TestEndpoint(t *testing.T) {
	cases := map[string]struct {
		DSL    func()
		Assert func(t *testing.T, s []*design.EndpointExpr)
	}{
		"basic_usage": {
			func() {
				Endpoint("basic", func() {
					Description("Optional description")
					Docs(func() {
						Description("Optional description")
						URL("https://goa.design")
					})
					Request(func() {
						Description("Optional description")
						Attribute("required", design.String)
						Required("required")
					})
					Response(func() {
						Description("Optional description")
						Attribute("required", design.String)
						Required("required")
					})
					Error("basic_error")
					Error("basic_media_error", design.ErrorMedia)
					Metadata("name", "some value", "some other value")
				})
				Endpoint("another", func() {
					Docs(func() {
						Description("Optional description")
						URL("https://goa.design")
					})
					Request(design.String)
					Response(design.String)
					Error("basic_media_error", design.ErrorMedia)
				})
			},
			func(t *testing.T, endpoints []*design.EndpointExpr) {
				if len(endpoints) != 2 {
					t.Errorf("expected 2 endpoints but got %d ", len(endpoints))
				}
				//assert on first endpoint
				endpoint := endpoints[0]
				assertEndpointDocs(t, endpoint.Docs, "https://goa.design", "Optional description")
				if len(endpoint.Errors) != 2 {
					t.Errorf("expected %d error definitions but got %d ", 2, len(endpoint.Errors))
				}
				assertEndpointDescription(t, "Optional description", endpoint.Description)
				assertEndpointError(t, endpoint.Errors[0], "basic_error", design.ErrorMedia)
				assertEndpointError(t, endpoint.Errors[1], "basic_media_error", design.ErrorMedia)
				expectedMeta := design.MetadataExpr{
					"name": []string{"some value", "some other value"},
				}
				assertEndpointMetaData(t, endpoint.Metadata, expectedMeta)
				expectedReq := &design.UserTypeExpr{
					TypeName:      "BasicRequest",
					AttributeExpr: &design.AttributeExpr{Description: "Optional description", Type: &design.Object{}}}
				assertEndpointRequestResponse(t, "Request", endpoint.Request, expectedReq)
				expectedRes := &design.UserTypeExpr{
					TypeName:      "BasicResponse",
					AttributeExpr: &design.AttributeExpr{Description: "Optional description", Type: &design.Object{}}}
				assertEndpointRequestResponse(t, "Response", endpoint.Response, expectedRes)

				//assert on second endpoint
				endpoint = endpoints[1]
				if len(endpoint.Errors) != 1 {
					t.Errorf("expected %d error definitions but got %d ", 1, len(endpoint.Errors))
				}
				if endpoint.Description != "" {
					t.Errorf("no endpoint Description was defined expected an empty Description but got %s", endpoint.Description)
				}
				if len(endpoint.Metadata) != 0 {
					t.Errorf("no endpoint Metadata defined expected an empty Metadata but got %v ", endpoint.Metadata)
				}
				assertEndpointError(t, endpoint.Errors[0], "basic_media_error", design.ErrorMedia)
				expectedReq = &design.UserTypeExpr{TypeName: "AnotherRequest", AttributeExpr: &design.AttributeExpr{Type: design.String}}
				assertEndpointRequestResponse(t, "Request", endpoint.Request, expectedReq)
				expectedRes = &design.UserTypeExpr{TypeName: "AnotherResponse", AttributeExpr: &design.AttributeExpr{Type: design.String}}
				assertEndpointRequestResponse(t, "Response", endpoint.Response, expectedRes)
			},
		},
	}
	//Run our tests
	for k, tc := range cases {
		t.Run(k, func(t *testing.T) {
			eval.Context = &eval.DSLContext{}
			serviceExpr := &design.ServiceExpr{}
			eval.Execute(tc.DSL, serviceExpr)
			if eval.Context.Errors != nil {
				t.Errorf("%s: Endpoint failed unexpectedly with %s", k, eval.Context.Errors)
			}
			tc.Assert(t, serviceExpr.Endpoints)
		})
	}
}

//helper funcs
func assertEndpointDocs(t *testing.T, doc *design.DocsExpr, url, desc string) {
	if doc.Description != desc {
		t.Errorf("expected docs description '%s' to match '%s' ", desc, doc.Description)
	}
	if doc.URL != url {
		t.Errorf("expected docs url '%s' to match '%s' ", url, doc.URL)
	}
}

func assertEndpointDescription(t *testing.T, expectedDesc, actualDesc string) {
	if expectedDesc != actualDesc {
		t.Errorf("expected description '%s' to match '%s' ", actualDesc, expectedDesc)
	}
}

func assertEndpointError(t *testing.T, actual *design.ErrorExpr, name string, dt design.DataType) {
	if actual.Name != name {
		t.Errorf("expected error to have name %s but got %s ", name, actual.Name)
	}

	if actual.AttributeExpr.Type != dt {
		t.Errorf("expected the error DataType to be %v but got %v ", dt, actual.AttributeExpr.Type)
	}
}

func assertEndpointMetaData(t *testing.T, actual design.MetadataExpr, expected design.MetadataExpr) {
	for key, val := range actual {
		vals, ok := expected[key]
		if !ok {
			t.Errorf("metaData was missing expected key %s ", key)
			continue
		}
		for _, metaVal := range val {
			if !hasValue(vals, metaVal) {
				t.Errorf("metaData was missing expected value %s ", metaVal)
			}
		}
	}
}

func assertEndpointRequestResponse(t *testing.T, assertType string, actual design.DataType, expected *design.UserTypeExpr) {
	ut, ok := actual.(*design.UserTypeExpr)
	if !ok || ut == nil {
		t.Errorf("expected endpoint %s to be a *UserTypeExpr but got %v", assertType, reflect.TypeOf(ut))
		return
	}
	if ut.Name() != expected.Name() {
		t.Errorf("expected endpoint %s name %s to match %s", assertType, ut.Name(), expected.Name())
	}
	if ut.AttributeExpr.Type.Name() != expected.Type.Name() {
		t.Errorf("expected endpoint %s TypeName %s to match %s ", assertType, ut.Type.Name(), expected.Type.Name())
	}
	if ut.Description != expected.Description {
		t.Errorf("expected endpoint %s description %s to match %s", assertType, ut.Description, expected.Description)
	}

}
<|endoftext|>


<commit_before>package aeon

import (
	"fmt"

	"github.com/bitly/go-simplejson"

	"github.com/ninjasphere/go-ninja"
	"github.com/ninjasphere/go-ninja/devices"
	"github.com/ninjasphere/go-openzwave"
	"github.com/ninjasphere/go-openzwave/CC"
)

type illuminator struct {
	node       openzwave.Node
	light      *devices.LightDevice
	brightness uint8
}

func IlluminatorFactory(bus *ninja.DriverBus, node openzwave.Node) (openzwave.Device, error) {
	var ok bool

	device := &illuminator{node, nil, 0}

	productId := node.GetProductId()
	productDescription := node.GetProductDescription()

	sigs := simplejson.New()
	sigs.Set("ninja:manufacturer", productDescription.ManufacturerName)
	sigs.Set("ninja:productName", productDescription.ProductName)
	sigs.Set("ninja:productType", productDescription.ProductType)
	sigs.Set("ninja:thingType", "light")

	address := fmt.Sprintf(
		"%08x:%03d:%s:%s",
		node.GetHomeId(),
		node.GetId(),
		productId.ManufacturerId,
		productId.ProductId)

	label := node.GetNodeName()

	// initialize brightness from the current level

	device.brightness, ok = device.node.GetUint8Value(CC.SWITCH_MULTILEVEL, 1, 0)
	if !ok || device.brightness == 0 {
		// we have to reset brightness to 100 since we apply brightness when
		// we switch it on

		//
		// one implication of this is that if the controller is removed
		// then replaced, while the light is off, the original brightness
		// will be lost
		//

		device.brightness = 100
	}

	deviceBus, err := bus.AnnounceDevice(address, "light", label, sigs)
	if err != nil {
		return nil, err
	}

	device.light, err = devices.CreateLightDevice(label, deviceBus)
	if err != nil {
		return nil, err
	}

	if err := device.light.EnableOnOffChannel(); err != nil {
		return nil, err
	}

	if err := device.light.EnableBrightnessChannel(); err != nil {
		return nil, err
	}

	device.light.ApplyLightState = func(state *devices.LightDeviceState) error {
		return nil
	}

	device.light.ApplyOnOff = func(state bool) error {
		level := uint8(0)
		if state {
			level = device.brightness
		}
		if device.node.SetUint8Value(CC.SWITCH_MULTILEVEL, 1, 0, level) {
			return nil
		} else {
			return fmt.Errorf("Failed to change on/off state")
		}
	}

	device.light.ApplyBrightness = func(state float64) error {
		var err error = nil
		if state < 0 {
			state = 0
		} else if state > 1.0 {
			state = 1.0
		}
		level, ok := device.node.GetUint8Value(CC.SWITCH_MULTILEVEL, 1, 0)
		if ok {
			device.brightness = uint8(state * 100)
			if level > 0 {
				if !device.node.SetUint8Value(CC.SWITCH_MULTILEVEL, 1, 0, device.brightness) {
					err = fmt.Errorf("Failed to change brightness")
				}
			}
		} else {
			err = fmt.Errorf("Failed to read existing level from device")
		}
		return err
	}

	return device, nil
}
<commit_msg>Implement ApplyLightState.<commit_after>package aeon

import (
	"fmt"

	"github.com/bitly/go-simplejson"

	"github.com/ninjasphere/go-ninja"
	"github.com/ninjasphere/go-ninja/devices"
	"github.com/ninjasphere/go-openzwave"
	"github.com/ninjasphere/go-openzwave/CC"
)

type illuminator struct {
	node       openzwave.Node
	light      *devices.LightDevice
	brightness uint8
}

func IlluminatorFactory(bus *ninja.DriverBus, node openzwave.Node) (openzwave.Device, error) {
	var ok bool

	device := &illuminator{node, nil, 0}

	productId := node.GetProductId()
	productDescription := node.GetProductDescription()

	sigs := simplejson.New()
	sigs.Set("ninja:manufacturer", productDescription.ManufacturerName)
	sigs.Set("ninja:productName", productDescription.ProductName)
	sigs.Set("ninja:productType", productDescription.ProductType)
	sigs.Set("ninja:thingType", "light")

	address := fmt.Sprintf(
		"%08x:%03d:%s:%s",
		node.GetHomeId(),
		node.GetId(),
		productId.ManufacturerId,
		productId.ProductId)

	label := node.GetNodeName()

	// initialize brightness from the current level

	device.brightness, ok = device.node.GetUint8Value(CC.SWITCH_MULTILEVEL, 1, 0)
	if !ok || device.brightness == 0 {
		// we have to reset brightness to 100 since we apply brightness when
		// we switch it on

		//
		// one implication of this is that if the controller is removed
		// then replaced, while the light is off, the original brightness
		// will be lost
		//

		device.brightness = 100
	}

	deviceBus, err := bus.AnnounceDevice(address, "light", label, sigs)
	if err != nil {
		return nil, err
	}

	device.light, err = devices.CreateLightDevice(label, deviceBus)
	if err != nil {
		return nil, err
	}

	if err := device.light.EnableOnOffChannel(); err != nil {
		return nil, err
	}

	if err := device.light.EnableBrightnessChannel(); err != nil {
		return nil, err
	}

	device.light.ApplyOnOff = func(state bool) error {
		level := uint8(0)
		if state {
			level = device.brightness
		}
		if device.node.SetUint8Value(CC.SWITCH_MULTILEVEL, 1, 0, level) {
			return nil
		} else {
			return fmt.Errorf("Failed to change on/off state")
		}
	}

	device.light.ApplyBrightness = func(state float64) error {
		var err error = nil
		if state < 0 {
			state = 0
		} else if state > 1.0 {
			state = 1.0
		}
		level, ok := device.node.GetUint8Value(CC.SWITCH_MULTILEVEL, 1, 0)
		if ok {
			device.brightness = uint8(state * 100)
			if level > 0 {
				if !device.node.SetUint8Value(CC.SWITCH_MULTILEVEL, 1, 0, device.brightness) {
					err = fmt.Errorf("Failed to change brightness")
				}
			}
		} else {
			err = fmt.Errorf("Failed to read existing level from device")
		}
		return err
	}

	device.light.ApplyLightState = func(state *devices.LightDeviceState) error {
		device.light.ApplyOnOff(*state.OnOff)
		device.light.ApplyBrightness(*state.Brightness)
		return nil
	}

	return device, nil
}
<|endoftext|>


<commit_before>package quoter

import (
	"fmt"
	"github.com/bwmarrin/discordgo"
	"log"
	"strconv"
)

type Quoter struct{}

func NewQuoter() *Quoter {
	return &Quoter{}
}

func (q *Quoter) Subscribe(s *discordgo.Session) {
	s.AddHandler(q.MessageReactionAdd)
}

// GetInfo returns info for command
func (q *Quoter) GetInfo() map[string]string {
	return map[string]string{
		"quoter": "Use `:copyright:` reaction on first message of message block to quote it using bot",
	}
}

func (q *Quoter) MessageReactionAdd(s *discordgo.Session, mr *discordgo.MessageReactionAdd) {
	if mr.Emoji.Name != "©" {
		return
	}

	convertedID, err := strconv.ParseInt(mr.MessageID, 10, 64)

	if err != nil {
		log.Println("Error converting ID: ", err)
		return
	}

	messageID := fmt.Sprintf("%v", convertedID-1)

	messages, err := s.ChannelMessages(mr.ChannelID, 100, "", messageID, "")

	if err != nil {
		log.Println("Error getting message: ", err)
		return
	}

	quoter, err := s.User(mr.UserID)

	if err != nil {
		log.Println("Error getting user: ", err)
		return
	}

	content := ""

	lastIndex := len(messages) - 1

	for i := lastIndex; i >= 0; i-- {
		if messages[i].Author.ID !=
			messages[lastIndex].Author.ID {
			break
		}

		content += messages[i].Content + "\n"
	}

	embed := &discordgo.MessageEmbed{
		Fields: []*discordgo.MessageEmbedField{
			{Name: "Quoter", Value: quoter.Username},
			{Name: "Sender", Value: "<@" + messages[lastIndex].Author.ID + ">"},
			{Name: "Message", Value: content},
		},
	}

	_, err = s.ChannelMessageSendEmbed(mr.ChannelID, embed)

	if err != nil {
		log.Println("Error getting user: ", err)
		return
	}
}
<commit_msg>get attachment urls<commit_after>package quoter

import (
	"fmt"
	"github.com/bwmarrin/discordgo"
	"log"
	"strconv"
)

type Quoter struct{}

func NewQuoter() *Quoter {
	return &Quoter{}
}

func (q *Quoter) Subscribe(s *discordgo.Session) {
	s.AddHandler(q.MessageReactionAdd)
}

// GetInfo returns info for command
func (q *Quoter) GetInfo() map[string]string {
	return map[string]string{
		"quoter": "Use `:copyright:` reaction on first message of message block to quote it using bot",
	}
}

func (q *Quoter) MessageReactionAdd(s *discordgo.Session, mr *discordgo.MessageReactionAdd) {
	if mr.Emoji.Name != "©" {
		return
	}

	convertedID, err := strconv.ParseInt(mr.MessageID, 10, 64)

	if err != nil {
		log.Println("Error converting ID: ", err)
		return
	}

	messageID := fmt.Sprintf("%v", convertedID-1)

	messages, err := s.ChannelMessages(mr.ChannelID, 100, "", messageID, "")

	if err != nil {
		log.Println("Error getting message: ", err)
		return
	}

	quoter, err := s.User(mr.UserID)

	if err != nil {
		log.Println("Error getting user: ", err)
		return
	}

	content := ""

	lastIndex := len(messages) - 1

	for i := lastIndex; i >= 0; i-- {
		if messages[i].Author.ID != messages[lastIndex].Author.ID {
			break
		}

		content += messages[i].Content + "\n"

		for _, at := range messages[i].Attachments {
			if at != nil {
				content += at.URL + "\n"
			}
		}
	}

	embed := &discordgo.MessageEmbed{
		Fields: []*discordgo.MessageEmbedField{
			{Name: "Quoter", Value: quoter.Username},
			{Name: "Sender", Value: "<@" + messages[lastIndex].Author.ID + ">"},
			{Name: "Message", Value: content},
		},
	}

	_, err = s.ChannelMessageSendEmbed(mr.ChannelID, embed)

	if err != nil {
		log.Println("Error getting user: ", err)
		return
	}
}
<|endoftext|>


<commit_before>package atlas

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"strings"
)

// MeasurementResp contains all the results of the measurements
type MeasurementResp struct {
	Measurements []int
}

// NewMeasurement create a new MeasurementRequest and fills some fields
func (c *Client) NewMeasurement() (req *MeasurementRequest) {
	var defs []Definition

	ps := NewProbeSet(c.config.PoolSize, c.config.AreaType, c.config.AreaValue, c.config.Tags)
	req = &MeasurementRequest{
		Definitions: defs,
		IsOneoff:    true,
		Probes:      []ProbeSet{ps},
	}
	c.verbose("probes: %#v", req.Probes)
	return
}

func isPositive(tag string) (string, bool) {
	bare := tag

	if tag == "" {
		return "", true
	}

	if tag[0] == '+' || tag[0] == '-' || tag[0] == '!' {
		bare = tag[1:]
	}

	if tag[0] == '-' || tag[0] == '!' {
		return bare, false
	}
	return bare, true
}

// splitTags analyse tags values:
//   +tag / tag  ==> tags_include
//   -tag / !tag ==> tags_exclude
func splitTags(tags string) (in, out string) {
	var (
		aIn  []string
		aOut []string
	)

	all := strings.Split(tags, ",")
	if len(all) == 0 {
		return "", ""
	}

	for _, tag := range all {
		if bare, yes := isPositive(tag); yes {
			aIn = append(aIn, bare)
		} else {
			aOut = append(aOut, bare)
		}
	}
	return strings.Join(aIn, ","), strings.Join(aOut, ",")
}

// NewProbeSet create a set of probes for later requests
func NewProbeSet(howmany int, settype, value string, tags string) (ps ProbeSet) {
	var aIn, aOut string

	if howmany == 0 {
		howmany = 10
	}

	if settype == "" {
		settype = "area"
	}

	if value == "" {
		value = "WW"
	}

	// If tags were specified, analyze them
	if tags != "" {
		aIn, aOut = splitTags(tags)
	}

	ps = ProbeSet{
		Requested:   howmany,
		Type:        settype,
		Value:       value,
		TagsInclude: aIn,
		TagsExclude: aOut,
	}
	return
}

// AddDefinition create a new MeasurementRequest and fills some fields
func (m *MeasurementRequest) AddDefinition(fields map[string]string) *MeasurementRequest {
	def := new(Definition)
	err := FillDefinition(def, fields)
	if err == nil {
		m.Definitions = append(m.Definitions, *def)
	}
	return m
}

// InsertTags add tags to a measurement definition
func (d *Definition) InsertTags(stags string) {
	var tags []string

	if stags != "" {
		tags = strings.Split(stags, ",")
		d.Tags = tags
	}
}

// createMeasurement creates a measurement for all types
func (c *Client) createMeasurement(t string, d *MeasurementRequest) (m *MeasurementResp, err error) {
	opts := make(map[string]string)
	opts = c.addAPIKey(opts)
	req := c.prepareRequest("POST", fmt.Sprintf("measurements/%s", t), opts)

	body, err := json.Marshal(d)
	if err != nil {
		return
	}

	buf := bytes.NewReader(body)
	req.Body = ioutil.NopCloser(buf)
	req.ContentLength = int64(buf.Len())

	c.verbose("req: %#v", req)
	c.verbose("body: %s", body)
	resp, err := c.call(req)
	c.verbose("resp: %v", resp)
	if err != nil {
		c.log.Printf("err: %v", err)
		//return
	}

	err = c.handleAPIResponsese(resp)
	if err != nil {
		return
	}

	m = &MeasurementResp{}
	rbody, _ := ioutil.ReadAll(resp.Body)
	defer resp.Body.Close()

	err = json.Unmarshal(rbody, m)
	// Only display if debug/verbose
	c.verbose("m: %v\nresp: %#v\nd: %v\n", m, string(rbody), d)
	if err != nil {
		err = fmt.Errorf("err: %v - m:%v", err, m)
		return
	}

	return
}

// DNS creates a measurement
func (c *Client) DNS(d *MeasurementRequest) (m *MeasurementResp, err error) {
	return c.createMeasurement("dns", d)
}

// HTTP creates a measurement
func (c *Client) HTTP(d *MeasurementRequest) (m *MeasurementResp, err error) {
	return c.createMeasurement("http", d)
}

// NTP creates a measurement
func (c *Client) NTP(d *MeasurementRequest) (m *MeasurementResp, err error) {
	return c.createMeasurement("ntp", d)
}

// Ping creates a measurement
func (c *Client) Ping(d *MeasurementRequest) (m *MeasurementResp, err error) {
	return c.createMeasurement("ping", d)
}

// SSLCert creates a measurement
func (c *Client) SSLCert(d *MeasurementRequest) (m *MeasurementResp, err error) {
	return c.createMeasurement("sslcert", d)
}

// Traceroute creates a measurement
func (c *Client) Traceroute(d *MeasurementRequest) (m *MeasurementResp, err error) {
	return c.createMeasurement("traceroute", d)
}
<commit_msg>Retire InsertTags() before it is used.<commit_after>package atlas

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"strings"
)

// MeasurementResp contains all the results of the measurements
type MeasurementResp struct {
	Measurements []int
}

// NewMeasurement create a new MeasurementRequest and fills some fields
func (c *Client) NewMeasurement() (req *MeasurementRequest) {
	var defs []Definition

	ps := NewProbeSet(c.config.PoolSize, c.config.AreaType, c.config.AreaValue, c.config.Tags)
	req = &MeasurementRequest{
		Definitions: defs,
		IsOneoff:    true,
		Probes:      []ProbeSet{ps},
	}
	c.verbose("probes: %#v", req.Probes)
	return
}

func isPositive(tag string) (string, bool) {
	bare := tag

	if tag == "" {
		return "", true
	}

	if tag[0] == '+' || tag[0] == '-' || tag[0] == '!' {
		bare = tag[1:]
	}

	if tag[0] == '-' || tag[0] == '!' {
		return bare, false
	}
	return bare, true
}

// splitTags analyse tags values:
//   +tag / tag  ==> tags_include
//   -tag / !tag ==> tags_exclude
func splitTags(tags string) (in, out string) {
	var (
		aIn  []string
		aOut []string
	)

	all := strings.Split(tags, ",")
	if len(all) == 0 {
		return "", ""
	}

	for _, tag := range all {
		if bare, yes := isPositive(tag); yes {
			aIn = append(aIn, bare)
		} else {
			aOut = append(aOut, bare)
		}
	}
	return strings.Join(aIn, ","), strings.Join(aOut, ",")
}

// NewProbeSet create a set of probes for later requests
func NewProbeSet(howmany int, settype, value string, tags string) (ps ProbeSet) {
	var aIn, aOut string

	if howmany == 0 {
		howmany = 10
	}

	if settype == "" {
		settype = "area"
	}

	if value == "" {
		value = "WW"
	}

	// If tags were specified, analyze them
	if tags != "" {
		aIn, aOut = splitTags(tags)
	}

	ps = ProbeSet{
		Requested:   howmany,
		Type:        settype,
		Value:       value,
		TagsInclude: aIn,
		TagsExclude: aOut,
	}
	return
}

// AddDefinition create a new MeasurementRequest and fills some fields
func (m *MeasurementRequest) AddDefinition(fields map[string]string) *MeasurementRequest {
	def := new(Definition)
	err := FillDefinition(def, fields)
	if err == nil {
		m.Definitions = append(m.Definitions, *def)
	}
	return m
}

// createMeasurement creates a measurement for all types
func (c *Client) createMeasurement(t string, d *MeasurementRequest) (m *MeasurementResp, err error) {
	opts := make(map[string]string)
	opts = c.addAPIKey(opts)
	req := c.prepareRequest("POST", fmt.Sprintf("measurements/%s", t), opts)

	body, err := json.Marshal(d)
	if err != nil {
		return
	}

	buf := bytes.NewReader(body)
	req.Body = ioutil.NopCloser(buf)
	req.ContentLength = int64(buf.Len())

	c.verbose("req: %#v", req)
	c.verbose("body: %s", body)
	resp, err := c.call(req)
	c.verbose("resp: %v", resp)
	if err != nil {
		c.log.Printf("err: %v", err)
		//return
	}

	err = c.handleAPIResponsese(resp)
	if err != nil {
		return
	}

	m = &MeasurementResp{}
	rbody, _ := ioutil.ReadAll(resp.Body)
	defer resp.Body.Close()

	err = json.Unmarshal(rbody, m)
	// Only display if debug/verbose
	c.verbose("m: %v\nresp: %#v\nd: %v\n", m, string(rbody), d)
	if err != nil {
		err = fmt.Errorf("err: %v - m:%v", err, m)
		return
	}

	return
}

// DNS creates a measurement
func (c *Client) DNS(d *MeasurementRequest) (m *MeasurementResp, err error) {
	return c.createMeasurement("dns", d)
}

// HTTP creates a measurement
func (c *Client) HTTP(d *MeasurementRequest) (m *MeasurementResp, err error) {
	return c.createMeasurement("http", d)
}

// NTP creates a measurement
func (c *Client) NTP(d *MeasurementRequest) (m *MeasurementResp, err error) {
	return c.createMeasurement("ntp", d)
}

// Ping creates a measurement
func (c *Client) Ping(d *MeasurementRequest) (m *MeasurementResp, err error) {
	return c.createMeasurement("ping", d)
}

// SSLCert creates a measurement
func (c *Client) SSLCert(d *MeasurementRequest) (m *MeasurementResp, err error) {
	return c.createMeasurement("sslcert", d)
}

// Traceroute creates a measurement
func (c *Client) Traceroute(d *MeasurementRequest) (m *MeasurementResp, err error) {
	return c.createMeasurement("traceroute", d)
}
<|endoftext|>