<commit_before>package main

import (
	"fmt"
	"image/color"
	"log"
	"math/rand"
	"sync"

	"github.com/paked/engi"
	"github.com/paked/engi/ecs"
)

type PongGame struct{}

var (
	basicFont *engi.Font
)

func (pong *PongGame) Preload() {
	engi.Files.AddFromDir("assets", true)
}

func (pong *PongGame) Setup(w *ecs.World) {
	engi.SetBg(color.Black)
	w.AddSystem(&engi.RenderSystem{})
	w.AddSystem(&engi.CollisionSystem{})
	w.AddSystem(&SpeedSystem{})
	w.AddSystem(&ControlSystem{})
	w.AddSystem(&BallSystem{})
	w.AddSystem(&ScoreSystem{})

	basicFont = (&engi.Font{URL: "Roboto-Regular.ttf", Size: 32, FG: color.NRGBA{255, 255, 255, 255}})
	if err := basicFont.CreatePreloaded(); err != nil {
		log.Fatalln("Could not load font:", err)
	}

	ball := ecs.NewEntity([]string{"RenderSystem", "CollisionSystem", "SpeedSystem", "BallSystem"})
	ballTexture := engi.Files.Image("ball.png")
	ballRender := engi.NewRenderComponent(ballTexture, engi.Point{2, 2}, "ball")
	ballSpace := &engi.SpaceComponent{engi.Point{(engi.Width() - ballTexture.Width()) / 2, (engi.Height() - ballTexture.Height()) / 2}, ballTexture.Width() * ballRender.Scale().X, ballTexture.Height() * ballRender.Scale().Y}
	ballCollision := &engi.CollisionComponent{Main: true, Solid: true}
	ballSpeed := &SpeedComponent{}
	ballSpeed.Point = engi.Point{300, 100}

	ball.AddComponent(ballRender)
	ball.AddComponent(ballSpace)
	ball.AddComponent(ballCollision)
	ball.AddComponent(ballSpeed)
	err := w.AddEntity(ball)
	if err != nil {
		log.Println(err)
	}

	score := ecs.NewEntity([]string{"RenderSystem", "ScoreSystem"})

	scoreRender := engi.NewRenderComponent(basicFont.Render(" "), engi.Point{1, 1}, "YOLO <3")

	scoreSpace := &engi.SpaceComponent{engi.Point{100, 100}, 100, 100}
	score.AddComponent(scoreRender)
	score.AddComponent(scoreSpace)
	err = w.AddEntity(score)
	if err != nil {
		log.Println(err)
	}

	schemes := []string{"WASD", ""}
	for i := 0; i < 2; i++ {
		paddle := ecs.NewEntity([]string{"RenderSystem", "CollisionSystem", "ControlSystem"})
		paddleTexture := engi.Files.Image("paddle.png")
		paddleRender := engi.NewRenderComponent(paddleTexture, engi.Point{2, 2}, "paddle")
		x := float32(0)
		if i != 0 {
			x = 800 - 16
		}

		paddleSpace := &engi.SpaceComponent{engi.Point{x, (engi.Height() - paddleTexture.Height()) / 2}, paddleRender.Scale().X * paddleTexture.Width(), paddleRender.Scale().Y * paddleTexture.Height()}
		paddleControl := &ControlComponent{schemes[i]}
		paddleCollision := &engi.CollisionComponent{Main: false, Solid: true}
		paddle.AddComponent(paddleRender)
		paddle.AddComponent(paddleSpace)
		paddle.AddComponent(paddleControl)
		paddle.AddComponent(paddleCollision)
		err = w.AddEntity(paddle)
		if err != nil {
			log.Println(err)
		}
	}
}

func (*PongGame) Hide()        {}
func (*PongGame) Show()        {}
func (*PongGame) Type() string { return "PongGame" }

type SpeedSystem struct {
	*ecs.System
}

func (ms *SpeedSystem) New(*ecs.World) {
	ms.System = ecs.NewSystem()
	engi.Mailbox.Listen("CollisionMessage", func(message engi.Message) {
		log.Println("collision")
		collision, isCollision := message.(engi.CollisionMessage)
		if isCollision {
			var speed *SpeedComponent
			if !collision.Entity.Component(&speed) {
				return
			}

			speed.X *= -1
		}
	})
}

func (*SpeedSystem) Type() string {
	return "SpeedSystem"
}

func (ms *SpeedSystem) Update(entity *ecs.Entity, dt float32) {
	var speed *SpeedComponent
	var space *engi.SpaceComponent
	if !entity.Component(&speed) || !entity.Component(&space) {
		return
	}
	space.Position.X += speed.X * dt
	space.Position.Y += speed.Y * dt
}

func (ms *SpeedSystem) Receive(message engi.Message) {}

type SpeedComponent struct {
	engi.Point
}

func (*SpeedComponent) Type() string {
	return "SpeedComponent"
}

type BallSystem struct {
	*ecs.System
}

func (bs *BallSystem) New(*ecs.World) {
	bs.System = ecs.NewSystem()
}

func (BallSystem) Type() string {
	return "BallSystem"
}

func (bs *BallSystem) Update(entity *ecs.Entity, dt float32) {
	var space *engi.SpaceComponent
	var speed *SpeedComponent
	if !entity.Component(&space) || !entity.Component(&speed) {
		return
	}

	if space.Position.X < 0 {
		engi.Mailbox.Dispatch(ScoreMessage{1})

		space.Position.X = 400 - 16
		space.Position.Y = 400 - 16
		speed.X = 800 * rand.Float32()
		speed.Y = 800 * rand.Float32()
	}

	if space.Position.Y < 0 {
		space.Position.Y = 0
		speed.Y *= -1
	}

	if space.Position.X > (800 - 16) {
		engi.Mailbox.Dispatch(ScoreMessage{2})

		space.Position.X = 400 - 16
		space.Position.Y = 400 - 16
		speed.X = 800 * rand.Float32()
		speed.Y = 800 * rand.Float32()
	}

	if space.Position.Y > (800 - 16) {
		space.Position.Y = 800 - 16
		speed.Y *= -1
	}
}

type ControlSystem struct {
	*ecs.System
}

func (ControlSystem) Type() string {
	return "ControlSystem"
}
func (c *ControlSystem) New(*ecs.World) {
	c.System = ecs.NewSystem()
}

func (c *ControlSystem) Update(entity *ecs.Entity, dt float32) {
	//Check scheme
	// -Move entity based on that
	var control *ControlComponent
	var space *engi.SpaceComponent

	if !entity.Component(&space) || !entity.Component(&control) {
		return
	}
	up := false
	down := false
	if control.Scheme == "WASD" {
		up = engi.Keys.Get(engi.W).Down()
		down = engi.Keys.Get(engi.S).Down()
	} else {
		up = engi.Keys.Get(engi.ArrowUp).Down()
		down = engi.Keys.Get(engi.ArrowDown).Down()
	}

	if up {
		space.Position.Y -= 800 * dt
	}

	if down {
		space.Position.Y += 800 * dt
	}

}

type ControlComponent struct {
	Scheme string
}

func (*ControlComponent) Type() string {
	return "ControlComponent"
}

type ScoreSystem struct {
	*ecs.System
	PlayerOneScore, PlayerTwoScore int
	upToDate                       bool
	scoreLock                      sync.RWMutex
}

func (ScoreSystem) Type() string {
	return "ScoreSystem"
}

func (sc *ScoreSystem) New(*ecs.World) {
	sc.upToDate = true
	sc.System = ecs.NewSystem()
	engi.Mailbox.Listen("ScoreMessage", func(message engi.Message) {
		scoreMessage, isScore := message.(ScoreMessage)
		if !isScore {
			return
		}

		sc.scoreLock.Lock()
		if scoreMessage.Player != 1 {
			sc.PlayerOneScore += 1
		} else {
			sc.PlayerTwoScore += 1
		}
		log.Println("The score is now", sc.PlayerOneScore, "vs", sc.PlayerTwoScore)
		sc.upToDate = false
		sc.scoreLock.Unlock()
	})
}

func (c *ScoreSystem) Update(entity *ecs.Entity, dt float32) {
	var render *engi.RenderComponent
	var space *engi.SpaceComponent

	if !entity.Component(&render) || !entity.Component(&space) {
		return
	}

	if !c.upToDate {
		c.scoreLock.RLock()
		render.Label = fmt.Sprintf("%v vs %v", c.PlayerOneScore, c.PlayerTwoScore)
		c.upToDate = true
		c.scoreLock.RUnlock()

		render.SetDrawable(basicFont.Render(render.Label))
		width := len(render.Label) * 20

		space.Position.X = float32(400 - (width / 2))
	}
}

type ScoreMessage struct {
	Player int
}

func (ScoreMessage) Type() string {
	return "ScoreMessage"
}

func main() {
	opts := engi.RunOptions{
		Title:         "Pong Demo",
		Width:         800,
		Height:        800,
		ScaleOnResize: true,
	}
	engi.Open(opts, &PongGame{})
}
<commit_msg>Check to ensure paddles don't go out of the screen<commit_after>package main

import (
	"fmt"
	"image/color"
	"log"
	"math/rand"
	"sync"

	"github.com/paked/engi"
	"github.com/paked/engi/ecs"
)

type PongGame struct{}

var (
	basicFont *engi.Font
)

func (pong *PongGame) Preload() {
	engi.Files.AddFromDir("assets", true)
}

func (pong *PongGame) Setup(w *ecs.World) {
	engi.SetBg(color.Black)
	w.AddSystem(&engi.RenderSystem{})
	w.AddSystem(&engi.CollisionSystem{})
	w.AddSystem(&SpeedSystem{})
	w.AddSystem(&ControlSystem{})
	w.AddSystem(&BallSystem{})
	w.AddSystem(&ScoreSystem{})

	basicFont = (&engi.Font{URL: "Roboto-Regular.ttf", Size: 32, FG: color.NRGBA{255, 255, 255, 255}})
	if err := basicFont.CreatePreloaded(); err != nil {
		log.Fatalln("Could not load font:", err)
	}

	ball := ecs.NewEntity([]string{"RenderSystem", "CollisionSystem", "SpeedSystem", "BallSystem"})
	ballTexture := engi.Files.Image("ball.png")
	ballRender := engi.NewRenderComponent(ballTexture, engi.Point{2, 2}, "ball")
	ballSpace := &engi.SpaceComponent{engi.Point{(engi.Width() - ballTexture.Width()) / 2, (engi.Height() - ballTexture.Height()) / 2}, ballTexture.Width() * ballRender.Scale().X, ballTexture.Height() * ballRender.Scale().Y}
	ballCollision := &engi.CollisionComponent{Main: true, Solid: true}
	ballSpeed := &SpeedComponent{}
	ballSpeed.Point = engi.Point{300, 100}

	ball.AddComponent(ballRender)
	ball.AddComponent(ballSpace)
	ball.AddComponent(ballCollision)
	ball.AddComponent(ballSpeed)
	err := w.AddEntity(ball)
	if err != nil {
		log.Println(err)
	}

	score := ecs.NewEntity([]string{"RenderSystem", "ScoreSystem"})

	scoreRender := engi.NewRenderComponent(basicFont.Render(" "), engi.Point{1, 1}, "YOLO <3")

	scoreSpace := &engi.SpaceComponent{engi.Point{100, 100}, 100, 100}
	score.AddComponent(scoreRender)
	score.AddComponent(scoreSpace)
	err = w.AddEntity(score)
	if err != nil {
		log.Println(err)
	}

	schemes := []string{"WASD", ""}
	for i := 0; i < 2; i++ {
		paddle := ecs.NewEntity([]string{"RenderSystem", "CollisionSystem", "ControlSystem"})
		paddleTexture := engi.Files.Image("paddle.png")
		paddleRender := engi.NewRenderComponent(paddleTexture, engi.Point{2, 2}, "paddle")
		x := float32(0)
		if i != 0 {
			x = 800 - 16
		}

		paddleSpace := &engi.SpaceComponent{engi.Point{x, (engi.Height() - paddleTexture.Height()) / 2}, paddleRender.Scale().X * paddleTexture.Width(), paddleRender.Scale().Y * paddleTexture.Height()}
		paddleControl := &ControlComponent{schemes[i]}
		paddleCollision := &engi.CollisionComponent{Main: false, Solid: true}
		paddle.AddComponent(paddleRender)
		paddle.AddComponent(paddleSpace)
		paddle.AddComponent(paddleControl)
		paddle.AddComponent(paddleCollision)
		err = w.AddEntity(paddle)
		if err != nil {
			log.Println(err)
		}
	}
}

func (*PongGame) Hide()        {}
func (*PongGame) Show()        {}
func (*PongGame) Type() string { return "PongGame" }

type SpeedSystem struct {
	*ecs.System
}

func (ms *SpeedSystem) New(*ecs.World) {
	ms.System = ecs.NewSystem()
	engi.Mailbox.Listen("CollisionMessage", func(message engi.Message) {
		log.Println("collision")
		collision, isCollision := message.(engi.CollisionMessage)
		if isCollision {
			var speed *SpeedComponent
			if !collision.Entity.Component(&speed) {
				return
			}

			speed.X *= -1
		}
	})
}

func (*SpeedSystem) Type() string {
	return "SpeedSystem"
}

func (ms *SpeedSystem) Update(entity *ecs.Entity, dt float32) {
	var speed *SpeedComponent
	var space *engi.SpaceComponent
	if !entity.Component(&speed) || !entity.Component(&space) {
		return
	}
	space.Position.X += speed.X * dt
	space.Position.Y += speed.Y * dt
}

func (ms *SpeedSystem) Receive(message engi.Message) {}

type SpeedComponent struct {
	engi.Point
}

func (*SpeedComponent) Type() string {
	return "SpeedComponent"
}

type BallSystem struct {
	*ecs.System
}

func (bs *BallSystem) New(*ecs.World) {
	bs.System = ecs.NewSystem()
}

func (BallSystem) Type() string {
	return "BallSystem"
}

func (bs *BallSystem) Update(entity *ecs.Entity, dt float32) {
	var space *engi.SpaceComponent
	var speed *SpeedComponent
	if !entity.Component(&space) || !entity.Component(&speed) {
		return
	}

	if space.Position.X < 0 {
		engi.Mailbox.Dispatch(ScoreMessage{1})

		space.Position.X = 400 - 16
		space.Position.Y = 400 - 16
		speed.X = 800 * rand.Float32()
		speed.Y = 800 * rand.Float32()
	}

	if space.Position.Y < 0 {
		space.Position.Y = 0
		speed.Y *= -1
	}

	if space.Position.X > (800 - 16) {
		engi.Mailbox.Dispatch(ScoreMessage{2})

		space.Position.X = 400 - 16
		space.Position.Y = 400 - 16
		speed.X = 800 * rand.Float32()
		speed.Y = 800 * rand.Float32()
	}

	if space.Position.Y > (800 - 16) {
		space.Position.Y = 800 - 16
		speed.Y *= -1
	}
}

type ControlSystem struct {
	*ecs.System
}

func (ControlSystem) Type() string {
	return "ControlSystem"
}
func (c *ControlSystem) New(*ecs.World) {
	c.System = ecs.NewSystem()
}

func (c *ControlSystem) Update(entity *ecs.Entity, dt float32) {
	//Check scheme
	// -Move entity based on that
	var control *ControlComponent
	var space *engi.SpaceComponent

	if !entity.Component(&space) || !entity.Component(&control) {
		return
	}
	up := false
	down := false
	if control.Scheme == "WASD" {
		up = engi.Keys.Get(engi.W).Down()
		down = engi.Keys.Get(engi.S).Down()
	} else {
		up = engi.Keys.Get(engi.ArrowUp).Down()
		down = engi.Keys.Get(engi.ArrowDown).Down()
	}

	if up {
		if space.Position.Y > 0 {
			space.Position.Y -= 800 * dt
		}
	}

	if down {
		if (space.Height + space.Position.Y) < 800 {
			space.Position.Y += 800 * dt
		}
	}

}

type ControlComponent struct {
	Scheme string
}

func (*ControlComponent) Type() string {
	return "ControlComponent"
}

type ScoreSystem struct {
	*ecs.System
	PlayerOneScore, PlayerTwoScore int
	upToDate                       bool
	scoreLock                      sync.RWMutex
}

func (ScoreSystem) Type() string {
	return "ScoreSystem"
}

func (sc *ScoreSystem) New(*ecs.World) {
	sc.upToDate = true
	sc.System = ecs.NewSystem()
	engi.Mailbox.Listen("ScoreMessage", func(message engi.Message) {
		scoreMessage, isScore := message.(ScoreMessage)
		if !isScore {
			return
		}

		sc.scoreLock.Lock()
		if scoreMessage.Player != 1 {
			sc.PlayerOneScore += 1
		} else {
			sc.PlayerTwoScore += 1
		}
		log.Println("The score is now", sc.PlayerOneScore, "vs", sc.PlayerTwoScore)
		sc.upToDate = false
		sc.scoreLock.Unlock()
	})
}

func (c *ScoreSystem) Update(entity *ecs.Entity, dt float32) {
	var render *engi.RenderComponent
	var space *engi.SpaceComponent

	if !entity.Component(&render) || !entity.Component(&space) {
		return
	}

	if !c.upToDate {
		c.scoreLock.RLock()
		render.Label = fmt.Sprintf("%v vs %v", c.PlayerOneScore, c.PlayerTwoScore)
		c.upToDate = true
		c.scoreLock.RUnlock()

		render.SetDrawable(basicFont.Render(render.Label))
		width := len(render.Label) * 20

		space.Position.X = float32(400 - (width / 2))
	}
}

type ScoreMessage struct {
	Player int
}

func (ScoreMessage) Type() string {
	return "ScoreMessage"
}

func main() {
	opts := engi.RunOptions{
		Title:         "Pong Demo",
		Width:         800,
		Height:        800,
		ScaleOnResize: true,
	}
	engi.Open(opts, &PongGame{})
}
<|endoftext|>


<commit_before>package model

import (
	"api"
	"log"
	"net/http"
	"os"
	"io"
)

type FileManagementModel struct {
	fileEnv *FileEnvDef
}

var _ = (api.Model)(&FileManagementModel{})
var _ = log.Println

func NewFileManagementService(fileEnv *FileEnvDef) *api.Service {
	fileModel := &FileManagementModel{
		fileEnv: fileEnv,
	}

	return api.NewService(fileModel)
}

// api/file/list
// api/file/delete
// api/file/new
// api/file/download/path/to/file
// api/file/upload/path/to/file
func (self *FileManagementModel) Access(appKey string, token string) bool {
	return true
}

func (self *FileManagementModel) PrefixGetApiFileDownload(w http.ResponseWriter, r *http.Request, path string) error {
	fileName := self.fileEnv.Home + path

	file, err := os.Open(fileName)
	if err != nil {
		return err
	}
	defer file.Close()

	_, err = io.Copy(w, file)
	return err
}

func (self *FileManagementModel) PrefixGetApiFileList(w http.ResponseWriter, r *http.Request, path string) error {
	rep := fileStatReponse{
		Entries: make([]fileStatVO, 0),
	}

	dir, err := os.Open(self.fileEnv.Home + path)
	if err != nil {
		return err
	}

	var fileInfos []os.FileInfo
	if fileInfos, err = dir.Readdir(0); err != nil {
		return err
	}
	for _, fileInfo := range fileInfos {
		switch fileInfo.Name() {
		case ".", "..":
			continue
		}

		vo := fileStatVO{
			Name:    fileInfo.Name(),
			Size:    fileInfo.Size(),
			Mode:    int16(fileInfo.Mode()),
			ModTime: fileInfo.ModTime().Format("2006-01-02 15:04:05"),
			IsDir:   fileInfo.IsDir(),
		}

		if fileInfo.IsDir() {
			vo.Type = "Directory"
		} else {
			vo.Type = "File"
		}

		rep.Entries = append(rep.Entries, vo)
	}

	api.EncodeJson(w, &rep)
	return nil
}
<commit_msg>Update raspbeerypi dashboard.<commit_after>package model

import (
	"api"
	"log"
	"net/http"
	"os"
	"io"
)

type FileManagementModel struct {
	fileEnv *FileEnvDef
}

var _ = (api.Model)(&FileManagementModel{})
var _ = log.Println

func NewFileManagementService(fileEnv *FileEnvDef) *api.Service {
	if fileEnv.Home == "" {
		log.Fatal("file_env.home can not be empty!")
	}

	fileModel := &FileManagementModel{
		fileEnv: fileEnv,
	}

	return api.NewService(fileModel)
}

// api/file/{list|delete|new|download|upload}/path/to/file
func (self *FileManagementModel) Access(appKey string, token string) bool {
	return true
}

func (self *FileManagementModel) PrefixGetApiFileDownload(w http.ResponseWriter, r *http.Request, path string) error {
	fileName := self.fileEnv.Home + path

	file, err := os.Open(fileName)
	if err != nil {
		return err
	}
	defer file.Close()

	_, err = io.Copy(w, file)
	return err
}

func (self *FileManagementModel) PrefixGetApiFileList(w http.ResponseWriter, r *http.Request, path string) error {
	rep := fileStatReponse{
		Entries: make([]fileStatVO, 0),
	}

	dir, err := os.Open(self.fileEnv.Home + path)
	if err != nil {
		return err
	}
	defer dir.Close()

	var fileInfos []os.FileInfo
	if fileInfos, err = dir.Readdir(0); err != nil {
		return err
	}

	for _, fileInfo := range fileInfos {
		switch fileInfo.Name() {
		case ".", "..":
			continue
		}

		vo := fileStatVO{
			Name:    fileInfo.Name(),
			Size:    fileInfo.Size(),
			Mode:    int16(fileInfo.Mode()),
			ModTime: fileInfo.ModTime().Format("2006-01-02 15:04:05"),
			IsDir:   fileInfo.IsDir(),
		}

		if fileInfo.IsDir() {
			vo.Type = "Directory";
			if vo.Contain, err = getDirContain(self.fileEnv.Home + path + "/" + vo.Name); err != nil {
				return err
			}
		} else {
			vo.Type = "File";
			vo.Contain = -1;
		}

		rep.Entries = append(rep.Entries, vo)
	}

	api.EncodeJson(w, &rep)
	return nil
}

func getDirContain(dirName string) (int, error) {
	dir, err := os.Open(dirName)
	if err != nil {
		return 0, err
	}
	defer dir.Close()

	var fileInfos []os.FileInfo
	if fileInfos, err = dir.Readdir(0); err != nil {
		return 0, err
	}

	return len(fileInfos), nil
}
<|endoftext|>


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

package es5

// Note: nativenew is based on http://www.bennadel.com/blog/2291-invoking-a-native-javascript-constructor-using-call-or-apply.htm

// runtimeTemplate contains all the necessary code for wrapping generated modules into a complete Serulian
// runtime bundle.
const runtimeTemplate = `
window.Serulian = (function($global) {
  var $g = {};
  var $t = {
    'cast': function(value, type) {
      // TODO: implement cast checking.
      return value
    },

    'nativenew': function(type) {
      return function () {
        var newInstance = Object.create(type.prototype);
        newInstance = type.apply(newInstance, arguments) || newInstance;
        return newInstance;
      };
    },

    'property': function(isExtension, getter, opt_setter) {
      var count = isExtension ? 2 : 1;
      var f = function() {
        if (arguments.length == count) {
          return opt_setter.apply(this, arguments);
        } else {
          return getter.apply(this, arguments);
        }
      };

      f.$property = true;
      return f;
    },

    'dynamicaccess': function(obj, name) {
      if (obj == null || obj[name] == null) {
        return null;
      }

      var value = obj[name];
      if (typeof value == 'function' && value.$property) {
        return $promise.wrap(function() {
          return value.apply(obj, arguments);
        });
      }

      return value
    },

    'nullcompare': function(first, second) {
      return first == null ? second : first;
    },

  	'sm': function(caller) {
  		return {
        resources: {},
  			current: 0,
  			next: caller,

        pushr: function(value, name) {
          this.resources[name] = value;
        },

        popr: function(names) {
          var promises = [];

          for (var i = 0; i < arguments.length; ++i) {
            var name = arguments[i];
            if (this.resources[name]) {
              promises.push(this.resources[name].Release());
              delete this.resources[name];
            }
          }

          if (promises.length > 0) {
            return $promise.all(promises);
          } else {
            return $promise.resolve(null);
          }
        },

        popall: function() {
          for (var name in this.resources) {
            if (this.resources.hasOwnProperty(name)) {
              this.resources[name].Release();
            }
          }
        }
  		};
  	}
  };

  var $promise = {
  	'build': function(statemachine) {
  		return new Promise(function(resolve, reject) {
        statemachine.resolve = function(value) {
          statemachine.popall();
          statemachine.current = -1;
          resolve(value);
        };

        statemachine.reject = function(value) {
          statemachine.popall();
          statemachine.current = -1;
          reject(value);
        };

  			var continueFunc = function() {
  				if (statemachine.current < 0) {
  					return;
  				}

  				statemachine.next(continueFunc);
			  };

  			continueFunc();
        if (statemachine.current < 0) {
          statemachine.resolve(null);
        }
  		});
  	},

  	'all': function(promises) {
  		return Promise.all(promises);
  	},

  	'empty': function() {
  		return new Promise(function() {
  			resolve();
  		});
  	},

    'resolve': function(value) {
      return Promise.resolve(value);
    },

  	'wrap': function(func) {
  		return Promise.resolve(func());
  	},

    'translate': function(prom) {
       return {
          'then': function() {
             return prom.Then.apply(prom, arguments);
          },
          'catch': function() {
             return prom.Catch.apply(prom, arguments);
          }
       };
    }
  };

  var moduleInits = [];

  var $module = function(name, creator) {
  	var module = {};

    var parts = name.split('.');
    var current = $g;
    for (var i = 0; i < parts.length - 1; ++i) {
      if (!current[parts[i]]) {
        current[parts[i]] = {};
      }
      current = current[parts[i]]
    }

    current[parts[parts.length - 1]] = module;

  	module.$init = function(cpromise) {
  	  moduleInits.push(cpromise);
  	};

    module.$newtypebuilder = function(kind) {
      return function(name, hasGenerics, creator) {
        if (hasGenerics) {
          module[name] = function(genericargs) {
            var tpe = function() {};
            creator.apply(tpe, arguments);
            return tpe;
          };
        } else {
          var tpe = new Function("return function " + name + "() {};")();
          creator.call(tpe);
          module[name] = tpe;
        }
      };
    };

  	module.$class = module.$newtypebuilder('class');
  	module.$interface = module.$newtypebuilder('interface');

    module.$type = function(name, creator) {
      var cls = function() {};
      creator.call(cls);
      module[name] = cls;
    };

  	creator.call(module)
  };

  {{ range $idx, $kv := .Iter }}
  	{{ $kv.Value }}
  {{ end }}

  return $promise.all(moduleInits).then(function() {
  	return $g;
  });
})(window)
`
<commit_msg>Ensure all promise paths resolve<commit_after>// Copyright 2015 The Serulian Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package es5

// Note: nativenew is based on http://www.bennadel.com/blog/2291-invoking-a-native-javascript-constructor-using-call-or-apply.htm

// runtimeTemplate contains all the necessary code for wrapping generated modules into a complete Serulian
// runtime bundle.
const runtimeTemplate = `
window.Serulian = (function($global) {
  var $g = {};
  var $t = {
    'cast': function(value, type) {
      // TODO: implement cast checking.
      return value
    },

    'nativenew': function(type) {
      return function () {
        var newInstance = Object.create(type.prototype);
        newInstance = type.apply(newInstance, arguments) || newInstance;
        return newInstance;
      };
    },

    'property': function(isExtension, getter, opt_setter) {
      var count = isExtension ? 2 : 1;
      var f = function() {
        if (arguments.length == count) {
          return opt_setter.apply(this, arguments);
        } else {
          return getter.apply(this, arguments);
        }
      };

      f.$property = true;
      return f;
    },

    'dynamicaccess': function(obj, name) {
      if (obj == null || obj[name] == null) {
        return null;
      }

      var value = obj[name];
      if (typeof value == 'function' && value.$property) {
        return $promise.wrap(function() {
          return value.apply(obj, arguments);
        });
      }

      return value
    },

    'nullcompare': function(first, second) {
      return first == null ? second : first;
    },

  	'sm': function(caller) {
  		return {
        resources: {},
  			current: 0,
  			next: caller,

        pushr: function(value, name) {
          this.resources[name] = value;
        },

        popr: function(names) {
          var promises = [];

          for (var i = 0; i < arguments.length; ++i) {
            var name = arguments[i];
            if (this.resources[name]) {
              promises.push(this.resources[name].Release());
              delete this.resources[name];
            }
          }

          if (promises.length > 0) {
            return $promise.all(promises);
          } else {
            return $promise.resolve(null);
          }
        },

        popall: function() {
          for (var name in this.resources) {
            if (this.resources.hasOwnProperty(name)) {
              this.resources[name].Release();
            }
          }
        }
  		};
  	}
  };

  var $promise = {
  	'build': function(statemachine) {
  		return new Promise(function(resolve, reject) {
        statemachine.resolve = function(value) {
          statemachine.popall();
          statemachine.current = -1;
          resolve(value);
        };

        statemachine.reject = function(value) {
          statemachine.popall();
          statemachine.current = -1;
          reject(value);
        };

  			var continueFunc = function() {
  				if (statemachine.current < 0) {
  					return;
  				}

  				statemachine.next(callFunc);
			  };

        var callFunc = function() {
    			continueFunc();
          if (statemachine.current < 0) {
            statemachine.resolve(null);
          }
        };

        callFunc();
  		});
  	},

  	'all': function(promises) {
  		return Promise.all(promises);
  	},

  	'empty': function() {
  		return new Promise(function() {
  			resolve();
  		});
  	},

    'resolve': function(value) {
      return Promise.resolve(value);
    },

  	'wrap': function(func) {
  		return Promise.resolve(func());
  	},

    'translate': function(prom) {
       return {
          'then': function() {
             return prom.Then.apply(prom, arguments);
          },
          'catch': function() {
             return prom.Catch.apply(prom, arguments);
          }
       };
    }
  };

  var moduleInits = [];

  var $module = function(name, creator) {
  	var module = {};

    var parts = name.split('.');
    var current = $g;
    for (var i = 0; i < parts.length - 1; ++i) {
      if (!current[parts[i]]) {
        current[parts[i]] = {};
      }
      current = current[parts[i]]
    }

    current[parts[parts.length - 1]] = module;

  	module.$init = function(cpromise) {
  	  moduleInits.push(cpromise);
  	};

    module.$newtypebuilder = function(kind) {
      return function(name, hasGenerics, creator) {
        if (hasGenerics) {
          module[name] = function(genericargs) {
            var tpe = function() {};
            creator.apply(tpe, arguments);
            return tpe;
          };
        } else {
          var tpe = new Function("return function " + name + "() {};")();
          creator.call(tpe);
          module[name] = tpe;
        }
      };
    };

  	module.$class = module.$newtypebuilder('class');
  	module.$interface = module.$newtypebuilder('interface');

    module.$type = function(name, creator) {
      var cls = function() {};
      creator.call(cls);
      module[name] = cls;
    };

  	creator.call(module)
  };

  {{ range $idx, $kv := .Iter }}
  	{{ $kv.Value }}
  {{ end }}

  return $promise.all(moduleInits).then(function() {
  	return $g;
  });
})(window)
`
<|endoftext|>


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

package commands

import (
	"errors"
	"fmt"
	"strconv"

	"github.com/digitalocean/doctl"
	"github.com/digitalocean/doctl/commands/displayers"
	"github.com/digitalocean/doctl/do"
	"github.com/digitalocean/godo"
	"github.com/spf13/cobra"
)

// Domain creates the domain commands hierarchy.
func Domain() *Command {
	cmd := &Command{
		Command: &cobra.Command{
			Use:   "domain",
			Short: "domain commands",
			Long:  `Use the subcommands of 'doctl compute domain' to manage domains you have purchased from a domain name registrar that you are managing through the DigitalOcean DNS interface.`,
		},
	}

	cmdDomainCreate := CmdBuilderWithDocs(cmd, RunDomainCreate, "create <domain>", "Add a domain",`Use this command to add a domain to your account.`, Writer,
		aliasOpt("c"), displayerType(&displayers.Domain{}))
	AddStringFlag(cmdDomainCreate, doctl.ArgIPAddress, "", "", "IP address, creates an initial A record when provided")

	CmdBuilderWithDocs(cmd, RunDomainList, "list", "List domains",`Use this command to retrive a list of domains added to your account.`, Writer,
		aliasOpt("ls"), displayerType(&displayers.Domain{}))

	CmdBuilderWithDocs(cmd, RunDomainGet, "get <domain>", "Retrive a domain",`Use this command to retrive a specific domain on your account.`, Writer,
		aliasOpt("g"), displayerType(&displayers.Domain{}))

	cmdRunDomainDelete := CmdBuilderWithDocs(cmd, RunDomainDelete, "delete <domain>", "Delete a domain",`Use this command to delete a domain from your account. This is irreversible.`, Writer, aliasOpt("d", "rm"))
	AddBoolFlag(cmdRunDomainDelete, doctl.ArgForce, doctl.ArgShortForce, false, "Force domain delete")

	cmdRecord := &Command{
		Command: &cobra.Command{
			Use:   "records",
			Short: "manage domain DNS",
			Long:  "Use the subcommands of 'doctl compute domain records' to manage the DNS records for your domains",
		},
	}
	cmd.AddCommand(cmdRecord)

	CmdBuilderWithDocs(cmdRecord, RunRecordList, "list <domain>", "List DNS records for a domain",`Use this command to list the current DNS records for a domain.`, Writer,
		aliasOpt("ls"), displayerType(&displayers.DomainRecord{}))

	cmdRecordCreate := CmdBuilderWithDocs(cmdRecord, RunRecordCreate, "create <domain>", "Create a DNS record", `Use this command to create DNS records for a domain.`, Writer,
		aliasOpt("c"), displayerType(&displayers.DomainRecord{}))
	AddStringFlag(cmdRecordCreate, doctl.ArgRecordType, "", "", "Record type")
	AddStringFlag(cmdRecordCreate, doctl.ArgRecordName, "", "", "Record name")
	AddStringFlag(cmdRecordCreate, doctl.ArgRecordData, "", "", "Record data")
	AddIntFlag(cmdRecordCreate, doctl.ArgRecordPriority, "", 0, "Record priority")
	AddIntFlag(cmdRecordCreate, doctl.ArgRecordPort, "", 0, "Record port")
	AddIntFlag(cmdRecordCreate, doctl.ArgRecordTTL, "", 1800, "Record TTL")
	AddIntFlag(cmdRecordCreate, doctl.ArgRecordWeight, "", 0, "Record weight")
	AddIntFlag(cmdRecordCreate, doctl.ArgRecordFlags, "", 0, "Record flags")
	AddStringFlag(cmdRecordCreate, doctl.ArgRecordTag, "", "", "Record tag")

<<<<<<< HEAD
	cmdRunRecordDelete := CmdBuilderWithDocs(cmdRecord, RunRecordDelete, "delete <domain> <record-id>...", "delete DNS record", `Use this command to delete DNS records for a domain.`, Writer,
		aliasOpt("d"))
	AddBoolFlag(cmdRunRecordDelete, doctl.ArgForce, doctl.ArgShortForce, false, "Force record delete")

	cmdRecordUpdate := CmdBuilderWithDocs(cmdRecord, RunRecordUpdate, "update <domain>", "update DNS record", `Use this command to update or change DNS records for a domain.`, Writer,
=======
	cmdRunRecordDelete := CmdBuilderWithDocs(cmdRecord, RunRecordDelete, "delete <domain> <record-id>...", "Delete a DNS record",`Use this command to delete DNS records for a domain.`, Writer,
		aliasOpt("d"))
	AddBoolFlag(cmdRunRecordDelete, doctl.ArgForce, doctl.ArgShortForce, false, "Force record delete")

	cmdRecordUpdate := CmdBuilderWithDocs(cmdRecord, RunRecordUpdate, "update <domain>", "Update a DNS record",`Use this command to update or change DNS records for a domain.`, Writer,
>>>>>>> extend short descriptions, domains.go
		aliasOpt("u"), displayerType(&displayers.DomainRecord{}))
	AddIntFlag(cmdRecordUpdate, doctl.ArgRecordID, "", 0, "Record ID")
	AddStringFlag(cmdRecordUpdate, doctl.ArgRecordType, "", "", "Record type")
	AddStringFlag(cmdRecordUpdate, doctl.ArgRecordName, "", "", "Record name")
	AddStringFlag(cmdRecordUpdate, doctl.ArgRecordData, "", "", "Record data")
	AddIntFlag(cmdRecordUpdate, doctl.ArgRecordPriority, "", 0, "Record priority")
	AddIntFlag(cmdRecordUpdate, doctl.ArgRecordPort, "", 0, "Record port")
	AddIntFlag(cmdRecordUpdate, doctl.ArgRecordTTL, "", 1800, "Record TTL")
	AddIntFlag(cmdRecordUpdate, doctl.ArgRecordWeight, "", 0, "Record weight")
	AddIntFlag(cmdRecordUpdate, doctl.ArgRecordFlags, "", 0, "Record flags")
	AddStringFlag(cmdRecordUpdate, doctl.ArgRecordTag, "", "", "Record tag")

	return cmd
}

// RunDomainCreate runs domain create.
func RunDomainCreate(c *CmdConfig) error {
	if len(c.Args) != 1 {
		return doctl.NewMissingArgsErr(c.NS)
	}
	domainName := c.Args[0]

	ds := c.Domains()

	ipAddress, err := c.Doit.GetString(c.NS, "ip-address")
	if err != nil {
		return err
	}

	req := &godo.DomainCreateRequest{
		Name:      domainName,
		IPAddress: ipAddress,
	}

	d, err := ds.Create(req)
	if err != nil {
		return err
	}

	return c.Display(&displayers.Domain{Domains: do.Domains{*d}})
}

// RunDomainList runs domain create.
func RunDomainList(c *CmdConfig) error {

	ds := c.Domains()

	domains, err := ds.List()
	if err != nil {
		return err
	}

	item := &displayers.Domain{Domains: domains}
	return c.Display(item)
}

// RunDomainGet retrieves a domain by name.
func RunDomainGet(c *CmdConfig) error {
	if len(c.Args) != 1 {
		return doctl.NewMissingArgsErr(c.NS)
	}
	id := c.Args[0]

	ds := c.Domains()

	if len(id) < 1 {
		return errors.New("invalid domain name")
	}

	d, err := ds.Get(id)
	if err != nil {
		return err
	}

	item := &displayers.Domain{Domains: do.Domains{*d}}
	return c.Display(item)
}

// RunDomainDelete deletes a domain by name.
func RunDomainDelete(c *CmdConfig) error {
	if len(c.Args) != 1 {
		return doctl.NewMissingArgsErr(c.NS)
	}
	name := c.Args[0]

	force, err := c.Doit.GetBool(c.NS, doctl.ArgForce)
	if err != nil {
		return err
	}

	if force || AskForConfirm("delete domain") == nil {
		ds := c.Domains()

		if len(name) < 1 {
			return errors.New("invalid domain name")
		}

		err := ds.Delete(name)
		return err
	}

	return fmt.Errorf("operation aborted")
}

// RunRecordList list records for a domain.
func RunRecordList(c *CmdConfig) error {
	if len(c.Args) != 1 {
		return doctl.NewMissingArgsErr(c.NS)
	}
	name := c.Args[0]

	ds := c.Domains()

	if len(name) < 1 {
		return errors.New("domain name is missing")
	}

	list, err := ds.Records(name)
	if err != nil {
		return err
	}

	items := &displayers.DomainRecord{DomainRecords: list}
	return c.Display(items)

}

// RunRecordCreate creates a domain record.
func RunRecordCreate(c *CmdConfig) error {
	if len(c.Args) != 1 {
		return doctl.NewMissingArgsErr(c.NS)
	}
	name := c.Args[0]

	ds := c.Domains()

	rType, err := c.Doit.GetString(c.NS, doctl.ArgRecordType)
	if err != nil {
		return err
	}

	rName, err := c.Doit.GetString(c.NS, doctl.ArgRecordName)
	if err != nil {
		return err
	}

	rData, err := c.Doit.GetString(c.NS, doctl.ArgRecordData)
	if err != nil {
		return err
	}

	rPriority, err := c.Doit.GetInt(c.NS, doctl.ArgRecordPriority)
	if err != nil {
		return err
	}

	rPort, err := c.Doit.GetInt(c.NS, doctl.ArgRecordPort)
	if err != nil {
		return err
	}

	rTTL, err := c.Doit.GetInt(c.NS, doctl.ArgRecordTTL)
	if err != nil {
		return err
	}

	rWeight, err := c.Doit.GetInt(c.NS, doctl.ArgRecordWeight)
	if err != nil {
		return err
	}

	rFlags, err := c.Doit.GetInt(c.NS, doctl.ArgRecordFlags)
	if err != nil {
		return err
	}

	rTag, err := c.Doit.GetString(c.NS, doctl.ArgRecordTag)
	if err != nil {
		return err
	}

	drcr := &godo.DomainRecordEditRequest{
		Type:     rType,
		Name:     rName,
		Data:     rData,
		Priority: rPriority,
		Port:     rPort,
		TTL:      rTTL,
		Weight:   rWeight,
		Flags:    rFlags,
		Tag:      rTag,
	}

	if len(drcr.Type) == 0 {
		return errors.New("record request is missing type")
	}

	r, err := ds.CreateRecord(name, drcr)
	if err != nil {
		return err
	}

	item := &displayers.DomainRecord{DomainRecords: do.DomainRecords{*r}}
	return c.Display(item)

}

// RunRecordDelete deletes a domain record.
func RunRecordDelete(c *CmdConfig) error {
	if len(c.Args) < 2 {
		return doctl.NewMissingArgsErr(c.NS)
	}

	force, err := c.Doit.GetBool(c.NS, doctl.ArgForce)
	if err != nil {
		return err
	}

	if force || AskForConfirm("delete record(s)") == nil {
		domainName, ids := c.Args[0], c.Args[1:]
		if len(ids) < 1 {
			return doctl.NewMissingArgsErr(c.NS)
		}

		ds := c.Domains()

		for _, i := range ids {
			id, err := strconv.Atoi(i)
			if err != nil {
				return fmt.Errorf("invalid record id %q", i)
			}

			err = ds.DeleteRecord(domainName, id)
			if err != nil {
				return err
			}
		}
	} else {
		return fmt.Errorf("opertaion aborted")
	}

	return nil

}

// RunRecordUpdate updates a domain record.
func RunRecordUpdate(c *CmdConfig) error {
	if len(c.Args) != 1 {
		return doctl.NewMissingArgsErr(c.NS)
	}
	domainName := c.Args[0]

	ds := c.Domains()

	recordID, err := c.Doit.GetInt(c.NS, doctl.ArgRecordID)
	if err != nil {
		return err
	}

	rType, err := c.Doit.GetString(c.NS, doctl.ArgRecordType)
	if err != nil {
		return err
	}

	rName, err := c.Doit.GetString(c.NS, doctl.ArgRecordName)
	if err != nil {
		return err
	}

	rData, err := c.Doit.GetString(c.NS, doctl.ArgRecordData)
	if err != nil {
		return err
	}

	rPriority, err := c.Doit.GetInt(c.NS, doctl.ArgRecordPriority)
	if err != nil {
		return err
	}

	rPort, err := c.Doit.GetInt(c.NS, doctl.ArgRecordPort)
	if err != nil {
		return err
	}

	rTTL, err := c.Doit.GetInt(c.NS, doctl.ArgRecordTTL)
	if err != nil {
		return err
	}

	rWeight, err := c.Doit.GetInt(c.NS, doctl.ArgRecordWeight)
	if err != nil {
		return err
	}

	rFlags, err := c.Doit.GetInt(c.NS, doctl.ArgRecordFlags)
	if err != nil {
		return err
	}

	rTag, err := c.Doit.GetString(c.NS, doctl.ArgRecordTag)
	if err != nil {
		return err
	}

	drcr := &godo.DomainRecordEditRequest{
		Type:     rType,
		Name:     rName,
		Data:     rData,
		Priority: rPriority,
		Port:     rPort,
		TTL:      rTTL,
		Weight:   rWeight,
		Flags:    rFlags,
		Tag:      rTag,
	}

	r, err := ds.EditRecord(domainName, recordID, drcr)
	if err != nil {
		return err
	}

	item := &displayers.DomainRecord{DomainRecords: do.DomainRecords{*r}}
	return c.Display(item)
}
<commit_msg>update short descriptions - domains.go<commit_after>/*
Copyright 2018 The Doctl Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package commands

import (
	"errors"
	"fmt"
	"strconv"

	"github.com/digitalocean/doctl"
	"github.com/digitalocean/doctl/commands/displayers"
	"github.com/digitalocean/doctl/do"
	"github.com/digitalocean/godo"
	"github.com/spf13/cobra"
)

// Domain creates the domain commands hierarchy.
func Domain() *Command {
	cmd := &Command{
		Command: &cobra.Command{
			Use:   "domain",
			Short: "domain commands",
			Long:  `Use the subcommands of 'doctl compute domain' to manage domains you have purchased from a domain name registrar that you are managing through the DigitalOcean DNS interface.`,
		},
	}

	cmdDomainCreate := CmdBuilderWithDocs(cmd, RunDomainCreate, "create <domain>", "Add a domain to your account",`Use this command to add a domain to your account.`, Writer,
		aliasOpt("c"), displayerType(&displayers.Domain{}))
	AddStringFlag(cmdDomainCreate, doctl.ArgIPAddress, "", "", "IP address, creates an initial A record when provided")

	CmdBuilderWithDocs(cmd, RunDomainList, "list", "List all domains on your account",`Use this command to retrive a list of domains added to your account.`, Writer,
		aliasOpt("ls"), displayerType(&displayers.Domain{}))

	CmdBuilderWithDocs(cmd, RunDomainGet, "get <domain>", "Retrive information about a domain",`Use this command to retrive a specific domain on your account.`, Writer,
		aliasOpt("g"), displayerType(&displayers.Domain{}))

	cmdRunDomainDelete := CmdBuilderWithDocs(cmd, RunDomainDelete, "delete <domain>", "Permanently delete a domain from your account",`Use this command to delete a domain from your account. This is irreversible.`, Writer, aliasOpt("d", "rm"))
	AddBoolFlag(cmdRunDomainDelete, doctl.ArgForce, doctl.ArgShortForce, false, "Force domain delete")

	cmdRecord := &Command{
		Command: &cobra.Command{
			Use:   "records",
			Short: "manage domain DNS",
			Long:  "Use the subcommands of 'doctl compute domain records' to manage the DNS records for your domains",
		},
	}
	cmd.AddCommand(cmdRecord)

	CmdBuilderWithDocs(cmdRecord, RunRecordList, "list <domain>", "List the DNS records for a domain",`Use this command to list the current DNS records for a domain.`, Writer,
		aliasOpt("ls"), displayerType(&displayers.DomainRecord{}))

	cmdRecordCreate := CmdBuilderWithDocs(cmdRecord, RunRecordCreate, "create <domain>", "Create a DNS record", `Use this command to create DNS records for a domain.`, Writer,
		aliasOpt("c"), displayerType(&displayers.DomainRecord{}))
	AddStringFlag(cmdRecordCreate, doctl.ArgRecordType, "", "", "Record type")
	AddStringFlag(cmdRecordCreate, doctl.ArgRecordName, "", "", "Record name")
	AddStringFlag(cmdRecordCreate, doctl.ArgRecordData, "", "", "Record data")
	AddIntFlag(cmdRecordCreate, doctl.ArgRecordPriority, "", 0, "Record priority")
	AddIntFlag(cmdRecordCreate, doctl.ArgRecordPort, "", 0, "Record port")
	AddIntFlag(cmdRecordCreate, doctl.ArgRecordTTL, "", 1800, "Record TTL")
	AddIntFlag(cmdRecordCreate, doctl.ArgRecordWeight, "", 0, "Record weight")
	AddIntFlag(cmdRecordCreate, doctl.ArgRecordFlags, "", 0, "Record flags")
	AddStringFlag(cmdRecordCreate, doctl.ArgRecordTag, "", "", "Record tag")

<<<<<<< HEAD
	cmdRunRecordDelete := CmdBuilderWithDocs(cmdRecord, RunRecordDelete, "delete <domain> <record-id>...", "delete DNS record", `Use this command to delete DNS records for a domain.`, Writer,
		aliasOpt("d"))
	AddBoolFlag(cmdRunRecordDelete, doctl.ArgForce, doctl.ArgShortForce, false, "Force record delete")

	cmdRecordUpdate := CmdBuilderWithDocs(cmdRecord, RunRecordUpdate, "update <domain>", "update DNS record", `Use this command to update or change DNS records for a domain.`, Writer,
=======
	cmdRunRecordDelete := CmdBuilderWithDocs(cmdRecord, RunRecordDelete, "delete <domain> <record-id>...", "Delete a DNS record",`Use this command to delete DNS records for a domain.`, Writer,
		aliasOpt("d"))
	AddBoolFlag(cmdRunRecordDelete, doctl.ArgForce, doctl.ArgShortForce, false, "Force record delete")

	cmdRecordUpdate := CmdBuilderWithDocs(cmdRecord, RunRecordUpdate, "update <domain>", "Update a DNS record",`Use this command to update or change DNS records for a domain.`, Writer,
>>>>>>> extend short descriptions, domains.go
		aliasOpt("u"), displayerType(&displayers.DomainRecord{}))
	AddIntFlag(cmdRecordUpdate, doctl.ArgRecordID, "", 0, "Record ID")
	AddStringFlag(cmdRecordUpdate, doctl.ArgRecordType, "", "", "Record type")
	AddStringFlag(cmdRecordUpdate, doctl.ArgRecordName, "", "", "Record name")
	AddStringFlag(cmdRecordUpdate, doctl.ArgRecordData, "", "", "Record data")
	AddIntFlag(cmdRecordUpdate, doctl.ArgRecordPriority, "", 0, "Record priority")
	AddIntFlag(cmdRecordUpdate, doctl.ArgRecordPort, "", 0, "Record port")
	AddIntFlag(cmdRecordUpdate, doctl.ArgRecordTTL, "", 1800, "Record TTL")
	AddIntFlag(cmdRecordUpdate, doctl.ArgRecordWeight, "", 0, "Record weight")
	AddIntFlag(cmdRecordUpdate, doctl.ArgRecordFlags, "", 0, "Record flags")
	AddStringFlag(cmdRecordUpdate, doctl.ArgRecordTag, "", "", "Record tag")

	return cmd
}

// RunDomainCreate runs domain create.
func RunDomainCreate(c *CmdConfig) error {
	if len(c.Args) != 1 {
		return doctl.NewMissingArgsErr(c.NS)
	}
	domainName := c.Args[0]

	ds := c.Domains()

	ipAddress, err := c.Doit.GetString(c.NS, "ip-address")
	if err != nil {
		return err
	}

	req := &godo.DomainCreateRequest{
		Name:      domainName,
		IPAddress: ipAddress,
	}

	d, err := ds.Create(req)
	if err != nil {
		return err
	}

	return c.Display(&displayers.Domain{Domains: do.Domains{*d}})
}

// RunDomainList runs domain create.
func RunDomainList(c *CmdConfig) error {

	ds := c.Domains()

	domains, err := ds.List()
	if err != nil {
		return err
	}

	item := &displayers.Domain{Domains: domains}
	return c.Display(item)
}

// RunDomainGet retrieves a domain by name.
func RunDomainGet(c *CmdConfig) error {
	if len(c.Args) != 1 {
		return doctl.NewMissingArgsErr(c.NS)
	}
	id := c.Args[0]

	ds := c.Domains()

	if len(id) < 1 {
		return errors.New("invalid domain name")
	}

	d, err := ds.Get(id)
	if err != nil {
		return err
	}

	item := &displayers.Domain{Domains: do.Domains{*d}}
	return c.Display(item)
}

// RunDomainDelete deletes a domain by name.
func RunDomainDelete(c *CmdConfig) error {
	if len(c.Args) != 1 {
		return doctl.NewMissingArgsErr(c.NS)
	}
	name := c.Args[0]

	force, err := c.Doit.GetBool(c.NS, doctl.ArgForce)
	if err != nil {
		return err
	}

	if force || AskForConfirm("delete domain") == nil {
		ds := c.Domains()

		if len(name) < 1 {
			return errors.New("invalid domain name")
		}

		err := ds.Delete(name)
		return err
	}

	return fmt.Errorf("operation aborted")
}

// RunRecordList list records for a domain.
func RunRecordList(c *CmdConfig) error {
	if len(c.Args) != 1 {
		return doctl.NewMissingArgsErr(c.NS)
	}
	name := c.Args[0]

	ds := c.Domains()

	if len(name) < 1 {
		return errors.New("domain name is missing")
	}

	list, err := ds.Records(name)
	if err != nil {
		return err
	}

	items := &displayers.DomainRecord{DomainRecords: list}
	return c.Display(items)

}

// RunRecordCreate creates a domain record.
func RunRecordCreate(c *CmdConfig) error {
	if len(c.Args) != 1 {
		return doctl.NewMissingArgsErr(c.NS)
	}
	name := c.Args[0]

	ds := c.Domains()

	rType, err := c.Doit.GetString(c.NS, doctl.ArgRecordType)
	if err != nil {
		return err
	}

	rName, err := c.Doit.GetString(c.NS, doctl.ArgRecordName)
	if err != nil {
		return err
	}

	rData, err := c.Doit.GetString(c.NS, doctl.ArgRecordData)
	if err != nil {
		return err
	}

	rPriority, err := c.Doit.GetInt(c.NS, doctl.ArgRecordPriority)
	if err != nil {
		return err
	}

	rPort, err := c.Doit.GetInt(c.NS, doctl.ArgRecordPort)
	if err != nil {
		return err
	}

	rTTL, err := c.Doit.GetInt(c.NS, doctl.ArgRecordTTL)
	if err != nil {
		return err
	}

	rWeight, err := c.Doit.GetInt(c.NS, doctl.ArgRecordWeight)
	if err != nil {
		return err
	}

	rFlags, err := c.Doit.GetInt(c.NS, doctl.ArgRecordFlags)
	if err != nil {
		return err
	}

	rTag, err := c.Doit.GetString(c.NS, doctl.ArgRecordTag)
	if err != nil {
		return err
	}

	drcr := &godo.DomainRecordEditRequest{
		Type:     rType,
		Name:     rName,
		Data:     rData,
		Priority: rPriority,
		Port:     rPort,
		TTL:      rTTL,
		Weight:   rWeight,
		Flags:    rFlags,
		Tag:      rTag,
	}

	if len(drcr.Type) == 0 {
		return errors.New("record request is missing type")
	}

	r, err := ds.CreateRecord(name, drcr)
	if err != nil {
		return err
	}

	item := &displayers.DomainRecord{DomainRecords: do.DomainRecords{*r}}
	return c.Display(item)

}

// RunRecordDelete deletes a domain record.
func RunRecordDelete(c *CmdConfig) error {
	if len(c.Args) < 2 {
		return doctl.NewMissingArgsErr(c.NS)
	}

	force, err := c.Doit.GetBool(c.NS, doctl.ArgForce)
	if err != nil {
		return err
	}

	if force || AskForConfirm("delete record(s)") == nil {
		domainName, ids := c.Args[0], c.Args[1:]
		if len(ids) < 1 {
			return doctl.NewMissingArgsErr(c.NS)
		}

		ds := c.Domains()

		for _, i := range ids {
			id, err := strconv.Atoi(i)
			if err != nil {
				return fmt.Errorf("invalid record id %q", i)
			}

			err = ds.DeleteRecord(domainName, id)
			if err != nil {
				return err
			}
		}
	} else {
		return fmt.Errorf("opertaion aborted")
	}

	return nil

}

// RunRecordUpdate updates a domain record.
func RunRecordUpdate(c *CmdConfig) error {
	if len(c.Args) != 1 {
		return doctl.NewMissingArgsErr(c.NS)
	}
	domainName := c.Args[0]

	ds := c.Domains()

	recordID, err := c.Doit.GetInt(c.NS, doctl.ArgRecordID)
	if err != nil {
		return err
	}

	rType, err := c.Doit.GetString(c.NS, doctl.ArgRecordType)
	if err != nil {
		return err
	}

	rName, err := c.Doit.GetString(c.NS, doctl.ArgRecordName)
	if err != nil {
		return err
	}

	rData, err := c.Doit.GetString(c.NS, doctl.ArgRecordData)
	if err != nil {
		return err
	}

	rPriority, err := c.Doit.GetInt(c.NS, doctl.ArgRecordPriority)
	if err != nil {
		return err
	}

	rPort, err := c.Doit.GetInt(c.NS, doctl.ArgRecordPort)
	if err != nil {
		return err
	}

	rTTL, err := c.Doit.GetInt(c.NS, doctl.ArgRecordTTL)
	if err != nil {
		return err
	}

	rWeight, err := c.Doit.GetInt(c.NS, doctl.ArgRecordWeight)
	if err != nil {
		return err
	}

	rFlags, err := c.Doit.GetInt(c.NS, doctl.ArgRecordFlags)
	if err != nil {
		return err
	}

	rTag, err := c.Doit.GetString(c.NS, doctl.ArgRecordTag)
	if err != nil {
		return err
	}

	drcr := &godo.DomainRecordEditRequest{
		Type:     rType,
		Name:     rName,
		Data:     rData,
		Priority: rPriority,
		Port:     rPort,
		TTL:      rTTL,
		Weight:   rWeight,
		Flags:    rFlags,
		Tag:      rTag,
	}

	r, err := ds.EditRecord(domainName, recordID, drcr)
	if err != nil {
		return err
	}

	item := &displayers.DomainRecord{DomainRecords: do.DomainRecords{*r}}
	return c.Display(item)
}
<|endoftext|>


<commit_before>package commands

// Request represents a call to a command from a consumer
type Request struct {
  options map[string]interface{}
  arguments []string
}

func (r *Request) Option(name string) interface{} {
  return r.options[name]
}

func (r *Request) Arguments() []string {
  return r.arguments
}

func NewRequest() *Request {
  return &Request{
    make(map[string]interface{}),
    make([]string, 0),
  }
}
<commit_msg>commands: Added Request#SetOption so we can set options with multiple names<commit_after>package commands

// Request represents a call to a command from a consumer
type Request struct {
  options map[string]interface{}
  arguments []string
}

func (r *Request) Option(name string) interface{} {
  return r.options[name]
}

func (r *Request) SetOption(option Option, value interface{}) {
  // saves the option value in the map, indexed by each name
  // (so commands can retrieve it using any of the names)
  for _, name := range option.Names {
    r.options[name] = value
  }
}

func (r *Request) Arguments() []string {
  return r.arguments
}

func NewRequest() *Request {
  return &Request{
    make(map[string]interface{}),
    make([]string, 0),
  }
}
<|endoftext|>


<commit_before>package commands

import (
	"errors"
	"fmt"
	"reflect"
	"strconv"

	"github.com/jbenet/go-ipfs/config"
	"github.com/jbenet/go-ipfs/core"
)

type optMap map[string]interface{}

type Context struct {
	ConfigRoot string
	Config     *config.Config
	Node       *core.IpfsNode
}

// Request represents a call to a command from a consumer
type Request interface {
	Path() []string
	Option(name string) (interface{}, bool)
	Options() map[string]interface{}
	SetOption(name string, val interface{})
	Arguments() []interface{} // TODO: make argument value type instead of using interface{}
	Context() *Context
	SetContext(Context)
	Command() *Command

	ConvertOptions(options map[string]Option) error
}

type request struct {
	path       []string
	options    optMap
	arguments  []interface{}
	cmd        *Command
	ctx        Context
	optionDefs map[string]Option
}

// Path returns the command path of this request
func (r *request) Path() []string {
	return r.path
}

// Option returns the value of the option for given name.
func (r *request) Option(name string) (interface{}, bool) {
	val, found := r.options[name]
	if found {
		return val, found
	}

	// if a value isn't defined for that name, we will try to look it up by its aliases

	// find the option with the specified name
	option, found := r.optionDefs[name]
	if found {
		// try all the possible names, break if we find a value
		for _, n := range option.Names {
			val, found := r.options[n]
			if found {
				return val, found
			}
		}
	}

	return nil, false
}

// Options returns a copy of the option map
func (r *request) Options() map[string]interface{} {
	output := make(optMap)
	for k, v := range r.options {
		output[k] = v
	}
	return output
}

// SetOption sets the value of the option for given name.
func (r *request) SetOption(name string, val interface{}) {
	r.options[name] = val
}

// Arguments returns the arguments slice
func (r *request) Arguments() []interface{} {
	return r.arguments
}

func (r *request) Context() *Context {
	return &r.ctx
}

func (r *request) SetContext(ctx Context) {
	r.ctx = ctx
}

func (r *request) Command() *Command {
	return r.cmd
}

type converter func(string) (interface{}, error)

var converters = map[reflect.Kind]converter{
	Bool: func(v string) (interface{}, error) {
		if v == "" {
			return true, nil
		}
		return strconv.ParseBool(v)
	},
	Int: func(v string) (interface{}, error) {
		return strconv.ParseInt(v, 0, 32)
	},
	Uint: func(v string) (interface{}, error) {
		return strconv.ParseInt(v, 0, 32)
	},
	Float: func(v string) (interface{}, error) {
		return strconv.ParseFloat(v, 64)
	},
}

func (r *request) ConvertOptions(options map[string]Option) error {
	converted := make(map[string]interface{})

	for k, v := range r.options {
		opt, ok := options[k]
		if !ok {
			continue
		}

		kind := reflect.TypeOf(v).Kind()
		var value interface{}

		if kind != opt.Type {
			if kind == String {
				convert := converters[opt.Type]
				str, ok := v.(string)
				if !ok {
					return errors.New("cast error")
				}
				val, err := convert(str)
				if err != nil {
					return fmt.Errorf("Could not convert string value '%s' to type '%s'",
						v, opt.Type.String())
				}
				value = val

			} else {
				return fmt.Errorf("Option '%s' should be type '%s', but got type '%s'",
					k, opt.Type.String(), kind.String())
			}
		} else {
			value = v
		}

		for _, name := range opt.Names {
			if _, ok := r.options[name]; name != k && ok {
				return fmt.Errorf("Duplicate command options were provided ('%s' and '%s')",
					k, name)
			}

			converted[name] = value
		}
	}

	r.options = converted
	return nil
}

// NewEmptyRequest initializes an empty request
func NewEmptyRequest() Request {
	return NewRequest(nil, nil, nil, nil, nil)
}

// NewRequest returns a request initialized with given arguments
func NewRequest(path []string, opts optMap, args []interface{}, cmd *Command, optDefs map[string]Option) Request {
	if path == nil {
		path = make([]string, 0)
	}
	if opts == nil {
		opts = make(map[string]interface{})
	}
	if args == nil {
		args = make([]interface{}, 0)
	}
	if optDefs == nil {
		optDefs = make(map[string]Option)
	}
	return &request{path, opts, args, cmd, Context{}, optDefs}
}
<commit_msg>commands: Made SetOption override existing values (even if they used a different alias)<commit_after>package commands

import (
	"errors"
	"fmt"
	"reflect"
	"strconv"

	"github.com/jbenet/go-ipfs/config"
	"github.com/jbenet/go-ipfs/core"
)

type optMap map[string]interface{}

type Context struct {
	ConfigRoot string
	Config     *config.Config
	Node       *core.IpfsNode
}

// Request represents a call to a command from a consumer
type Request interface {
	Path() []string
	Option(name string) (interface{}, bool)
	Options() map[string]interface{}
	SetOption(name string, val interface{})
	Arguments() []interface{} // TODO: make argument value type instead of using interface{}
	Context() *Context
	SetContext(Context)
	Command() *Command

	ConvertOptions(options map[string]Option) error
}

type request struct {
	path       []string
	options    optMap
	arguments  []interface{}
	cmd        *Command
	ctx        Context
	optionDefs map[string]Option
}

// Path returns the command path of this request
func (r *request) Path() []string {
	return r.path
}

// Option returns the value of the option for given name.
func (r *request) Option(name string) (interface{}, bool) {
	val, found := r.options[name]
	if found {
		return val, found
	}

	// if a value isn't defined for that name, we will try to look it up by its aliases

	// find the option with the specified name
	option, found := r.optionDefs[name]
	if found {
		// try all the possible names, break if we find a value
		for _, n := range option.Names {
			val, found := r.options[n]
			if found {
				return val, found
			}
		}
	}

	return nil, false
}

// Options returns a copy of the option map
func (r *request) Options() map[string]interface{} {
	output := make(optMap)
	for k, v := range r.options {
		output[k] = v
	}
	return output
}

// SetOption sets the value of the option for given name.
func (r *request) SetOption(name string, val interface{}) {
	// find the option with the specified name
	option, found := r.optionDefs[name]
	if !found {
		return
	}

	// try all the possible names, if we already have a value then set over it
	for _, n := range option.Names {
		val, found := r.options[n]
		if found {
			r.options[n] = val
			return
		}
	}

	r.options[name] = val
}

// Arguments returns the arguments slice
func (r *request) Arguments() []interface{} {
	return r.arguments
}

func (r *request) Context() *Context {
	return &r.ctx
}

func (r *request) SetContext(ctx Context) {
	r.ctx = ctx
}

func (r *request) Command() *Command {
	return r.cmd
}

type converter func(string) (interface{}, error)

var converters = map[reflect.Kind]converter{
	Bool: func(v string) (interface{}, error) {
		if v == "" {
			return true, nil
		}
		return strconv.ParseBool(v)
	},
	Int: func(v string) (interface{}, error) {
		return strconv.ParseInt(v, 0, 32)
	},
	Uint: func(v string) (interface{}, error) {
		return strconv.ParseInt(v, 0, 32)
	},
	Float: func(v string) (interface{}, error) {
		return strconv.ParseFloat(v, 64)
	},
}

func (r *request) ConvertOptions(options map[string]Option) error {
	converted := make(map[string]interface{})

	for k, v := range r.options {
		opt, ok := options[k]
		if !ok {
			continue
		}

		kind := reflect.TypeOf(v).Kind()
		var value interface{}

		if kind != opt.Type {
			if kind == String {
				convert := converters[opt.Type]
				str, ok := v.(string)
				if !ok {
					return errors.New("cast error")
				}
				val, err := convert(str)
				if err != nil {
					return fmt.Errorf("Could not convert string value '%s' to type '%s'",
						v, opt.Type.String())
				}
				value = val

			} else {
				return fmt.Errorf("Option '%s' should be type '%s', but got type '%s'",
					k, opt.Type.String(), kind.String())
			}
		} else {
			value = v
		}

		for _, name := range opt.Names {
			if _, ok := r.options[name]; name != k && ok {
				return fmt.Errorf("Duplicate command options were provided ('%s' and '%s')",
					k, name)
			}

			converted[name] = value
		}
	}

	r.options = converted
	return nil
}

// NewEmptyRequest initializes an empty request
func NewEmptyRequest() Request {
	return NewRequest(nil, nil, nil, nil, nil)
}

// NewRequest returns a request initialized with given arguments
func NewRequest(path []string, opts optMap, args []interface{}, cmd *Command, optDefs map[string]Option) Request {
	if path == nil {
		path = make([]string, 0)
	}
	if opts == nil {
		opts = make(map[string]interface{})
	}
	if args == nil {
		args = make([]interface{}, 0)
	}
	if optDefs == nil {
		optDefs = make(map[string]Option)
	}
	return &request{path, opts, args, cmd, Context{}, optDefs}
}
<|endoftext|>


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

/*
	Package builtin provides documentation for Go's predeclared identifiers.
	The items documented here are not actually in package builtin
	but their descriptions here allow godoc to present documentation
	for the language's special identifiers.
*/
package builtin

// bool is the set of boolean values, true and false.
type bool bool

// true and false are the two untyped boolean values.
const (
	true  = 0 == 0 // Untyped bool.
	false = 0 != 0 // Untyped bool.
)

// uint8 is the set of all unsigned 8-bit integers.
// Range: 0 through 255.
type uint8 uint8

// uint16 is the set of all unsigned 16-bit integers.
// Range: 0 through 65535.
type uint16 uint16

// uint32 is the set of all unsigned 32-bit integers.
// Range: 0 through 4294967295.
type uint32 uint32

// uint64 is the set of all unsigned 64-bit integers.
// Range: 0 through 18446744073709551615.
type uint64 uint64

// int8 is the set of all signed 8-bit integers.
// Range: -128 through 127.
type int8 int8

// int16 is the set of all signed 16-bit integers.
// Range: -32768 through 32767.
type int16 int16

// int32 is the set of all signed 32-bit integers.
// Range: -2147483648 through 2147483647.
type int32 int32

// int64 is the set of all signed 64-bit integers.
// Range: -9223372036854775808 through 9223372036854775807.
type int64 int64

// float32 is the set of all IEEE-754 32-bit floating-point numbers.
type float32 float32

// float64 is the set of all IEEE-754 64-bit floating-point numbers.
type float64 float64

// complex64 is the set of all complex numbers with float32 real and
// imaginary parts.
type complex64 complex64

// complex128 is the set of all complex numbers with float64 real and
// imaginary parts.
type complex128 complex128

// string is the set of all strings of 8-bit bytes, conventionally but not
// necessarily representing UTF-8-encoded text. A string may be empty, but
// not nil. Values of string type are immutable.
type string string

// int is a signed integer type that is at least 32 bits in size. It is a
// distinct type, however, and not an alias for, say, int32.
type int int

// uint is an unsigned integer type that is at least 32 bits in size. It is a
// distinct type, however, and not an alias for, say, uint32.
type uint uint

// uintptr is an integer type that is large enough to hold the bit pattern of
// any pointer.
type uintptr uintptr

// byte is an alias for uint8 and is equivalent to uint8 in all ways. It is
// used, by convention, to distinguish byte values from 8-bit unsigned
// integer values.
type byte = uint8

// rune is an alias for int32 and is equivalent to int32 in all ways. It is
// used, by convention, to distinguish character values from integer values.
type rune = int32

// any is an alias for interface{} and is equivalent to interface{} in all ways.
type any = interface{}

// comparable is an interface that is implemented by all comparable types
// (booleans, numbers, strings, pointers, channels, interfaces,
// arrays of comparable types, structs whose fields are all comparable types).
// The comparable interface may only be used as a type parameter constraint,
// not as the type of a variable.
type comparable comparable

// iota is a predeclared identifier representing the untyped integer ordinal
// number of the current const specification in a (usually parenthesized)
// const declaration. It is zero-indexed.
const iota = 0 // Untyped int.

// nil is a predeclared identifier representing the zero value for a
// pointer, channel, func, interface, map, or slice type.
var nil Type // Type must be a pointer, channel, func, interface, map, or slice type

// Type is here for the purposes of documentation only. It is a stand-in
// for any Go type, but represents the same type for any given function
// invocation.
type Type int

// Type1 is here for the purposes of documentation only. It is a stand-in
// for any Go type, but represents the same type for any given function
// invocation.
type Type1 int

// IntegerType is here for the purposes of documentation only. It is a stand-in
// for any integer type: int, uint, int8 etc.
type IntegerType int

// FloatType is here for the purposes of documentation only. It is a stand-in
// for either float type: float32 or float64.
type FloatType float32

// ComplexType is here for the purposes of documentation only. It is a
// stand-in for either complex type: complex64 or complex128.
type ComplexType complex64

// The append built-in function appends elements to the end of a slice. If
// it has sufficient capacity, the destination is resliced to accommodate the
// new elements. If it does not, a new underlying array will be allocated.
// Append returns the updated slice. It is therefore necessary to store the
// result of append, often in the variable holding the slice itself:
//	slice = append(slice, elem1, elem2)
//	slice = append(slice, anotherSlice...)
// As a special case, it is legal to append a string to a byte slice, like this:
//	slice = append([]byte("hello "), "world"...)
func append(slice []Type, elems ...Type) []Type

// The copy built-in function copies elements from a source slice into a
// destination slice. (As a special case, it also will copy bytes from a
// string to a slice of bytes.) The source and destination may overlap. Copy
// returns the number of elements copied, which will be the minimum of
// len(src) and len(dst).
func copy(dst, src []Type) int

// The delete built-in function deletes the element with the specified key
// (m[key]) from the map. If m is nil or there is no such element, delete
// is a no-op.
func delete(m map[Type]Type1, key Type)

// The len built-in function returns the length of v, according to its type:
//	Array: the number of elements in v.
//	Pointer to array: the number of elements in *v (even if v is nil).
//	Slice, or map: the number of elements in v; if v is nil, len(v) is zero.
//	String: the number of bytes in v.
//	Channel: the number of elements queued (unread) in the channel buffer;
//	         if v is nil, len(v) is zero.
// For some arguments, such as a string literal or a simple array expression, the
// result can be a constant. See the Go language specification's "Length and
// capacity" section for details.
func len(v Type) int

// The cap built-in function returns the capacity of v, according to its type:
//	Array: the number of elements in v (same as len(v)).
//	Pointer to array: the number of elements in *v (same as len(v)).
//	Slice: the maximum length the slice can reach when resliced;
//	if v is nil, cap(v) is zero.
//	Channel: the channel buffer capacity, in units of elements;
//	if v is nil, cap(v) is zero.
// For some arguments, such as a simple array expression, the result can be a
// constant. See the Go language specification's "Length and capacity" section for
// details.
func cap(v Type) int

// The make built-in function allocates and initializes an object of type
// slice, map, or chan (only). Like new, the first argument is a type, not a
// value. Unlike new, make's return type is the same as the type of its
// argument, not a pointer to it. The specification of the result depends on
// the type:
//	Slice: The size specifies the length. The capacity of the slice is
//	equal to its length. A second integer argument may be provided to
//	specify a different capacity; it must be no smaller than the
//	length. For example, make([]int, 0, 10) allocates an underlying array
//	of size 10 and returns a slice of length 0 and capacity 10 that is
//	backed by this underlying array.
//	Map: An empty map is allocated with enough space to hold the
//	specified number of elements. The size may be omitted, in which case
//	a small starting size is allocated.
//	Channel: The channel's buffer is initialized with the specified
//	buffer capacity. If zero, or the size is omitted, the channel is
//	unbuffered.
func make(t Type, size ...IntegerType) Type

// The new built-in function allocates memory. The first argument is a type,
// not a value, and the value returned is a pointer to a newly
// allocated zero value of that type.
func new(Type) *Type

// The complex built-in function constructs a complex value from two
// floating-point values. The real and imaginary parts must be of the same
// size, either float32 or float64 (or assignable to them), and the return
// value will be the corresponding complex type (complex64 for float32,
// complex128 for float64).
func complex(r, i FloatType) ComplexType

// The real built-in function returns the real part of the complex number c.
// The return value will be floating point type corresponding to the type of c.
func real(c ComplexType) FloatType

// The imag built-in function returns the imaginary part of the complex
// number c. The return value will be floating point type corresponding to
// the type of c.
func imag(c ComplexType) FloatType

// The close built-in function closes a channel, which must be either
// bidirectional or send-only. It should be executed only by the sender,
// never the receiver, and has the effect of shutting down the channel after
// the last sent value is received. After the last value has been received
// from a closed channel c, any receive from c will succeed without
// blocking, returning the zero value for the channel element. The form
//	x, ok := <-c
// will also set ok to false for a closed channel.
func close(c chan<- Type)

// The panic built-in function stops normal execution of the current
// goroutine. When a function F calls panic, normal execution of F stops
// immediately. Any functions whose execution was deferred by F are run in
// the usual way, and then F returns to its caller. To the caller G, the
// invocation of F then behaves like a call to panic, terminating G's
// execution and running any deferred functions. This continues until all
// functions in the executing goroutine have stopped, in reverse order. At
// that point, the program is terminated with a non-zero exit code. This
// termination sequence is called panicking and can be controlled by the
// built-in function recover.
func panic(v any)

// The recover built-in function allows a program to manage behavior of a
// panicking goroutine. Executing a call to recover inside a deferred
// function (but not any function called by it) stops the panicking sequence
// by restoring normal execution and retrieves the error value passed to the
// call of panic. If recover is called outside the deferred function it will
// not stop a panicking sequence. In this case, or when the goroutine is not
// panicking, or if the argument supplied to panic was nil, recover returns
// nil. Thus the return value from recover reports whether the goroutine is
// panicking.
func recover() any

// The print built-in function formats its arguments in an
// implementation-specific way and writes the result to standard error.
// Print is useful for bootstrapping and debugging; it is not guaranteed
// to stay in the language.
func print(args ...Type)

// The println built-in function formats its arguments in an
// implementation-specific way and writes the result to standard error.
// Spaces are always added between arguments and a newline is appended.
// Println is useful for bootstrapping and debugging; it is not guaranteed
// to stay in the language.
func println(args ...Type)

// The error built-in interface type is the conventional interface for
// representing an error condition, with the nil value representing no error.
type error interface {
	Error() string
}
<commit_msg>builtin: clarify that interface types do not implement comparable<commit_after>// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/*
	Package builtin provides documentation for Go's predeclared identifiers.
	The items documented here are not actually in package builtin
	but their descriptions here allow godoc to present documentation
	for the language's special identifiers.
*/
package builtin

// bool is the set of boolean values, true and false.
type bool bool

// true and false are the two untyped boolean values.
const (
	true  = 0 == 0 // Untyped bool.
	false = 0 != 0 // Untyped bool.
)

// uint8 is the set of all unsigned 8-bit integers.
// Range: 0 through 255.
type uint8 uint8

// uint16 is the set of all unsigned 16-bit integers.
// Range: 0 through 65535.
type uint16 uint16

// uint32 is the set of all unsigned 32-bit integers.
// Range: 0 through 4294967295.
type uint32 uint32

// uint64 is the set of all unsigned 64-bit integers.
// Range: 0 through 18446744073709551615.
type uint64 uint64

// int8 is the set of all signed 8-bit integers.
// Range: -128 through 127.
type int8 int8

// int16 is the set of all signed 16-bit integers.
// Range: -32768 through 32767.
type int16 int16

// int32 is the set of all signed 32-bit integers.
// Range: -2147483648 through 2147483647.
type int32 int32

// int64 is the set of all signed 64-bit integers.
// Range: -9223372036854775808 through 9223372036854775807.
type int64 int64

// float32 is the set of all IEEE-754 32-bit floating-point numbers.
type float32 float32

// float64 is the set of all IEEE-754 64-bit floating-point numbers.
type float64 float64

// complex64 is the set of all complex numbers with float32 real and
// imaginary parts.
type complex64 complex64

// complex128 is the set of all complex numbers with float64 real and
// imaginary parts.
type complex128 complex128

// string is the set of all strings of 8-bit bytes, conventionally but not
// necessarily representing UTF-8-encoded text. A string may be empty, but
// not nil. Values of string type are immutable.
type string string

// int is a signed integer type that is at least 32 bits in size. It is a
// distinct type, however, and not an alias for, say, int32.
type int int

// uint is an unsigned integer type that is at least 32 bits in size. It is a
// distinct type, however, and not an alias for, say, uint32.
type uint uint

// uintptr is an integer type that is large enough to hold the bit pattern of
// any pointer.
type uintptr uintptr

// byte is an alias for uint8 and is equivalent to uint8 in all ways. It is
// used, by convention, to distinguish byte values from 8-bit unsigned
// integer values.
type byte = uint8

// rune is an alias for int32 and is equivalent to int32 in all ways. It is
// used, by convention, to distinguish character values from integer values.
type rune = int32

// any is an alias for interface{} and is equivalent to interface{} in all ways.
type any = interface{}

// comparable is an interface that is implemented by all comparable types
// (booleans, numbers, strings, pointers, channels, arrays of comparable types,
// structs whose fields are all comparable types).
// The comparable interface may only be used as a type parameter constraint,
// not as the type of a variable.
type comparable interface{ comparable }

// iota is a predeclared identifier representing the untyped integer ordinal
// number of the current const specification in a (usually parenthesized)
// const declaration. It is zero-indexed.
const iota = 0 // Untyped int.

// nil is a predeclared identifier representing the zero value for a
// pointer, channel, func, interface, map, or slice type.
var nil Type // Type must be a pointer, channel, func, interface, map, or slice type

// Type is here for the purposes of documentation only. It is a stand-in
// for any Go type, but represents the same type for any given function
// invocation.
type Type int

// Type1 is here for the purposes of documentation only. It is a stand-in
// for any Go type, but represents the same type for any given function
// invocation.
type Type1 int

// IntegerType is here for the purposes of documentation only. It is a stand-in
// for any integer type: int, uint, int8 etc.
type IntegerType int

// FloatType is here for the purposes of documentation only. It is a stand-in
// for either float type: float32 or float64.
type FloatType float32

// ComplexType is here for the purposes of documentation only. It is a
// stand-in for either complex type: complex64 or complex128.
type ComplexType complex64

// The append built-in function appends elements to the end of a slice. If
// it has sufficient capacity, the destination is resliced to accommodate the
// new elements. If it does not, a new underlying array will be allocated.
// Append returns the updated slice. It is therefore necessary to store the
// result of append, often in the variable holding the slice itself:
//	slice = append(slice, elem1, elem2)
//	slice = append(slice, anotherSlice...)
// As a special case, it is legal to append a string to a byte slice, like this:
//	slice = append([]byte("hello "), "world"...)
func append(slice []Type, elems ...Type) []Type

// The copy built-in function copies elements from a source slice into a
// destination slice. (As a special case, it also will copy bytes from a
// string to a slice of bytes.) The source and destination may overlap. Copy
// returns the number of elements copied, which will be the minimum of
// len(src) and len(dst).
func copy(dst, src []Type) int

// The delete built-in function deletes the element with the specified key
// (m[key]) from the map. If m is nil or there is no such element, delete
// is a no-op.
func delete(m map[Type]Type1, key Type)

// The len built-in function returns the length of v, according to its type:
//	Array: the number of elements in v.
//	Pointer to array: the number of elements in *v (even if v is nil).
//	Slice, or map: the number of elements in v; if v is nil, len(v) is zero.
//	String: the number of bytes in v.
//	Channel: the number of elements queued (unread) in the channel buffer;
//	         if v is nil, len(v) is zero.
// For some arguments, such as a string literal or a simple array expression, the
// result can be a constant. See the Go language specification's "Length and
// capacity" section for details.
func len(v Type) int

// The cap built-in function returns the capacity of v, according to its type:
//	Array: the number of elements in v (same as len(v)).
//	Pointer to array: the number of elements in *v (same as len(v)).
//	Slice: the maximum length the slice can reach when resliced;
//	if v is nil, cap(v) is zero.
//	Channel: the channel buffer capacity, in units of elements;
//	if v is nil, cap(v) is zero.
// For some arguments, such as a simple array expression, the result can be a
// constant. See the Go language specification's "Length and capacity" section for
// details.
func cap(v Type) int

// The make built-in function allocates and initializes an object of type
// slice, map, or chan (only). Like new, the first argument is a type, not a
// value. Unlike new, make's return type is the same as the type of its
// argument, not a pointer to it. The specification of the result depends on
// the type:
//	Slice: The size specifies the length. The capacity of the slice is
//	equal to its length. A second integer argument may be provided to
//	specify a different capacity; it must be no smaller than the
//	length. For example, make([]int, 0, 10) allocates an underlying array
//	of size 10 and returns a slice of length 0 and capacity 10 that is
//	backed by this underlying array.
//	Map: An empty map is allocated with enough space to hold the
//	specified number of elements. The size may be omitted, in which case
//	a small starting size is allocated.
//	Channel: The channel's buffer is initialized with the specified
//	buffer capacity. If zero, or the size is omitted, the channel is
//	unbuffered.
func make(t Type, size ...IntegerType) Type

// The new built-in function allocates memory. The first argument is a type,
// not a value, and the value returned is a pointer to a newly
// allocated zero value of that type.
func new(Type) *Type

// The complex built-in function constructs a complex value from two
// floating-point values. The real and imaginary parts must be of the same
// size, either float32 or float64 (or assignable to them), and the return
// value will be the corresponding complex type (complex64 for float32,
// complex128 for float64).
func complex(r, i FloatType) ComplexType

// The real built-in function returns the real part of the complex number c.
// The return value will be floating point type corresponding to the type of c.
func real(c ComplexType) FloatType

// The imag built-in function returns the imaginary part of the complex
// number c. The return value will be floating point type corresponding to
// the type of c.
func imag(c ComplexType) FloatType

// The close built-in function closes a channel, which must be either
// bidirectional or send-only. It should be executed only by the sender,
// never the receiver, and has the effect of shutting down the channel after
// the last sent value is received. After the last value has been received
// from a closed channel c, any receive from c will succeed without
// blocking, returning the zero value for the channel element. The form
//	x, ok := <-c
// will also set ok to false for a closed channel.
func close(c chan<- Type)

// The panic built-in function stops normal execution of the current
// goroutine. When a function F calls panic, normal execution of F stops
// immediately. Any functions whose execution was deferred by F are run in
// the usual way, and then F returns to its caller. To the caller G, the
// invocation of F then behaves like a call to panic, terminating G's
// execution and running any deferred functions. This continues until all
// functions in the executing goroutine have stopped, in reverse order. At
// that point, the program is terminated with a non-zero exit code. This
// termination sequence is called panicking and can be controlled by the
// built-in function recover.
func panic(v any)

// The recover built-in function allows a program to manage behavior of a
// panicking goroutine. Executing a call to recover inside a deferred
// function (but not any function called by it) stops the panicking sequence
// by restoring normal execution and retrieves the error value passed to the
// call of panic. If recover is called outside the deferred function it will
// not stop a panicking sequence. In this case, or when the goroutine is not
// panicking, or if the argument supplied to panic was nil, recover returns
// nil. Thus the return value from recover reports whether the goroutine is
// panicking.
func recover() any

// The print built-in function formats its arguments in an
// implementation-specific way and writes the result to standard error.
// Print is useful for bootstrapping and debugging; it is not guaranteed
// to stay in the language.
func print(args ...Type)

// The println built-in function formats its arguments in an
// implementation-specific way and writes the result to standard error.
// Spaces are always added between arguments and a newline is appended.
// Println is useful for bootstrapping and debugging; it is not guaranteed
// to stay in the language.
func println(args ...Type)

// The error built-in interface type is the conventional interface for
// representing an error condition, with the nil value representing no error.
type error interface {
	Error() string
}
<|endoftext|>


<commit_before>// Copyright © 2015 Hraban Luyat <hraban@0brg.net>
//
// License for use of this code is detailed in the LICENSE file

package opus

import (
	"math"
	"strings"
	"testing"
)

func TestVersion(t *testing.T) {
	if ver := Version(); !strings.HasPrefix(ver, "libopus") {
		t.Errorf("Unexpected linked libopus version: " + ver)
	}
}

func TestEncoderNew(t *testing.T) {
	enc, err := NewEncoder(48000, 1, APPLICATION_VOIP)
	if err != nil || enc == nil {
		t.Errorf("Error creating new encoder: %v", err)
	}
	enc, err = NewEncoder(12345, 1, APPLICATION_VOIP)
	if err == nil || enc != nil {
		t.Errorf("Expected error for illegal samplerate 12345")
	}
}

func TestDecoderNew(t *testing.T) {
	dec, err := NewDecoder(48000, 1)
	if err != nil || dec == nil {
		t.Errorf("Error creating new decoder: %v", err)
	}
	dec, err = NewDecoder(12345, 1)
	if err == nil || dec != nil {
		t.Errorf("Expected error for illegal samplerate 12345")
	}
}

func addSineFloat32(buf []float32, sampleRate int, freq float64) {
	factor := 2 * math.Pi * freq / float64(sampleRate)
	for i := range buf {
		buf[i] += float32(math.Sin(float64(i) * factor))
	}
}

func addSine(buf []int16, sampleRate int, freq float64) {
	factor := 2 * math.Pi * freq / float64(sampleRate)
	for i := range buf {
		buf[i] += int16(math.Sin(float64(i)*factor) * math.MaxInt16)
	}
}

func TestCodec(t *testing.T) {
	// Create bogus input sound
	const G4 = 391.995
	const SAMPLE_RATE = 48000
	const FRAME_SIZE_MS = 60
	const FRAME_SIZE = SAMPLE_RATE * FRAME_SIZE_MS / 1000
	pcm := make([]int16, FRAME_SIZE)
	enc, err := NewEncoder(SAMPLE_RATE, 1, APPLICATION_VOIP)
	if err != nil || enc == nil {
		t.Fatalf("Error creating new encoder: %v", err)
	}
	addSine(pcm, SAMPLE_RATE, G4)
	data, err := enc.Encode(pcm)
	if err != nil {
		t.Fatalf("Couldn't encode data: %v", err)
	}
	dec, err := NewDecoder(SAMPLE_RATE, 1)
	if err != nil || dec == nil {
		t.Fatalf("Error creating new decoder: %v", err)
	}
	pcm2, err := dec.Decode(data)
	if err != nil {
		t.Fatalf("Couldn't decode data: %v", err)
	}
	if len(pcm) != len(pcm2) {
		t.Fatalf("Length mismatch: %d samples in, %d out", len(pcm), len(pcm2))
	}
	// Checking the output programmatically is seriously not easy. I checked it
	// by hand and by ear, it looks fine. I'll just assume the API faithfully
	// passes error codes through, and that's that.
}

func TestCodecFloat32(t *testing.T) {
	// Create bogus input sound
	const G4 = 391.995
	const SAMPLE_RATE = 48000
	const FRAME_SIZE_MS = 60
	const FRAME_SIZE = SAMPLE_RATE * FRAME_SIZE_MS / 1000
	pcm := make([]float32, FRAME_SIZE)
	enc, err := NewEncoder(SAMPLE_RATE, 1, APPLICATION_VOIP)
	if err != nil || enc == nil {
		t.Fatalf("Error creating new encoder: %v", err)
	}
	addSineFloat32(pcm, SAMPLE_RATE, G4)
	data, err := enc.EncodeFloat32(pcm)
	if err != nil {
		t.Fatalf("Couldn't encode data: %v", err)
	}
	dec, err := NewDecoder(SAMPLE_RATE, 1)
	if err != nil || dec == nil {
		t.Fatalf("Error creating new decoder: %v", err)
	}
	pcm2, err := dec.DecodeFloat32(data)
	if err != nil {
		t.Fatalf("Couldn't decode data: %v", err)
	}
	if len(pcm) != len(pcm2) {
		t.Fatalf("Length mismatch: %d samples in, %d out", len(pcm), len(pcm2))
	}
}
<commit_msg>Unit test for opus error string<commit_after>// Copyright © 2015 Hraban Luyat <hraban@0brg.net>
//
// License for use of this code is detailed in the LICENSE file

package opus

import (
	"math"
	"strings"
	"testing"
)

func TestVersion(t *testing.T) {
	if ver := Version(); !strings.HasPrefix(ver, "libopus") {
		t.Errorf("Unexpected linked libopus version: " + ver)
	}
}

func TestEncoderNew(t *testing.T) {
	enc, err := NewEncoder(48000, 1, APPLICATION_VOIP)
	if err != nil || enc == nil {
		t.Errorf("Error creating new encoder: %v", err)
	}
	enc, err = NewEncoder(12345, 1, APPLICATION_VOIP)
	if err == nil || enc != nil {
		t.Errorf("Expected error for illegal samplerate 12345")
	}
}

func TestDecoderNew(t *testing.T) {
	dec, err := NewDecoder(48000, 1)
	if err != nil || dec == nil {
		t.Errorf("Error creating new decoder: %v", err)
	}
	dec, err = NewDecoder(12345, 1)
	if err == nil || dec != nil {
		t.Errorf("Expected error for illegal samplerate 12345")
	}
}

func TestOpuserr(t *testing.T) {
	// I scooped this -1 up from opus_defines.h, it's OPUS_BAD_ARG. Not pretty,
	// but it's better than not testing at all. Again, accessing #defines from
	// CGO is not possible.
	err := opuserr(-1)
	if err.Error() != "opus: invalid argument" {
		t.Errorf("Expected \"invalid argument\" error message for error code -1: %v")
	}
}

func addSineFloat32(buf []float32, sampleRate int, freq float64) {
	factor := 2 * math.Pi * freq / float64(sampleRate)
	for i := range buf {
		buf[i] += float32(math.Sin(float64(i) * factor))
	}
}

func addSine(buf []int16, sampleRate int, freq float64) {
	factor := 2 * math.Pi * freq / float64(sampleRate)
	for i := range buf {
		buf[i] += int16(math.Sin(float64(i)*factor) * math.MaxInt16)
	}
}

func TestCodec(t *testing.T) {
	// Create bogus input sound
	const G4 = 391.995
	const SAMPLE_RATE = 48000
	const FRAME_SIZE_MS = 60
	const FRAME_SIZE = SAMPLE_RATE * FRAME_SIZE_MS / 1000
	pcm := make([]int16, FRAME_SIZE)
	enc, err := NewEncoder(SAMPLE_RATE, 1, APPLICATION_VOIP)
	if err != nil || enc == nil {
		t.Fatalf("Error creating new encoder: %v", err)
	}
	addSine(pcm, SAMPLE_RATE, G4)
	data, err := enc.Encode(pcm)
	if err != nil {
		t.Fatalf("Couldn't encode data: %v", err)
	}
	dec, err := NewDecoder(SAMPLE_RATE, 1)
	if err != nil || dec == nil {
		t.Fatalf("Error creating new decoder: %v", err)
	}
	pcm2, err := dec.Decode(data)
	if err != nil {
		t.Fatalf("Couldn't decode data: %v", err)
	}
	if len(pcm) != len(pcm2) {
		t.Fatalf("Length mismatch: %d samples in, %d out", len(pcm), len(pcm2))
	}
	// Checking the output programmatically is seriously not easy. I checked it
	// by hand and by ear, it looks fine. I'll just assume the API faithfully
	// passes error codes through, and that's that.
}

func TestCodecFloat32(t *testing.T) {
	// Create bogus input sound
	const G4 = 391.995
	const SAMPLE_RATE = 48000
	const FRAME_SIZE_MS = 60
	const FRAME_SIZE = SAMPLE_RATE * FRAME_SIZE_MS / 1000
	pcm := make([]float32, FRAME_SIZE)
	enc, err := NewEncoder(SAMPLE_RATE, 1, APPLICATION_VOIP)
	if err != nil || enc == nil {
		t.Fatalf("Error creating new encoder: %v", err)
	}
	addSineFloat32(pcm, SAMPLE_RATE, G4)
	data, err := enc.EncodeFloat32(pcm)
	if err != nil {
		t.Fatalf("Couldn't encode data: %v", err)
	}
	dec, err := NewDecoder(SAMPLE_RATE, 1)
	if err != nil || dec == nil {
		t.Fatalf("Error creating new decoder: %v", err)
	}
	pcm2, err := dec.DecodeFloat32(data)
	if err != nil {
		t.Fatalf("Couldn't decode data: %v", err)
	}
	if len(pcm) != len(pcm2) {
		t.Fatalf("Length mismatch: %d samples in, %d out", len(pcm), len(pcm2))
	}
}
<|endoftext|>