<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
// Note: toType is based on https://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/
// Note: uuid generation from https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript

// runtimeTemplate contains all the necessary code for wrapping generated modules into a complete Serulian
// runtime bundle.
const runtimeTemplate = `
this.Serulian = (function($global) {
  var $__currentScriptSrc = '';
  if (typeof document === 'object') {
    $__currentScriptSrc = document.currentScript.src;
  } else {
    // TODO: fix for nested calls to workers by workers.
  }

  $global.__serulian_internal = {
    'autoNominalWrap': function(k, v) {
      if (v == null) {
        return v;
      }

      var typeName = $t.toType(v);
      switch (typeName) {
        case 'object':
          if (k != '') {
            return $t.nominalwrap(v, $a.mapping($t.any));
          }
          break;

        case 'array':
          return $t.nominalwrap(v, $a.slice($t.any));

        case 'boolean':
          return $t.nominalwrap(v, $a.bool);

        case 'string':
          return $t.nominalwrap(v, $a.string);

        case 'number':
          if (Math.ceil(v) == v) {
            return $t.nominalwrap(v, $a.int);
          }

          return $t.nominalwrap(v, $a.float64);
      }

      return v;
    }
  };

  var $g = {};
  var $a = {};
  var $w = {};

  var $t = {
    'toType': function(obj) {
      return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
    },

    'any': new Function("return function any() {};")(),

    'cast': function(value, type) {
      // TODO: implement cast checking.
      return value
    },

    'uuid': function() {
        var buf = new Uint16Array(8);
        crypto.getRandomValues(buf);
        var S4 = function(num) {
            var ret = num.toString(16);
            while(ret.length < 4){
                ret = "0"+ret;
            }
            return ret;
        };
        return (S4(buf[0])+S4(buf[1])+"-"+S4(buf[2])+"-"+S4(buf[3])+"-"+S4(buf[4])+"-"+S4(buf[5])+S4(buf[6])+S4(buf[7]));
    },

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

    'nominalroot': function(instance) {
      if (instance.$wrapped) {
        return instance.$wrapped;
      }

      return instance;
    },

    'nominalwrap': function(instance, type) {
      return type.new(instance)
    },

    'nominalunwrap': function(instance) {
      return instance.$wrapped;
    },

    'workerwrap': function(methodId, f) {
      $w[methodId] = f;
      return function() {
         var args = Array.prototype.slice.call(arguments);
         var token = $t.uuid();

         var promise = new Promise(function(resolve, reject) {
           var worker = new Worker($__currentScriptSrc + "?__serulian_async_token=" + token);
           worker.onmessage = function(e) {
              if (!e.isTrusted) {
                worker.terminate();
                return;
              }

              var data = e.data;
              if (data['token'] != token) {
                return;
              }

              if (data['result']) {
                resolve(data['result']);
              } else {
                reject(data['reject']);
              }

              worker.terminate();
           };

           worker.postMessage({
            'action': 'invoke',
            'arguments': args,
            'method': methodId,
            'token': token
           });
         });
         return promise;
      };
    },

    'property': function(getter, opt_setter) {
      var f = function() {
        if (arguments.length == 1) {
          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, alias, creator) {
        var buildType = function(n, args) {
          var tpe = new Function("return function " + n + "() {};")();
          creator.apply(tpe, args || []);

          if (kind == 'type') {
            tpe.prototype.toJSON = function() {
              return $t.nominalunwrap(this);
            };
          } else if (kind == 'struct') {
            // Stringify.
            tpe.prototype.Stringify = function(T) {
              var $this = this;
              return function() {
                // Special case JSON, as it uses an internal method.
                if (T == $a['$json']) {
                  return $promise.resolve(JSON.stringify($this.data));
                }

                return T.Get().then(function(resolved) {
                  return resolved.Stringify($t.any)($this.data);
                });
              };
            };

            // Parse.
            tpe.Parse = function(T) {
              return function(value) {
                // TODO: Validate the struct.

                // Special case JSON for performance, as it uses an internal method.
                if (T == $a['$json']) {
                  var created = new tpe();
                  created.data = JSON.parse($t.nominalunwrap(value));
                  return $promise.resolve(created);
                }

                return T.Get().then(function(resolved) {
                  return (resolved.Parse($t.any)(value)).then(function(parsed) {
                    var created = new tpe();
                    // TODO: *efficiently* unwrap internal nominal types.
                    created.data = JSON.parse(JSON.stringify($t.nominalunwrap(parsed)));
                    return $promise.resolve(created);
                  });
                });
              };
            };
          }

          return tpe;
        };

        if (hasGenerics) {
          module[name] = function(__genericargs) {
            var fullName = name;
            for (var i = 0; i < arguments.length; ++i) {
              fullName = fullName + '_' + arguments[i].name;
            }

            return buildType(fullName, arguments);
          };
        } else {
          module[name] = buildType(name);
        }

        if (alias) {
          $a[alias] = module[name];
        }
      };
    };

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

  	creator.call(module)
  };

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

  $g.executeWorkerMethod = function(token) {
    $global.onmessage = function(e) {
      if (!e.isTrusted) {
        close();
        return;
      }

      var data = e.data;
      if (data['token'] != token) {
        throw Error('Invalid token')
        close();
      }

      switch (data['action']) {
        case 'invoke':
          var methodId = data['method'];
          var arguments = data['arguments'];
          var method = $w[methodId];

          method.apply(null, arguments).then(function(result) {
            $global.postMessage({
              'result': result,
              'token': token
            });
            close();
          }).catch(function(reject) {
            $global.postMessage({
              'reject': reject,
              'token': token
            });
            close();
          });
          break
      }
    };
  };

  return $promise.all(moduleInits).then(function() {
  	return $g;
  });
})(this)

// Handle web-worker calls.
if (typeof importScripts === 'function') {
  var runWorker = function() {
    var search = location.search;
    if (!search || search[0] != '?') {
      return;
    }

    var searchPairs = search.substr(1).split('&')
    if (searchPairs.length < 1) {
      return;
    }

    for (var i = 0; i < searchPairs.length; ++i) {
      var pair = searchPairs[i].split('=');
      if (pair[0] == '__serulian_async_token') {
        this.Serulian.then(function(global) {
          global.executeWorkerMethod(pair[1]);
        });
        return;
      }
    }

    close();
  };
  runWorker();
}
`
<commit_msg>Use `$global` where possible<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
// Note: toType is based on https://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/
// Note: uuid generation from https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript

// runtimeTemplate contains all the necessary code for wrapping generated modules into a complete Serulian
// runtime bundle.
const runtimeTemplate = `
this.Serulian = (function($global) {
  var $__currentScriptSrc = '';
  if (typeof document === 'object') {
    $__currentScriptSrc = document.currentScript.src;
  } else {
    // TODO: fix for nested calls to workers by workers.
  }

  $global.__serulian_internal = {
    'autoNominalWrap': function(k, v) {
      if (v == null) {
        return v;
      }

      var typeName = $t.toType(v);
      switch (typeName) {
        case 'object':
          if (k != '') {
            return $t.nominalwrap(v, $a.mapping($t.any));
          }
          break;

        case 'array':
          return $t.nominalwrap(v, $a.slice($t.any));

        case 'boolean':
          return $t.nominalwrap(v, $a.bool);

        case 'string':
          return $t.nominalwrap(v, $a.string);

        case 'number':
          if (Math.ceil(v) == v) {
            return $t.nominalwrap(v, $a.int);
          }

          return $t.nominalwrap(v, $a.float64);
      }

      return v;
    }
  };

  var $g = {};
  var $a = {};
  var $w = {};

  var $t = {
    'toType': function(obj) {
      return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
    },

    'any': new Function("return function any() {};")(),

    'cast': function(value, type) {
      // TODO: implement cast checking.
      return value
    },

    'uuid': function() {
        var buf = new Uint16Array(8);
        crypto.getRandomValues(buf);
        var S4 = function(num) {
            var ret = num.toString(16);
            while(ret.length < 4){
                ret = "0"+ret;
            }
            return ret;
        };
        return (S4(buf[0])+S4(buf[1])+"-"+S4(buf[2])+"-"+S4(buf[3])+"-"+S4(buf[4])+"-"+S4(buf[5])+S4(buf[6])+S4(buf[7]));
    },

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

    'nominalroot': function(instance) {
      if (instance.$wrapped) {
        return instance.$wrapped;
      }

      return instance;
    },

    'nominalwrap': function(instance, type) {
      return type.new(instance)
    },

    'nominalunwrap': function(instance) {
      return instance.$wrapped;
    },

    'workerwrap': function(methodId, f) {
      $w[methodId] = f;
      return function() {
         var args = Array.prototype.slice.call(arguments);
         var token = $t.uuid();

         var promise = new Promise(function(resolve, reject) {
           var worker = new Worker($__currentScriptSrc + "?__serulian_async_token=" + token);
           worker.onmessage = function(e) {
              if (!e.isTrusted) {
                worker.terminate();
                return;
              }

              var data = e.data;
              if (data['token'] != token) {
                return;
              }

              if (data['result']) {
                resolve(data['result']);
              } else {
                reject(data['reject']);
              }

              worker.terminate();
           };

           worker.postMessage({
            'action': 'invoke',
            'arguments': args,
            'method': methodId,
            'token': token
           });
         });
         return promise;
      };
    },

    'property': function(getter, opt_setter) {
      var f = function() {
        if (arguments.length == 1) {
          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, alias, creator) {
        var buildType = function(n, args) {
          var tpe = new Function("return function " + n + "() {};")();
          creator.apply(tpe, args || []);

          if (kind == 'type') {
            tpe.prototype.toJSON = function() {
              return $t.nominalunwrap(this);
            };
          } else if (kind == 'struct') {
            // Stringify.
            tpe.prototype.Stringify = function(T) {
              var $this = this;
              return function() {
                // Special case JSON, as it uses an internal method.
                if (T == $a['$json']) {
                  return $promise.resolve(JSON.stringify($this.data));
                }

                return T.Get().then(function(resolved) {
                  return resolved.Stringify($t.any)($this.data);
                });
              };
            };

            // Parse.
            tpe.Parse = function(T) {
              return function(value) {
                // TODO: Validate the struct.

                // Special case JSON for performance, as it uses an internal method.
                if (T == $a['$json']) {
                  var created = new tpe();
                  created.data = JSON.parse($t.nominalunwrap(value));
                  return $promise.resolve(created);
                }

                return T.Get().then(function(resolved) {
                  return (resolved.Parse($t.any)(value)).then(function(parsed) {
                    var created = new tpe();
                    // TODO: *efficiently* unwrap internal nominal types.
                    created.data = JSON.parse(JSON.stringify($t.nominalunwrap(parsed)));
                    return $promise.resolve(created);
                  });
                });
              };
            };
          }

          return tpe;
        };

        if (hasGenerics) {
          module[name] = function(__genericargs) {
            var fullName = name;
            for (var i = 0; i < arguments.length; ++i) {
              fullName = fullName + '_' + arguments[i].name;
            }

            return buildType(fullName, arguments);
          };
        } else {
          module[name] = buildType(name);
        }

        if (alias) {
          $a[alias] = module[name];
        }
      };
    };

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

  	creator.call(module)
  };

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

  $g.executeWorkerMethod = function(token) {
    $global.onmessage = function(e) {
      if (!e.isTrusted) {
        $global.close();
        return;
      }

      var data = e.data;
      if (data['token'] != token) {
        throw Error('Invalid token')
        $global.close();
      }

      switch (data['action']) {
        case 'invoke':
          var methodId = data['method'];
          var arguments = data['arguments'];
          var method = $w[methodId];

          method.apply(null, arguments).then(function(result) {
            $global.postMessage({
              'result': result,
              'token': token
            });
            $global.close();
          }).catch(function(reject) {
            $global.postMessage({
              'reject': reject,
              'token': token
            });
            $global.close();
          });
          break
      }
    };
  };

  return $promise.all(moduleInits).then(function() {
  	return $g;
  });
})(this)

// Handle web-worker calls.
if (typeof importScripts === 'function') {
  var runWorker = function() {
    var search = location.search;
    if (!search || search[0] != '?') {
      return;
    }

    var searchPairs = search.substr(1).split('&')
    if (searchPairs.length < 1) {
      return;
    }

    for (var i = 0; i < searchPairs.length; ++i) {
      var pair = searchPairs[i].split('=');
      if (pair[0] == '__serulian_async_token') {
        this.Serulian.then(function(global) {
          global.executeWorkerMethod(pair[1]);
        });
        return;
      }
    }

    close();
  };
  runWorker();
}
`
<|endoftext|>


<commit_before>package aws

import (
	"fmt"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/iam"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsIamAccountAlias() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsIamAccountAliasCreate,
		Read:   resourceAwsIamAccountAliasRead,
		Delete: resourceAwsIamAccountAliasDelete,

		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"account_alias": {
				Type:         schema.TypeString,
				Required:     true,
				ForceNew:     true,
				ValidateFunc: validateAccountAlias,
			},
		},
	}
}

func resourceAwsIamAccountAliasCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).iamconn

	account_alias := d.Get("account_alias").(string)

	params := &iam.CreateAccountAliasInput{
		AccountAlias: aws.String(account_alias),
	}

	_, err := conn.CreateAccountAlias(params)

	if err != nil {
		return fmt.Errorf("Error creating account alias with name %s", account_alias)
	}

	d.SetId(account_alias)

	return nil
}

func resourceAwsIamAccountAliasRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).iamconn

	params := &iam.ListAccountAliasesInput{}

	resp, err := conn.ListAccountAliases(params)

	if err != nil {
		return err
	}

	if resp == nil || len(resp.AccountAliases) == 0 {
		d.SetId("")
		return nil
	}

	account_alias := aws.StringValue(resp.AccountAliases[0])

	d.SetId(account_alias)
	d.Set("account_alias", account_alias)

	return nil
}

func resourceAwsIamAccountAliasDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).iamconn

	account_alias := d.Get("account_alias").(string)

	params := &iam.DeleteAccountAliasInput{
		AccountAlias: aws.String(account_alias),
	}

	_, err := conn.DeleteAccountAlias(params)

	if err != nil {
		return fmt.Errorf("Error deleting account alias with name %s", account_alias)
	}

	d.SetId("")

	return nil
}
<commit_msg>iam_account_alias: Pass awserr in returned error<commit_after>package aws

import (
	"fmt"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/iam"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsIamAccountAlias() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsIamAccountAliasCreate,
		Read:   resourceAwsIamAccountAliasRead,
		Delete: resourceAwsIamAccountAliasDelete,

		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"account_alias": {
				Type:         schema.TypeString,
				Required:     true,
				ForceNew:     true,
				ValidateFunc: validateAccountAlias,
			},
		},
	}
}

func resourceAwsIamAccountAliasCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).iamconn

	account_alias := d.Get("account_alias").(string)

	params := &iam.CreateAccountAliasInput{
		AccountAlias: aws.String(account_alias),
	}

	_, err := conn.CreateAccountAlias(params)

	if err != nil {
		return fmt.Errorf("Error creating account alias with name '%s': %s", account_alias, err)
	}

	d.SetId(account_alias)

	return nil
}

func resourceAwsIamAccountAliasRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).iamconn

	params := &iam.ListAccountAliasesInput{}

	resp, err := conn.ListAccountAliases(params)

	if err != nil {
		return fmt.Errorf("Error listing account aliases: %s", err)
	}

	if resp == nil || len(resp.AccountAliases) == 0 {
		d.SetId("")
		return nil
	}

	account_alias := aws.StringValue(resp.AccountAliases[0])

	d.SetId(account_alias)
	d.Set("account_alias", account_alias)

	return nil
}

func resourceAwsIamAccountAliasDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).iamconn

	account_alias := d.Get("account_alias").(string)

	params := &iam.DeleteAccountAliasInput{
		AccountAlias: aws.String(account_alias),
	}

	_, err := conn.DeleteAccountAlias(params)

	if err != nil {
		return fmt.Errorf("Error deleting account alias with name '%s': %s", account_alias, err)
	}

	d.SetId("")

	return nil
}
<|endoftext|>


<commit_before>package glutton

import (
	"errors"
	"log"
	"net"
	"os"
)

type address struct {
	srcAddr net.Addr
	dstAddr net.Addr
}

type reader interface {
	Read(p []byte) (n int, err error)
}

type writer interface {
	Write(p []byte) (n int, err error)
}

type readerFrom interface {
	ReadFrom(r reader) (n int64, err error)
}

type writerTo interface {
	WriteTo(w writer) (n int64, err error)
}

// TCPClient for proxy connections
func TCPClient(addr string) *net.TCPConn {

	tcpAddr, err := net.ResolveTCPAddr("tcp", addr)
	if err != nil {
		log.Println("Error. ResolveTCPAddr failed:", err.Error())
		return nil
	}

	conn, err := net.DialTCP("tcp", nil, tcpAddr)
	if err != nil {
		log.Println("Error. Dial failed: Host either not active or not responding ", err.Error())
		return nil
	}

	return conn
}

// ProxyServer handles the proxy connections
func ProxyServer(srvConn, cliConn *net.TCPConn, file *os.File) {

	// f = file
	log.SetOutput(file)
	serverClosed := make(chan struct{}, 1)
	clientClosed := make(chan struct{}, 1)

	go TCPBroker(srvConn, cliConn, clientClosed)
	go TCPBroker(cliConn, srvConn, serverClosed)

	var waitFor chan struct{}
	select {
	case <-clientClosed:
		srvConn.SetLinger(0)
		srvConn.CloseRead()
		waitFor = serverClosed
	case <-serverClosed:
		cliConn.CloseRead()
		waitFor = clientClosed
	}

	<-waitFor
}

// TCPBroker is handling a TCP connection
func TCPBroker(dst, src net.Conn, srcClosed chan struct{}) {

	_, err := transfer(dst, src, address{src.RemoteAddr(), dst.RemoteAddr()})

	if err != nil {
		log.Printf("Warning Copy error: %s", err)
	}
	if err := src.Close(); err != nil {
		log.Printf("Warning Close error: %s", err)
	}
	srcClosed <- struct{}{}
}

func transfer(dst writer, src reader, addr interface{}) (int64, error) {
	v := addr.(address)
	if wt, ok := src.(writerTo); ok {
		return wt.WriteTo(dst)
	}

	if rt, ok := dst.(readerFrom); ok {
		return rt.ReadFrom(src)
	}

	buf := make([]byte, 32*1024)
	var written int64
	var err error

	for {
		nr, readErr := src.Read(buf)
		if nr > 0 {
			nw, writeErr := dst.Write(buf[0:nr])
			log.Printf("[TCP] [%v -> %v] Payload: %v", v.srcAddr, v.dstAddr, string(buf[0:nr]))
			if nw > 0 {
				written += int64(nw)
			}
			if writeErr != nil {
				err = writeErr
				break
			}
			if nr != nw {
				err = errors.New("Short write")
				break
			}
		}
		if readErr == errors.New("EOF") {
			break
		}
		if readErr != nil {
			err = readErr
			break
		}

	}
	return written, err
}
<commit_msg>removing the payload from logging and newline to message<commit_after>package glutton

import (
	"errors"
	"log"
	"net"
	"os"
)

type address struct {
	srcAddr net.Addr
	dstAddr net.Addr
}

type reader interface {
	Read(p []byte) (n int, err error)
}

type writer interface {
	Write(p []byte) (n int, err error)
}

type readerFrom interface {
	ReadFrom(r reader) (n int64, err error)
}

type writerTo interface {
	WriteTo(w writer) (n int64, err error)
}

// TCPClient for proxy connections
func TCPClient(addr string) *net.TCPConn {

	tcpAddr, err := net.ResolveTCPAddr("tcp", addr)
	if err != nil {
		log.Println("Error. ResolveTCPAddr failed:", err.Error())
		return nil
	}

	conn, err := net.DialTCP("tcp", nil, tcpAddr)
	if err != nil {
		log.Println("Error. Dial failed: Host either not active or not responding ", err.Error())
		return nil
	}

	return conn
}

// ProxyServer handles the proxy connections
func ProxyServer(srvConn, cliConn *net.TCPConn, file *os.File) {

	// f = file
	log.SetOutput(file)
	serverClosed := make(chan struct{}, 1)
	clientClosed := make(chan struct{}, 1)

	go TCPBroker(srvConn, cliConn, clientClosed)
	go TCPBroker(cliConn, srvConn, serverClosed)

	var waitFor chan struct{}
	select {
	case <-clientClosed:
		srvConn.SetLinger(0)
		srvConn.CloseRead()
		waitFor = serverClosed
	case <-serverClosed:
		cliConn.CloseRead()
		waitFor = clientClosed
	}

	<-waitFor
}

// TCPBroker is handling a TCP connection
func TCPBroker(dst, src net.Conn, srcClosed chan struct{}) {

	_, err := transfer(dst, src, address{src.RemoteAddr(), dst.RemoteAddr()})

	if err != nil {
		log.Printf("Warning Copy error: %s", err)
	}
	if err := src.Close(); err != nil {
		log.Printf("Warning Close error: %s", err)
	}
	srcClosed <- struct{}{}
}

func transfer(dst writer, src reader, addr interface{}) (int64, error) {
	v := addr.(address)
	if wt, ok := src.(writerTo); ok {
		return wt.WriteTo(dst)
	}

	if rt, ok := dst.(readerFrom); ok {
		return rt.ReadFrom(src)
	}

	buf := make([]byte, 32*1024)
	var written int64
	var err error

	for {
		nr, readErr := src.Read(buf)
		if nr > 0 {
			nw, writeErr := dst.Write(buf[0:nr])
			log.Printf("[TCP] [%v -> %v]\n", v.srcAddr, v.dstAddr)
			if nw > 0 {
				written += int64(nw)
			}
			if writeErr != nil {
				err = writeErr
				break
			}
			if nr != nw {
				err = errors.New("Short write")
				break
			}
		}
		if readErr == errors.New("EOF") {
			break
		}
		if readErr != nil {
			err = readErr
			break
		}

	}
	return written, err
}
<|endoftext|>


<commit_before>/*
Package iterfloat64x2 provides tools for creating iterators for the [2]float64 type.

These iterators are intentionally made to resemble *sql.Rows from the "database/sql" package.
Including having the same Close, Err, Next, and Scan methods.

(Note that to turn something into an actual *sql.Rows from the "database/sql" package, instead of just resembling it,
use https://github.com/reiver/go-shunt instead.)

For example, we can turn a slice into an iterator, with code like the following:

	var slice [][2]float64 = [][2]float64 {
		[2]float64{5.0, -25.0},
		[2]float64{4.0,-16.0},
		[2]float64{3.0, -9.0},
		[2]float64{2.0, -4.0},
		[2]float64{1.0, -1.0},
		[2]float64{0.0,  0.0},
		[2]float64{1.0,  0.1},
		[2]float64{2.0,  0.4},
		[2]float64{3.0,  0.9},
		[2]float64{4.0,  0.16},
		[2]float64{5.0,  0.25},
	}

	iterator := iterfloat64x2.Slice{
		Slice: slice,
	}

	defer iterator.Close()

	for iterator.Next() {

		var datum [2]float64 // Could have also used: var datum interface{}

		if err := iterator.Decode(&datum); nil != err {
			return err
		}

		fmt.Printf("Next datum: %v \n", datum)
	}
	if err := iterator.Err(); nil != err {
		return err
	}

This can help to enable us to write more (run-time oriented) generic code.

To be able to distinguish one iterator type from another, in a (run-time oriented)
generic way, that is not so specific to this package, we can use the Type method.

For example:

	switch reflect.Zero( iterator.Type() ).Interface().(type) {
	case bool:
		//@TODO
	case byte:
		//@TODO
	case complex64:
		//@TODO
	case complex128:
		//@TODO
	case float32:
		//@TODO
	case float64:
		//@TODO
	case [2]float64:
		//@TODO
	case [3]float64:
		//@TODO
	case [4]float64:
		//@TODO
	case int8:
		//@TODO
	case int16:
		//@TODO
	case int32:
		//@TODO
	case int64:
		//@TODO
	case rune:
		//@TODO
	case string:
		//@TODO
	case struct{}:
		//@TODO
	case time.Time:
		//@TODO
	case uint8:
		//@TODO
	case uint16:
		//@TODO
	case uint32:
		//@TODO
	case uint64:
		//@TODO
	default:
		//@TODO
	}
*/
package iterfloat64x2
<commit_msg>added docs<commit_after>/*
Package iterstring provides tools for creating iterators for the string type.

These iterators are intentionally made to resemble *sql.Rows from the "database/sql" package.
Including having the same Close, Err, Next, and Scan methods.

(Note that to turn something into an actual *sql.Rows from the "database/sql" package, instead of just resembling it,
use https://github.com/reiver/go-shunt instead.)

For example, we can turn a slice into an iterator, with code like the following:

	var slice []string = []string {
		false,
		true,
		true,
		false,
		true,
	}

	iterator := iterstring.Slice{
		Slice: slice,
	}

	defer iterator.Close()

	for iterator.Next() {

		var datum string // Could have also used: var datum interface{}

		if err := iterator.Decode(&datum); nil != err {
			return err
		}

		fmt.Printf("Next datum: %v \n", datum)
	}
	if err := iterator.Err(); nil != err {
		return err
	}

This can help to enable us to write more (run-time oriented) generic code.

To be able to distinguish one iterator type from another, in a (run-time oriented)
generic way, that is not so specific to this package, we can use the Type method.

For example:

	switch reflect.Zero( iterator.Type() ).Interface().(type) {
	case bool:
		//@TODO
	case byte:
		//@TODO
	case complex64:
		//@TODO
	case complex128:
		//@TODO
	case float32:
		//@TODO
	case float64:
		//@TODO
	case [2]float64:
		//@TODO
	case [3]float64:
		//@TODO
	case [4]float64:
		//@TODO
	case int8:
		//@TODO
	case int16:
		//@TODO
	case int32:
		//@TODO
	case int64:
		//@TODO
	case rune:
		//@TODO
	case string:
		//@TODO
	case struct{}:
		//@TODO
	case time.Time:
		//@TODO
	case uint8:
		//@TODO
	case uint16:
		//@TODO
	case uint32:
		//@TODO
	case uint64:
		//@TODO
	default:
		//@TODO
	}
*/
package iterstring
<|endoftext|>


<commit_before>package tasks

import (
	"context"
	"time"

	"pixur.org/pixur/be/schema"
	"pixur.org/pixur/be/schema/db"
	tab "pixur.org/pixur/be/schema/tables"
	"pixur.org/pixur/be/status"
)

type IncrementViewCountTask struct {
	// Deps
	Beg tab.JobBeginner
	Now func() time.Time

	// Inputs
	PicID int64
}

func (t *IncrementViewCountTask) Run(ctx context.Context) (stscap status.S) {
	userID, ok := UserIDFromCtx(ctx)
	if !ok {
		return status.Unauthenticated(nil, "no user provided")
	}
	_ = userID // TODO: use this
	j, err := tab.NewJob(ctx, t.Beg)
	if err != nil {
		return status.Internal(err, "can't create job")
	}
	defer revert(j, &stscap)

	if _, sts := requireCapability(ctx, j, schema.User_PIC_UPDATE_VIEW_COUNTER); sts != nil {
		return sts
	}

	pics, err := j.FindPics(db.Opts{
		Prefix: tab.PicsPrimary{Id: &t.PicID},
		Limit:  1,
		Lock:   db.LockWrite,
	})
	if err != nil {
		return status.Internal(err, "can't find pics")
	}
	if len(pics) != 1 {
		return status.NotFound(nil, "can't lookup pic")
	}
	p := pics[0]

	if p.HardDeleted() {
		return status.InvalidArgument(nil, "can't update view count of deleted pic")
	}

	// TODO: This needs some sort of debouncing to avoid being run up.
	p.ViewCount++
	p.SetModifiedTime(t.Now())

	if err := j.UpdatePic(p); err != nil {
		return status.Internal(err, "can't update pic")
	}

	if err := j.Commit(); err != nil {
		return status.Internal(err, "can't commit job")
	}

	return nil
}
<commit_msg>be/tasks: let anonymous users increment view count<commit_after>package tasks

import (
	"context"
	"time"

	"pixur.org/pixur/be/schema"
	"pixur.org/pixur/be/schema/db"
	tab "pixur.org/pixur/be/schema/tables"
	"pixur.org/pixur/be/status"
)

type IncrementViewCountTask struct {
	// Deps
	Beg tab.JobBeginner
	Now func() time.Time

	// Inputs
	PicID int64
}

func (t *IncrementViewCountTask) Run(ctx context.Context) (stscap status.S) {
	j, err := tab.NewJob(ctx, t.Beg)
	if err != nil {
		return status.Internal(err, "can't create job")
	}
	defer revert(j, &stscap)

	if _, sts := requireCapability(ctx, j, schema.User_PIC_UPDATE_VIEW_COUNTER); sts != nil {
		return sts
	}

	pics, err := j.FindPics(db.Opts{
		Prefix: tab.PicsPrimary{Id: &t.PicID},
		Limit:  1,
		Lock:   db.LockWrite,
	})
	if err != nil {
		return status.Internal(err, "can't find pics")
	}
	if len(pics) != 1 {
		return status.NotFound(nil, "can't lookup pic")
	}
	p := pics[0]

	if p.HardDeleted() {
		return status.InvalidArgument(nil, "can't update view count of deleted pic")
	}

	// TODO: This needs some sort of debouncing to avoid being run up.
	p.ViewCount++
	p.SetModifiedTime(t.Now())

	if err := j.UpdatePic(p); err != nil {
		return status.Internal(err, "can't update pic")
	}

	if err := j.Commit(); err != nil {
		return status.Internal(err, "can't commit job")
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"sync"

	"github.com/bitly/go-simplejson"
)

const (
	KubernetesAPIServer = "192.168.1.200:8080"
	Port                = ":55123"
	Tag                 = "raft"
)

var (
	hosts    []string
	next     int = 0
	nextLock sync.Mutex
)

func UpdateHosts() error {
	hst, err := getIPsFromKubernetes(Tag)

	hosts = hst

	return err
}

func Update(rw http.ResponseWriter, req *http.Request) {
	err := UpdateHosts()

	if err != nil {
		fmt.Fprintln(rw, err)
		rw.WriteHeader(http.StatusInternalServerError)
		return
	}

	fmt.Fprintln(rw, "Hosts: ", hosts)
}

func Hosts(rw http.ResponseWriter, req *http.Request) {
	fmt.Fprintln(rw, "Hosts: ", hosts)
}

func Forward(rw http.ResponseWriter, req *http.Request) {
	nextLock.Lock()
	host := hosts[next]
	next = (next + 1) % len(hosts)
	nextLock.Unlock()

	url := host + Port + req.URL.Path

	log.Printf("fowarding: %v", url)

	resp, err := http.Get("http://" + url)

	if err != nil {
		rw.WriteHeader(http.StatusInternalServerError)
		return
	}

	body, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		rw.WriteHeader(http.StatusInternalServerError)
		return
	}

	rw.WriteHeader(resp.StatusCode)
	rw.Write(body)
}

func main() {

	http.HandleFunc("/update", Update)
	http.HandleFunc("/hosts", Hosts)
	http.HandleFunc("/", Forward)

	if UpdateHosts() != nil {
		fmt.Println("Error on initial update!")
		os.Exit(1)
	}

	http.ListenAndServe(":12345", nil)

}

func getIPsFromKubernetes(tag string) ([]string, error) {
	log.Printf("starting getIPsFromKubernetes(%s)\n", tag)

	resp, err := http.Get("http://" + KubernetesAPIServer + "/api/v1/namespaces/default/endpoints/" + tag)

	if err != nil {
		return nil, err
	}

	log.Println("GET successful")

	defer resp.Body.Close()

	content, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		return nil, err
	}

	log.Println("Read body")

	json, err := simplejson.NewJson(content)

	if err != nil {
		return nil, err
	}

	log.Println("Parsing json")

	replicas := make([]string, 0)

	addresses := json.Get("subsets").GetIndex(0).Get("addresses")

	for i := 0; ; i++ {

		ip, err := addresses.GetIndex(i).Get("ip").String()

		if err != nil {
			break
		}

		replicas = append(replicas, ip)
	}

	log.Printf("Done: %v\n", replicas)

	return replicas, nil
}
<commit_msg>Final version of generic firewall<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"sync"

	"github.com/bitly/go-simplejson"
)

const (
	KubernetesAPIServer = "192.168.1.200:8080"
)

var (
	PORT     = ":" + os.Getenv("PORT")
	TAG      = os.Getenv("TAG")
	hosts    []string
	next     = 0
	nextLock sync.Mutex
)

func RedirectHandler(req *http.Request, via []*http.Request) error {
	fmt.Println(via)

	return nil
}

var client = &http.Client{
	CheckRedirect: RedirectHandler,
}

func UpdateHosts() error {
	hst, err := getIPsFromKubernetes(TAG)

	hosts = hst

	return err
}

func Update(rw http.ResponseWriter, req *http.Request) {
	err := UpdateHosts()

	if err != nil {
		fmt.Fprintln(rw, err)
		rw.WriteHeader(http.StatusInternalServerError)
		return
	}

	fmt.Fprintln(rw, "Hosts: ", hosts)
}

func Hosts(rw http.ResponseWriter, req *http.Request) {
	fmt.Fprintln(rw, "Hosts: ", hosts)
}

func Forward(rw http.ResponseWriter, req *http.Request) {
	nextLock.Lock()
	host := hosts[next]
	next = (next + 1) % len(hosts)
	nextLock.Unlock()

	url := host + PORT + req.URL.Path

	log.Printf("fowarding: %v", url)

	resp, err := client.Get("http://" + url)

	if err != nil {
		rw.WriteHeader(http.StatusInternalServerError)
		fmt.Fprintln(rw, "Error: get")
		return
	}

	body, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		rw.WriteHeader(http.StatusInternalServerError)
		fmt.Fprintln(rw, "Error: read body")
		return
	}

	rw.WriteHeader(resp.StatusCode)
	rw.Write(body)
}

func Version(rw http.ResponseWriter, req *http.Request) {
	fmt.Fprintln(rw, 1)
}

func main() {

	http.HandleFunc("/update", Update)
	http.HandleFunc("/hosts", Hosts)
	http.HandleFunc("/version", Version)
	http.HandleFunc("/", Forward)

	if UpdateHosts() != nil {
		fmt.Println("Error on initial update!")
		os.Exit(1)
	}

	http.ListenAndServe(":12345", nil)

}

func getIPsFromKubernetes(tag string) ([]string, error) {
	log.Printf("starting getIPsFromKubernetes(%s)\n", tag)

	resp, err := http.Get("http://" + KubernetesAPIServer + "/api/v1/namespaces/default/endpoints/" + tag)

	if err != nil {
		return nil, err
	}

	log.Println("GET successful")

	defer resp.Body.Close()

	content, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		return nil, err
	}

	log.Println("Read body")

	json, err := simplejson.NewJson(content)

	if err != nil {
		return nil, err
	}

	log.Println("Parsing json")

	replicas := make([]string, 0)

	addresses := json.Get("subsets").GetIndex(0).Get("addresses")

	for i := 0; ; i++ {

		ip, err := addresses.GetIndex(i).Get("ip").String()

		if err != nil {
			break
		}

		replicas = append(replicas, ip)
	}

	log.Printf("Done: %v\n", replicas)

	return replicas, nil
}
<|endoftext|>


<commit_before>// Copyright (c) 2016-2017 The btcsuite developers
// Copyright (c) 2016-2017 The Lightning Network Developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package gcs_test

import (
	"encoding/binary"
	"math/rand"
	"testing"

	"github.com/roasbeef/btcutil/gcs"
)

func genRandFilterElements(numElements uint) ([][]byte, error) {
	testContents := make([][]byte, numElements)
	for i := range contents {
		randElem := make([]byte, 32)
		if _, err := rand.Read(randElem); err != nil {
			return nil, err
		}
		testContents[i] = randElem
	}

	return testContents, nil
}

var (
	generatedFilter *gcs.Filter
	filterErr       error
)

// BenchmarkGCSFilterBuild benchmarks building a filter.
func BenchmarkGCSFilterBuild50000(b *testing.B) {
	b.StopTimer()
	var testKey [gcs.KeySize]byte
	for i := 0; i < gcs.KeySize; i += 4 {
		binary.BigEndian.PutUint32(testKey[i:], rand.Uint32())
	}
	randFilterElems, genErr := genRandFilterElements(50000)
	if err != nil {
		b.Fatalf("unable to generate random item: %v", genErr)
	}
	b.StartTimer()

	var localFilter *gcs.Filter
	for i := 0; i < b.N; i++ {
		localFilter, err = gcs.BuildGCSFilter(P, key,
			randFilterElems)
		if err != nil {
			b.Fatalf("unable to generate filter: %v", err)
		}
	}
	generatedFilter = localFilter
}

var (
	match bool
)

// BenchmarkGCSFilterMatch benchmarks querying a filter for a single value.
func BenchmarkGCSFilterMatch(b *testing.B) {
	b.StopTimer()
	filter, err := gcs.BuildGCSFilter(P, key, contents)
	if err != nil {
		b.Fatalf("Failed to build filter")
	}
	b.StartTimer()

	var (
		localMatch bool
	)
	for i := 0; i < b.N; i++ {
		localMatch, err = filter.Match(key, []byte("Nate"))
		if err != nil {
			b.Fatalf("unable to match filter: %v", err)
		}

		localMatch, err = filter.Match(key, []byte("Nates"))
		if err != nil {
			b.Fatalf("unable to match filter: %v", err)
		}
	}
	match = localMatch
}

// BenchmarkGCSFilterMatchAny benchmarks querying a filter for a list of
// values.
func BenchmarkGCSFilterMatchAny(b *testing.B) {
	b.StopTimer()
	filter, err := gcs.BuildGCSFilter(P, key, contents)
	if err != nil {
		b.Fatalf("Failed to build filter")
	}
	b.StartTimer()

	var (
		localMatch bool
	)
	for i := 0; i < b.N; i++ {
		localMatch, err = filter.MatchAny(key, contents2)
		if err != nil {
			b.Fatalf("unable to match filter: %v", err)
		}
	}
	match = localMatch
}
<commit_msg>gcs: add an extra benchmark for a filter with 100k items<commit_after>// Copyright (c) 2016-2017 The btcsuite developers
// Copyright (c) 2016-2017 The Lightning Network Developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package gcs_test

import (
	"encoding/binary"
	"math/rand"
	"testing"

	"github.com/btcsuite/btcutil/gcs"
)

func genRandFilterElements(numElements uint) ([][]byte, error) {
	testContents := make([][]byte, numElements)
	for i := range contents {
		randElem := make([]byte, 32)
		if _, err := rand.Read(randElem); err != nil {
			return nil, err
		}
		testContents[i] = randElem
	}

	return testContents, nil
}

var (
	generatedFilter *gcs.Filter
	filterErr       error
)

// BenchmarkGCSFilterBuild benchmarks building a filter.
func BenchmarkGCSFilterBuild50000(b *testing.B) {
	b.StopTimer()
	var testKey [gcs.KeySize]byte
	for i := 0; i < gcs.KeySize; i += 4 {
		binary.BigEndian.PutUint32(testKey[i:], rand.Uint32())
	}
	randFilterElems, genErr := genRandFilterElements(50000)
	if err != nil {
		b.Fatalf("unable to generate random item: %v", genErr)
	}
	b.StartTimer()

	var localFilter *gcs.Filter
	for i := 0; i < b.N; i++ {
		localFilter, err = gcs.BuildGCSFilter(P, key,
			randFilterElems)
		if err != nil {
			b.Fatalf("unable to generate filter: %v", err)
		}
	}
	generatedFilter = localFilter
}

// BenchmarkGCSFilterBuild benchmarks building a filter.
func BenchmarkGCSFilterBuild100000(b *testing.B) {
	b.StopTimer()
	var testKey [gcs.KeySize]byte
	for i := 0; i < gcs.KeySize; i += 4 {
		binary.BigEndian.PutUint32(testKey[i:], rand.Uint32())
	}
	randFilterElems, genErr := genRandFilterElements(100000)
	if err != nil {
		b.Fatalf("unable to generate random item: %v", genErr)
	}
	b.StartTimer()

	var localFilter *gcs.Filter
	for i := 0; i < b.N; i++ {
		localFilter, err = gcs.BuildGCSFilter(P, key,
			randFilterElems)
		if err != nil {
			b.Fatalf("unable to generate filter: %v", err)
		}
	}
	generatedFilter = localFilter
}

var (
	match bool
)

// BenchmarkGCSFilterMatch benchmarks querying a filter for a single value.
func BenchmarkGCSFilterMatch(b *testing.B) {
	b.StopTimer()
	filter, err := gcs.BuildGCSFilter(P, key, contents)
	if err != nil {
		b.Fatalf("Failed to build filter")
	}
	b.StartTimer()

	var (
		localMatch bool
	)
	for i := 0; i < b.N; i++ {
		localMatch, err = filter.Match(key, []byte("Nate"))
		if err != nil {
			b.Fatalf("unable to match filter: %v", err)
		}

		localMatch, err = filter.Match(key, []byte("Nates"))
		if err != nil {
			b.Fatalf("unable to match filter: %v", err)
		}
	}
	match = localMatch
}

// BenchmarkGCSFilterMatchAny benchmarks querying a filter for a list of
// values.
func BenchmarkGCSFilterMatchAny(b *testing.B) {
	b.StopTimer()
	filter, err := gcs.BuildGCSFilter(P, key, contents)
	if err != nil {
		b.Fatalf("Failed to build filter")
	}
	b.StartTimer()

	var (
		localMatch bool
	)
	for i := 0; i < b.N; i++ {
		localMatch, err = filter.MatchAny(key, contents2)
		if err != nil {
			b.Fatalf("unable to match filter: %v", err)
		}
	}
	match = localMatch
}
<|endoftext|>


<commit_before>package generator

import (
	"fmt"
	"go/format"
	"io/ioutil"
	"os"
	"path/filepath"
	"sort"
)

const UTIL_FILE = "primitive.go"

// Represents the output package
type Package struct {
	name  string
	files map[string]*File
}

func NewPackage(name string) *Package {
	return &Package{name: name, files: make(map[string]*File)}
}

func (p *Package) WriteFiles(targetDir string) error {
	for _, f := range p.files {
		err := f.writeFile(p.name, filepath.Join(targetDir, f.name))
		if err != nil {
			return err
		}
	}
	return nil
}

func (p *Package) Files() []string {
	files := make([]string, 0)
	for file, _ := range p.files {
		files = append(files, file)
	}
	sort.Strings(files)
	return files
}

func (p *Package) File(name string) (*File, bool) {
	file, ok := p.files[name]
	return file, ok
}

func (p *Package) addFunction(file, str, name, def string) {
	f, ok := p.files[file]
	if !ok {
		f = &File{file, make(map[FunctionName]string), make(map[string]string), make(map[string]interface{})}
		p.files[file] = f
	}
	f.functions[FunctionName{str, name}] = def
}

func (p *Package) addStruct(file, name, def string) {
	f, ok := p.files[file]
	if !ok {
		f = &File{file, make(map[FunctionName]string), make(map[string]string), make(map[string]interface{})}
		p.files[file] = f
	}
	f.structs[name] = def
}

func (p *Package) addImport(file, name string) {
	f, ok := p.files[file]
	if !ok {
		f = &File{file, make(map[FunctionName]string), make(map[string]string), make(map[string]interface{})}
		p.files[file] = f
	}
	f.imports[name] = 1
}

func (p *Package) hasStruct(file, name string) bool {
	f, ok := p.files[file]
	if !ok {
		return false
	}
	_, ok = f.structs[name]
	return ok
}

func (p *Package) hasFunction(file, str, name string) bool {
	f, ok := p.files[file]
	if !ok {
		return false
	}
	_, ok = f.functions[FunctionName{str, name}]
	return ok
}

func (p *Package) hasImport(file, name string) bool {
	f, ok := p.files[file]
	if !ok {
		return false
	}
	_, ok = f.imports[name]
	return ok
}

// Represents a Go source file in the output package
type File struct {
	name      string
	functions map[FunctionName]string
	structs   map[string]string
	imports   map[string]interface{}
}

type FunctionName struct {
	// The target struct type, if there is one
	str string
	// The function name
	name string
}

func (f *File) Imports() []string {
	imports := make([]string, 0)
	for i, _ := range f.imports {
		imports = append(imports, i)
	}
	sort.Strings(imports)
	return imports
}

func (f *File) Structs() []string {
	structs := make([]string, 0)
	for s, _ := range f.structs {
		structs = append(structs, s)
	}
	sort.Strings(structs)
	return structs
}

func (f *File) Functions() []FunctionName {
	funcs := make([]FunctionName, 0)
	for f, _ := range f.functions {
		funcs = append(funcs, f)
	}
	sort.Sort(FunctionNameList(funcs))
	return funcs
}

func (f *File) importString() string {
	if len(f.imports) == 0 {
		return ""
	}
	imports := "import (\n"
	for i, _ := range f.imports {
		imports += fmt.Sprintf("%q\n", i)
	}
	imports += ")"
	return imports
}

func (f *File) structString() string {
	structs := ""
	keys := make([]string, 0)
	for k := range f.structs {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	for _, k := range keys {
		structs += f.structs[k] + "\n"
	}
	return structs
}

func (f *File) functionString() string {
	funcs := ""
	keys := make(FunctionNameList, 0)
	for k := range f.functions {
		keys = append(keys, k)
	}
	sort.Sort(keys)
	for _, k := range keys {
		funcs += f.functions[k] + "\n"
	}
	return funcs
}

/* Write the contents of the file:
- imports (all in one block)
- struct definitions (alphabetically)
- functions (sorted alphabetically by struct to which they're attached, then unattached funcs)
TODO: It'd be better to group funcs attached to a struct with the struct definition
*/
func (f *File) writeFile(pkgName, targetFile string) error {
	src := fmt.Sprintf("package %v\n%v\n%v\n%v\n", pkgName, f.importString(), f.structString(), f.functionString())
	fileContent, err := format.Source([]byte(src))
	if err != nil {
		return fmt.Errorf("Error formatting file %v - %v\n\nContents: %v", f.name, err, src)
	}
	err = ioutil.WriteFile(targetFile, fileContent, os.ModePerm)
	if err != nil {
		return fmt.Errorf("Error writing file %v - %v", f.name, err)
	}
	return nil
}

/* Implement the Sortable interface for FunctionNames */
type FunctionNameList []FunctionName

func (f FunctionNameList) Len() int {
	return len(f)
}

func (f FunctionNameList) Swap(i, j int) {
	f[i], f[j] = f[j], f[i]
}

/* Sort functions by the struct to which they're attached first, then the name of the method itself. If the function isn't attached to a struct, put it at the bottom */
func (f FunctionNameList) Less(i, j int) bool {
	if f[i].str == "" && f[j].str != "" {
		return true
	}
	if f[i].str != "" && f[j].str == "" {
		return false
	}
	if f[i].str != "" && f[j].str != "" {
		if f[i].str > f[j].str {
			return true
		} else if f[i].str < f[j].str {
			return false
		}
	}
	return f[i].name < f[j].name
}
<commit_msg>Add NewFile constructor<commit_after>package generator

import (
	"fmt"
	"go/format"
	"io/ioutil"
	"os"
	"path/filepath"
	"sort"
)

const UTIL_FILE = "primitive.go"

// Represents the output package
type Package struct {
	name  string
	files map[string]*File
}

func NewPackage(name string) *Package {
	return &Package{name: name, files: make(map[string]*File)}
}

func (p *Package) WriteFiles(targetDir string) error {
	for _, f := range p.files {
		err := f.writeFile(p.name, filepath.Join(targetDir, f.name))
		if err != nil {
			return err
		}
	}
	return nil
}

func (p *Package) Files() []string {
	files := make([]string, 0)
	for file, _ := range p.files {
		files = append(files, file)
	}
	sort.Strings(files)
	return files
}

func (p *Package) File(name string) (*File, bool) {
	file, ok := p.files[name]
	return file, ok
}

func (p *Package) addFunction(file, str, name, def string) {
	f, ok := p.files[file]
	if !ok {
		f = NewFile(file)
		p.files[file] = f
	}
	f.functions[FunctionName{str, name}] = def
}

func (p *Package) addStruct(file, name, def string) {
	f, ok := p.files[file]
	if !ok {
		f = NewFile(file)
		p.files[file] = f
	}
	f.structs[name] = def
}

func (p *Package) addImport(file, name string) {
	f, ok := p.files[file]
	if !ok {
		f = NewFile(file)
		p.files[file] = f
	}
	f.imports[name] = 1
}

func (p *Package) hasStruct(file, name string) bool {
	f, ok := p.files[file]
	if !ok {
		return false
	}
	_, ok = f.structs[name]
	return ok
}

func (p *Package) hasFunction(file, str, name string) bool {
	f, ok := p.files[file]
	if !ok {
		return false
	}
	_, ok = f.functions[FunctionName{str, name}]
	return ok
}

func (p *Package) hasImport(file, name string) bool {
	f, ok := p.files[file]
	if !ok {
		return false
	}
	_, ok = f.imports[name]
	return ok
}

// Represents a Go source file in the output package
type File struct {
	name      string
	functions map[FunctionName]string
	structs   map[string]string
	imports   map[string]interface{}
}

func NewFile(name string) *File {
	return &File{name: name, functions: make(map[FunctionName]string), structs: make(map[string]string), imports: make(map[string]interface{})}
}

type FunctionName struct {
	// The target struct type, if there is one
	str string
	// The function name
	name string
}

func (f *File) Imports() []string {
	imports := make([]string, 0)
	for i, _ := range f.imports {
		imports = append(imports, i)
	}
	sort.Strings(imports)
	return imports
}

func (f *File) Structs() []string {
	structs := make([]string, 0)
	for s, _ := range f.structs {
		structs = append(structs, s)
	}
	sort.Strings(structs)
	return structs
}

func (f *File) Functions() []FunctionName {
	funcs := make([]FunctionName, 0)
	for f, _ := range f.functions {
		funcs = append(funcs, f)
	}
	sort.Sort(FunctionNameList(funcs))
	return funcs
}

func (f *File) importString() string {
	if len(f.imports) == 0 {
		return ""
	}
	imports := "import (\n"
	for i, _ := range f.imports {
		imports += fmt.Sprintf("%q\n", i)
	}
	imports += ")"
	return imports
}

func (f *File) structString() string {
	structs := ""
	keys := make([]string, 0)
	for k := range f.structs {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	for _, k := range keys {
		structs += f.structs[k] + "\n"
	}
	return structs
}

func (f *File) functionString() string {
	funcs := ""
	keys := make(FunctionNameList, 0)
	for k := range f.functions {
		keys = append(keys, k)
	}
	sort.Sort(keys)
	for _, k := range keys {
		funcs += f.functions[k] + "\n"
	}
	return funcs
}

/* Write the contents of the file:
- imports (all in one block)
- struct definitions (alphabetically)
- functions (sorted alphabetically by struct to which they're attached, then unattached funcs)
TODO: It'd be better to group funcs attached to a struct with the struct definition
*/
func (f *File) writeFile(pkgName, targetFile string) error {
	src := fmt.Sprintf("package %v\n%v\n%v\n%v\n", pkgName, f.importString(), f.structString(), f.functionString())
	fileContent, err := format.Source([]byte(src))
	if err != nil {
		return fmt.Errorf("Error formatting file %v - %v\n\nContents: %v", f.name, err, src)
	}
	err = ioutil.WriteFile(targetFile, fileContent, os.ModePerm)
	if err != nil {
		return fmt.Errorf("Error writing file %v - %v", f.name, err)
	}
	return nil
}

/* Implement the Sortable interface for FunctionNames */
type FunctionNameList []FunctionName

func (f FunctionNameList) Len() int {
	return len(f)
}

func (f FunctionNameList) Swap(i, j int) {
	f[i], f[j] = f[j], f[i]
}

/* Sort functions by the struct to which they're attached first, then the name of the method itself. If the function isn't attached to a struct, put it at the bottom */
func (f FunctionNameList) Less(i, j int) bool {
	if f[i].str == "" && f[j].str != "" {
		return true
	}
	if f[i].str != "" && f[j].str == "" {
		return false
	}
	if f[i].str != "" && f[j].str != "" {
		if f[i].str > f[j].str {
			return true
		} else if f[i].str < f[j].str {
			return false
		}
	}
	return f[i].name < f[j].name
}
<|endoftext|>


<commit_before>package auth

import (
	"net/http"
	"sync"
	"time"

	"github.com/aybabtme/log"
	"github.com/pquerna/otp/totp"
	"github.com/satori/go.uuid"
)

type Config struct {
	Token string
	Log   *log.Log
}

type Authenticator struct {
	Config        *Config
	authedClients []*Client
	clientsMutex  sync.RWMutex
}

// Client is an authenticated web ui session
type Client struct {
	UUID  string
	Added time.Time
}

func New(config *Config) *Authenticator {
	authenticator := &Authenticator{
		Config: config,
	}

	go authenticator.ExpireClients()
	return authenticator
}

func (a *Authenticator) Authenticate(w http.ResponseWriter, r *http.Request) (bool, error) {
	cookie, err := r.Cookie("session")

	if err != nil {
		if err != http.ErrNoCookie {
			a.Config.Log.Err(err).Error("could not authenticate user")

			return false, err
		}

		err = nil
	}

	authed := false
	if cookie != nil {
		a.clientsMutex.RLock()
		for _, client := range a.authedClients {
			if cookie.Value == client.UUID {
				authed = true
				break
			}
		}
		a.clientsMutex.RUnlock()
	}

	if !authed && a.hasValidToken(r) {
		cookie = &http.Cookie{
			Name:  "session",
			Value: uuid.NewV4().String(),
			Path:  "/",
		}

		a.clientsMutex.Lock()
		a.authedClients = append(a.authedClients, &Client{
			UUID:  cookie.Value,
			Added: time.Now(),
		})
		a.clientsMutex.Unlock()

		authed = true
		http.SetCookie(w, cookie)
	}

	return authed, nil
}

func (a *Authenticator) hasValidToken(r *http.Request) bool {
	token := r.URL.Query().Get("token")
	if token == "" {
		return false
	}

	return totp.Validate(token, a.Config.Token)
}

func (a *Authenticator) ExpireClients() {
	for {
		<-time.After(2 * time.Minute)
		go func() {
			now := time.Now()

			for i, client := range a.authedClients {
				if now.Sub(client.Added).Hours() >= 48 {
					a.authedClients = append(a.authedClients[:i], a.authedClients[i+1:]...)
				}
			}
		}()
	}
}

func (a *Authenticator) GetToken() (string, error) {
	return totp.GenerateCode(a.Config.Token, time.Now())
}
<commit_msg>use a mutex when expiring client sessions<commit_after>package auth

import (
	"net/http"
	"sync"
	"time"

	"github.com/aybabtme/log"
	"github.com/pquerna/otp/totp"
	"github.com/satori/go.uuid"
)

type Config struct {
	Token string
	Log   *log.Log
}

type Authenticator struct {
	Config        *Config
	authedClients []*Client
	clientsMutex  sync.RWMutex
}

// Client is an authenticated web ui session
type Client struct {
	UUID  string
	Added time.Time
}

func New(config *Config) *Authenticator {
	authenticator := &Authenticator{
		Config: config,
	}

	go authenticator.ExpireClients()
	return authenticator
}

func (a *Authenticator) Authenticate(w http.ResponseWriter, r *http.Request) (bool, error) {
	cookie, err := r.Cookie("session")

	if err != nil {
		if err != http.ErrNoCookie {
			a.Config.Log.Err(err).Error("could not authenticate user")

			return false, err
		}

		err = nil
	}

	authed := false
	if cookie != nil {
		a.clientsMutex.RLock()
		for _, client := range a.authedClients {
			if cookie.Value == client.UUID {
				authed = true
				break
			}
		}
		a.clientsMutex.RUnlock()
	}

	if !authed && a.hasValidToken(r) {
		cookie = &http.Cookie{
			Name:  "session",
			Value: uuid.NewV4().String(),
			Path:  "/",
		}

		a.clientsMutex.Lock()
		a.authedClients = append(a.authedClients, &Client{
			UUID:  cookie.Value,
			Added: time.Now(),
		})
		a.clientsMutex.Unlock()

		authed = true
		http.SetCookie(w, cookie)
	}

	return authed, nil
}

func (a *Authenticator) hasValidToken(r *http.Request) bool {
	token := r.URL.Query().Get("token")
	if token == "" {
		return false
	}

	return totp.Validate(token, a.Config.Token)
}

func (a *Authenticator) ExpireClients() {
	for {
		<-time.After(2 * time.Minute)
		go func() {
			now := time.Now()

			a.clientsMutex.RLock()
			for i, client := range a.authedClients {
				if now.Sub(client.Added).Hours() >= 48 {
					a.clientsMutex.Lock()
					a.authedClients = append(a.authedClients[:i], a.authedClients[i+1:]...)
					a.clientsMutex.Unlock()
				}
			}
			a.clientsMutex.RUnlock()
		}()
	}
}

func (a *Authenticator) GetToken() (string, error) {
	return totp.GenerateCode(a.Config.Token, time.Now())
}
<|endoftext|>


<commit_before>package javascript

import (
	"encoding/json"
	"fmt"
	"net/url"
	"os"
	"path/filepath"

	"strings"

	"sourcegraph.com/sourcegraph/srcgraph/config"
	"sourcegraph.com/sourcegraph/srcgraph/container"
	"sourcegraph.com/sourcegraph/srcgraph/dep2"
	"sourcegraph.com/sourcegraph/srcgraph/scan"
	"sourcegraph.com/sourcegraph/srcgraph/unit"
)

func init() {
	scan.Register("npm", scan.DockerScanner{defaultNPM})
	dep2.RegisterLister(&CommonJSPackage{}, defaultNPM)
	dep2.RegisterResolver(npmDependencyTargetType, dep2.DockerResolver{defaultNPM})
}

const (
	nodeStdlibRepoURL = "git://github.com/joyent/node.git"
	NodeJSStdlibUnit  = "node"
)

type nodeVersion struct{}

type npmVersion struct{ nodeVersion }

var (
	defaultNode = nodeVersion{}
	defaultNPM  = &npmVersion{defaultNode}
)

func (_ *nodeVersion) baseDockerfile() ([]byte, error) {
	return []byte(baseNPMDockerfile), nil
}

const baseNPMDockerfile = `FROM ubuntu:14.04
RUN apt-get update -qq
RUN apt-get install -qqy nodejs node-gyp npm git

# Some NPM modules expect the node.js interpreter to be "node", not "nodejs" (as
# it is on Ubuntu).
RUN ln -s /usr/bin/nodejs /usr/bin/node
`

// containerDir returns the directory in the Docker container to use for the
// local directory dir.
func containerDir(dir string) string {
	return filepath.Join("/tmp/sg", filepath.Base(dir))
}

func (v *npmVersion) BuildScanner(dir string, c *config.Repository) (*container.Command, error) {
	dockerfile, err := v.baseDockerfile()
	if err != nil {
		return nil, err
	}

	const (
		findpkgsNPM = "commonjs-findpkgs@0.0.5"
		findpkgsGit = "git://github.com/sourcegraph/commonjs-findpkgs.git"
		findpkgsSrc = findpkgsNPM
	)
	dockerfile = append(dockerfile, []byte("\n\nRUN npm install --quiet -g "+findpkgsNPM+"\n")...)

	scanIgnores, err := json.Marshal(c.ScanIgnore)
	if err != nil {
		return nil, err
	}

	containerDir := containerDir(dir)
	cont := container.Container{
		Dockerfile: dockerfile,
		RunOptions: []string{"-v", dir + ":" + containerDir},
		Cmd:        []string{"commonjs-findpkgs", "--ignore", string(scanIgnores)},
		Dir:        containerDir,
	}
	cmd := container.Command{
		Container: cont,
		Transform: func(orig []byte) ([]byte, error) {
			var pkgs []*CommonJSPackage
			err := json.Unmarshal(orig, &pkgs)
			if err != nil {
				return nil, err
			}

			// filter out undesirable packages
			var pkgs2 []*CommonJSPackage
			for _, pkg := range pkgs {
				if !strings.Contains(pkg.Dir, "node_modules") {
					pkgs2 = append(pkgs2, pkg)
				}
			}

			// filter out undesirable source files (minified files) from
			// packages
			for _, pkg := range pkgs {
				for i, f := range pkg.LibFiles {
					if strings.HasSuffix(f, ".min.js") {
						pkg.LibFiles = append(pkg.LibFiles[:i], pkg.LibFiles[i+1:]...)
					}
				}
			}

			// set other fields
			for _, pkg := range pkgs2 {
				var pkgjson struct {
					Name        string
					Description string
				}
				if err := json.Unmarshal(pkg.Package, &pkgjson); err != nil {
					return nil, err
				}
				pkg.PackageName = pkgjson.Name
				pkg.PackageDescription = pkgjson.Description
			}

			return json.Marshal(pkgs2)
		},
	}
	return &cmd, nil
}

func (v *npmVersion) UnmarshalSourceUnits(data []byte) ([]unit.SourceUnit, error) {
	if len(data) == 0 {
		return nil, nil
	}

	var npmPackages []*CommonJSPackage
	err := json.Unmarshal(data, &npmPackages)
	if err != nil {
		return nil, err
	}

	units := make([]unit.SourceUnit, len(npmPackages))
	for i, p := range npmPackages {
		units[i] = p
	}

	return units, nil
}

// npmDependency is a name/version pair that represents an NPM dependency. This
// pair corresponds to the object property/value pairs in package.json
// "dependency" objects.
type npmDependency struct {
	// Name is the package name of the dependency.
	Name string

	// Spec is the specifier of the version, which can be an NPM version number,
	// a tarball URL, a git/hg clone URL, etc.
	Spec string
}

const npmDependencyTargetType = "npm-dep"

func (v *npmVersion) BuildResolver(dep *dep2.RawDependency, c *config.Repository) (*container.Command, error) {
	var npmDep npmDependency
	j, _ := json.Marshal(dep.Target)
	json.Unmarshal(j, &npmDep)

	dockerfile, err := v.baseDockerfile()
	if err != nil {
		return nil, err
	}
	dockerfile = append(dockerfile, []byte("\n\nRUN npm install --quiet -g deptool@~0.0.2\n")...)

	cmd := container.Command{
		Container: container.Container{
			Dockerfile: dockerfile,
			Cmd:        []string{"nodejs", "/usr/local/bin/npm-deptool", npmDep.Name + "@" + npmDep.Spec},
		},
		Transform: func(orig []byte) ([]byte, error) {
			// resolvedDep is output from npm-deptool.
			type npmDeptoolOutput struct {
				Name        string
				ResolvedURL string `json:"_resolved"`
				ID          string `json:"_id"`
				Repository  struct {
					Type string
					URL  string
				}
			}
			var resolvedDeps map[string]npmDeptoolOutput
			err := json.Unmarshal(orig, &resolvedDeps)
			if err != nil {
				return nil, err
			}

			if len(resolvedDeps) == 0 {
				return nil, fmt.Errorf("npm-deptool did not output anything for raw dependency %+v", dep)
			}
			if len(resolvedDeps) != 1 {
				return nil, fmt.Errorf("npm-deptool unexpectedly returned %d deps for raw dependency %+v: deps are %+v", len(resolvedDeps), dep, resolvedDeps)
			}

			var resolvedDep npmDeptoolOutput
			for _, v := range resolvedDeps {
				resolvedDep = v
			}

			var toRepoCloneURL, toRevSpec string
			if strings.HasPrefix(resolvedDep.ResolvedURL, "https://registry.npmjs.org/") {
				// known npm package, so the repository refers to it
				toRepoCloneURL = resolvedDep.Repository.URL
			} else {
				// external tarball, git repo url, etc., so the repository might
				// refer to the source repo (if this is a fork) or not be
				// present at all
				u, err := url.Parse(resolvedDep.ResolvedURL)
				if err != nil {
					return nil, err
				}
				toRevSpec = u.Fragment

				u.Fragment = ""
				toRepoCloneURL = u.String()
			}

			return json.Marshal(&dep2.ResolvedTarget{
				ToRepoCloneURL:  toRepoCloneURL,
				ToUnitType:      unit.Type((&CommonJSPackage{})),
				ToUnit:          resolvedDep.Name,
				ToVersionString: resolvedDep.ID,
				ToRevSpec:       toRevSpec,
			})
		},
	}
	return &cmd, nil
}

// List reads the "dependencies" key in the NPM package's package.json file and
// outputs the properties as raw dependencies.
func (v *npmVersion) List(dir string, unit unit.SourceUnit, c *config.Repository) ([]*dep2.RawDependency, error) {
	pkg := unit.(*CommonJSPackage)

	if pkg.PackageJSONFile == "" {
		// No package.json file, so we won't be able to find any dependencies anyway.
		return nil, nil
	}

	pkgFile := filepath.Join(dir, pkg.PackageJSONFile)

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

	var pkgjson struct {
		Dependencies    map[string]string `json:"dependencies"`
		DevDependencies map[string]string `json:"devDependencies"`
	}
	err = json.NewDecoder(f).Decode(&pkgjson)
	if err != nil {
		return nil, err
	}

	rawDeps := make([]*dep2.RawDependency, len(pkgjson.Dependencies)+len(pkgjson.DevDependencies))
	i := 0
	addDeps := func(deps map[string]string) {
		for name, spec := range deps {
			rawDeps[i] = &dep2.RawDependency{
				FromFile:   pkg.PackageJSONFile,
				TargetType: npmDependencyTargetType,
				Target:     npmDependency{Name: name, Spec: spec},
			}
			i++
		}
	}
	addDeps(pkgjson.Dependencies)
	addDeps(pkgjson.DevDependencies)

	return rawDeps, nil
}

const fixPhantomJSHack = "\n\n# fix phantomjs bad url issue (https://github.com/Medium/phantomjs/issues/170)\n" + `RUN sed -ri 's/"phantomjs"\s*:\s*"[^"]+"/"phantomjs":"1.9.7-8"/g' package.json` + "\n"
<commit_msg>handle when npm-deptool returns >1 dependency (find it by name) (fixes #860)<commit_after>package javascript

import (
	"encoding/json"
	"fmt"
	"net/url"
	"os"
	"path/filepath"

	"strings"

	"sourcegraph.com/sourcegraph/srcgraph/config"
	"sourcegraph.com/sourcegraph/srcgraph/container"
	"sourcegraph.com/sourcegraph/srcgraph/dep2"
	"sourcegraph.com/sourcegraph/srcgraph/scan"
	"sourcegraph.com/sourcegraph/srcgraph/unit"
)

func init() {
	scan.Register("npm", scan.DockerScanner{defaultNPM})
	dep2.RegisterLister(&CommonJSPackage{}, defaultNPM)
	dep2.RegisterResolver(npmDependencyTargetType, dep2.DockerResolver{defaultNPM})
}

const (
	nodeStdlibRepoURL = "git://github.com/joyent/node.git"
	NodeJSStdlibUnit  = "node"
)

type nodeVersion struct{}

type npmVersion struct{ nodeVersion }

var (
	defaultNode = nodeVersion{}
	defaultNPM  = &npmVersion{defaultNode}
)

func (_ *nodeVersion) baseDockerfile() ([]byte, error) {
	return []byte(baseNPMDockerfile), nil
}

const baseNPMDockerfile = `FROM ubuntu:14.04
RUN apt-get update -qq
RUN apt-get install -qqy nodejs node-gyp npm git

# Some NPM modules expect the node.js interpreter to be "node", not "nodejs" (as
# it is on Ubuntu).
RUN ln -s /usr/bin/nodejs /usr/bin/node
`

// containerDir returns the directory in the Docker container to use for the
// local directory dir.
func containerDir(dir string) string {
	return filepath.Join("/tmp/sg", filepath.Base(dir))
}

func (v *npmVersion) BuildScanner(dir string, c *config.Repository) (*container.Command, error) {
	dockerfile, err := v.baseDockerfile()
	if err != nil {
		return nil, err
	}

	const (
		findpkgsNPM = "commonjs-findpkgs@0.0.5"
		findpkgsGit = "git://github.com/sourcegraph/commonjs-findpkgs.git"
		findpkgsSrc = findpkgsNPM
	)
	dockerfile = append(dockerfile, []byte("\n\nRUN npm install --quiet -g "+findpkgsNPM+"\n")...)

	scanIgnores, err := json.Marshal(c.ScanIgnore)
	if err != nil {
		return nil, err
	}

	containerDir := containerDir(dir)
	cont := container.Container{
		Dockerfile: dockerfile,
		RunOptions: []string{"-v", dir + ":" + containerDir},
		Cmd:        []string{"commonjs-findpkgs", "--ignore", string(scanIgnores)},
		Dir:        containerDir,
	}
	cmd := container.Command{
		Container: cont,
		Transform: func(orig []byte) ([]byte, error) {
			var pkgs []*CommonJSPackage
			err := json.Unmarshal(orig, &pkgs)
			if err != nil {
				return nil, err
			}

			// filter out undesirable packages
			var pkgs2 []*CommonJSPackage
			for _, pkg := range pkgs {
				if !strings.Contains(pkg.Dir, "node_modules") {
					pkgs2 = append(pkgs2, pkg)
				}
			}

			// filter out undesirable source files (minified files) from
			// packages
			for _, pkg := range pkgs {
				for i, f := range pkg.LibFiles {
					if strings.HasSuffix(f, ".min.js") {
						pkg.LibFiles = append(pkg.LibFiles[:i], pkg.LibFiles[i+1:]...)
					}
				}
			}

			// set other fields
			for _, pkg := range pkgs2 {
				var pkgjson struct {
					Name        string
					Description string
				}
				if err := json.Unmarshal(pkg.Package, &pkgjson); err != nil {
					return nil, err
				}
				pkg.PackageName = pkgjson.Name
				pkg.PackageDescription = pkgjson.Description
			}

			return json.Marshal(pkgs2)
		},
	}
	return &cmd, nil
}

func (v *npmVersion) UnmarshalSourceUnits(data []byte) ([]unit.SourceUnit, error) {
	if len(data) == 0 {
		return nil, nil
	}

	var npmPackages []*CommonJSPackage
	err := json.Unmarshal(data, &npmPackages)
	if err != nil {
		return nil, err
	}

	units := make([]unit.SourceUnit, len(npmPackages))
	for i, p := range npmPackages {
		units[i] = p
	}

	return units, nil
}

// npmDependency is a name/version pair that represents an NPM dependency. This
// pair corresponds to the object property/value pairs in package.json
// "dependency" objects.
type npmDependency struct {
	// Name is the package name of the dependency.
	Name string

	// Spec is the specifier of the version, which can be an NPM version number,
	// a tarball URL, a git/hg clone URL, etc.
	Spec string
}

const npmDependencyTargetType = "npm-dep"

func (v *npmVersion) BuildResolver(dep *dep2.RawDependency, c *config.Repository) (*container.Command, error) {
	var npmDep npmDependency
	j, _ := json.Marshal(dep.Target)
	json.Unmarshal(j, &npmDep)

	dockerfile, err := v.baseDockerfile()
	if err != nil {
		return nil, err
	}
	dockerfile = append(dockerfile, []byte("\n\nRUN npm install --quiet -g deptool@~0.0.2\n")...)

	cmd := container.Command{
		Container: container.Container{
			Dockerfile: dockerfile,
			Cmd:        []string{"nodejs", "/usr/local/bin/npm-deptool", npmDep.Name + "@" + npmDep.Spec},
		},
		Transform: func(orig []byte) ([]byte, error) {
			// resolvedDep is output from npm-deptool.
			type npmDeptoolOutput struct {
				Name        string
				ResolvedURL string `json:"_resolved"`
				ID          string `json:"_id"`
				Repository  struct {
					Type string
					URL  string
				}
			}
			var resolvedDeps map[string]npmDeptoolOutput
			err := json.Unmarshal(orig, &resolvedDeps)
			if err != nil {
				return nil, err
			}

			if len(resolvedDeps) == 0 {
				return nil, fmt.Errorf("npm-deptool did not output anything for raw dependency %+v", dep)
			}

			var resolvedDep *npmDeptoolOutput
			for name, v := range resolvedDeps {
				if name == npmDep.Name {
					resolvedDep = &v
					break
				}
			}

			if resolvedDep == nil {
				return nil, fmt.Errorf("npm-deptool did not return info about npm package %q for raw dependency %+v: all %d resolved deps are %+v", npmDep.Name, dep, len(resolvedDeps), resolvedDeps)
			}

			var toRepoCloneURL, toRevSpec string
			if strings.HasPrefix(resolvedDep.ResolvedURL, "https://registry.npmjs.org/") {
				// known npm package, so the repository refers to it
				toRepoCloneURL = resolvedDep.Repository.URL
			} else {
				// external tarball, git repo url, etc., so the repository might
				// refer to the source repo (if this is a fork) or not be
				// present at all
				u, err := url.Parse(resolvedDep.ResolvedURL)
				if err != nil {
					return nil, err
				}
				toRevSpec = u.Fragment

				u.Fragment = ""
				toRepoCloneURL = u.String()
			}

			return json.Marshal(&dep2.ResolvedTarget{
				ToRepoCloneURL:  toRepoCloneURL,
				ToUnitType:      unit.Type((&CommonJSPackage{})),
				ToUnit:          resolvedDep.Name,
				ToVersionString: resolvedDep.ID,
				ToRevSpec:       toRevSpec,
			})
		},
	}
	return &cmd, nil
}

// List reads the "dependencies" key in the NPM package's package.json file and
// outputs the properties as raw dependencies.
func (v *npmVersion) List(dir string, unit unit.SourceUnit, c *config.Repository) ([]*dep2.RawDependency, error) {
	pkg := unit.(*CommonJSPackage)

	if pkg.PackageJSONFile == "" {
		// No package.json file, so we won't be able to find any dependencies anyway.
		return nil, nil
	}

	pkgFile := filepath.Join(dir, pkg.PackageJSONFile)

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

	var pkgjson struct {
		Dependencies    map[string]string `json:"dependencies"`
		DevDependencies map[string]string `json:"devDependencies"`
	}
	err = json.NewDecoder(f).Decode(&pkgjson)
	if err != nil {
		return nil, err
	}

	rawDeps := make([]*dep2.RawDependency, len(pkgjson.Dependencies)+len(pkgjson.DevDependencies))
	i := 0
	addDeps := func(deps map[string]string) {
		for name, spec := range deps {
			rawDeps[i] = &dep2.RawDependency{
				FromFile:   pkg.PackageJSONFile,
				TargetType: npmDependencyTargetType,
				Target:     npmDependency{Name: name, Spec: spec},
			}
			i++
		}
	}
	addDeps(pkgjson.Dependencies)
	addDeps(pkgjson.DevDependencies)

	return rawDeps, nil
}

const fixPhantomJSHack = "\n\n# fix phantomjs bad url issue (https://github.com/Medium/phantomjs/issues/170)\n" + `RUN sed -ri 's/"phantomjs"\s*:\s*"[^"]+"/"phantomjs":"1.9.7-8"/g' package.json` + "\n"
<|endoftext|>


<commit_before>package gluatest

import (
	"fmt"
	"sort"
	"strings"
	"testing"

	"github.com/bmatsuo/lark/gluamodule"
	"github.com/yuin/gopher-lua"
)

// Module is a lua module to be tested.
type Module struct {
	Module     gluamodule.Module
	TestScript string
}

// Preload runs the loader to register the module name.
func (m *Module) Preload(t testing.TB) *lua.LState {
	L := lua.NewState()
	gluamodule.Preload(L, gluamodule.Resolve(m.Module)...)
	err := L.DoFile(m.TestScript)
	if err != nil {
		t.Error(err)
	}
	return L
}

// Test runs the specified test function
func (m *Module) Test(t testing.TB) {
	testFuncs := m.getTestFuncs(t)
	for _, fname := range testFuncs {
		m.runTest(t, fname, getGlobalFunction(fname))
	}
}

func (m *Module) getTestFuncs(t testing.TB) []string {
	l := m.Preload(t)
	defer l.Close()

	return getTestFuncs(l)
}

type lfuncGetter func(*lua.LState) (*lua.LFunction, error)

func (m *Module) runTest(t testing.TB, name string, getfunc lfuncGetter) {
	var fatal bool
	defer func() {
		if fatal {
			t.Fatal("FATAL")
		}
	}()

	l := m.Preload(t)
	defer l.Close()

	failmsg := func(name string, err error) string {
		return fmt.Sprintf("FAIL   %s\n%s", name, err)
	}

	errFn := l.NewFunction(errTraceback)

	lfunc, err := getfunc(l)
	if err != nil {
		t.Errorf("FAIL\n%s", err)
		return
	}
	setup := l.GetGlobal("__test_setup")
	teardown := l.GetGlobal("__test_teardown")

	if setup != lua.LNil {
		l.Push(setup)
		err := l.PCall(0, 0, errFn)
		if err != nil {
			fatal = true
			t.Error(failmsg("SETUP", err))
		}
	}

	if !fatal {
		t.Logf("ENTER  %s", name)
		l.Push(lfunc)
		err = l.PCall(0, 0, errFn)
		if err != nil {
			t.Error(failmsg(name, err))
		} else {
			t.Logf("PASS   %s", name)
		}
	}

	if teardown != lua.LNil {
		l.Push(teardown)
		err := l.PCall(0, 0, errFn)
		if err != nil {
			fatal = true
			t.Error(failmsg("TEARDOWN", err))
			return
		}
	}
}

func getTestFuncs(L *lua.LState) []string {
	funcs := getGlobals(L, selTestFuncs)
	sort.Strings(funcs)
	return funcs
}

func selTestFuncs(L *lua.LState, k, v lua.LValue) bool {
	s := string(k.(lua.LString))
	if !strings.HasPrefix(s, "test_") {
		return false
	}
	return true
}

func getGlobalFunction(fname string) lfuncGetter {
	return func(l *lua.LState) (*lua.LFunction, error) {
		lfunc, ok := l.GetGlobal(fname).(*lua.LFunction)
		if !ok {
			return nil, fmt.Errorf("not a function: %s", lfunc)
		}
		return lfunc, nil
	}
}

func getGlobals(L *lua.LState, sel func(L *lua.LState, k, v lua.LValue) bool) []string {
	var sels []string
	globals := L.Get(lua.GlobalsIndex).(*lua.LTable)
	L.ForEach(globals, func(k, v lua.LValue) {
		s, ok := k.(lua.LString)
		if !ok {
			return
		}
		if sel(L, k, v) {
			sels = append(sels, string(s))
		}
	})
	return sels
}

func errTraceback(L *lua.LState) int {
	msg := L.Get(1)
	L.SetTop(0)
	L.Push(L.GetField(L.GetGlobal("debug"), "traceback"))
	L.Push(msg)
	L.Push(lua.LNumber(3))
	L.Call(2, 1)
	return 1
}
<commit_msg>gluatest: cleanup and document setup and teardown<commit_after>package gluatest

import (
	"fmt"
	"sort"
	"strings"
	"testing"

	"github.com/bmatsuo/lark/gluamodule"
	"github.com/yuin/gopher-lua"
)

// FuncSetup is the name of a global variable containing a "setup" function.
// The setup function will be executed before each test function.  If any setup
// function fails the test function that would follow it will not execute.
var FuncSetup = "__test_setup"

// FuncTeardown is the name of a global variable containing a "teardown"
// function.  A teardown function will execute after each test function or
// after a setup function has failed.
var FuncTeardown = "__test_teardown"

// Module is a lua module to be tested.
type Module struct {
	Module     gluamodule.Module
	TestScript string
}

// Preload runs the loader to register the module name.
func (m *Module) Preload(t testing.TB) *lua.LState {
	L := lua.NewState()
	gluamodule.Preload(L, gluamodule.Resolve(m.Module)...)
	err := L.DoFile(m.TestScript)
	if err != nil {
		t.Error(err)
	}
	return L
}

// Test runs the specified test function
func (m *Module) Test(t testing.TB) {
	testFuncs := m.getTestFuncs(t)
	for _, fname := range testFuncs {
		m.runTest(t, fname, getGlobalFunction(fname))
	}
}

func (m *Module) getTestFuncs(t testing.TB) []string {
	l := m.Preload(t)
	defer l.Close()

	return getTestFuncs(l)
}

type lfuncGetter func(*lua.LState) (*lua.LFunction, error)

func (m *Module) runTest(t testing.TB, name string, getfunc lfuncGetter) {
	var fatal bool
	defer func() {
		if fatal {
			t.Fatal("FATAL")
		}
	}()

	l := m.Preload(t)
	defer l.Close()

	failmsg := func(name string, err error) string {
		return fmt.Sprintf("FAIL   %s\n%s", name, err)
	}

	errFn := l.NewFunction(errTraceback)

	lfunc, err := getfunc(l)
	if err != nil {
		t.Errorf("FAIL\n%s", err)
		return
	}
	setup := l.GetGlobal(FuncSetup)
	teardown := l.GetGlobal(FuncTeardown)

	if setup != lua.LNil {
		l.Push(setup)
		err := l.PCall(0, 0, errFn)
		if err != nil {
			fatal = true
			t.Error(failmsg("SETUP", err))
		}
	}

	if !fatal {
		t.Logf("ENTER  %s", name)
		l.Push(lfunc)
		err = l.PCall(0, 0, errFn)
		if err != nil {
			t.Error(failmsg(name, err))
		} else {
			t.Logf("PASS   %s", name)
		}
	}

	if teardown != lua.LNil {
		l.Push(teardown)
		err := l.PCall(0, 0, errFn)
		if err != nil {
			fatal = true
			t.Error(failmsg("TEARDOWN", err))
		}
	}
}

func getTestFuncs(L *lua.LState) []string {
	funcs := getGlobals(L, selTestFuncs)
	sort.Strings(funcs)
	return funcs
}

func selTestFuncs(L *lua.LState, k, v lua.LValue) bool {
	s := string(k.(lua.LString))
	if !strings.HasPrefix(s, "test_") {
		return false
	}
	return true
}

func getGlobalFunction(fname string) lfuncGetter {
	return func(l *lua.LState) (*lua.LFunction, error) {
		lfunc, ok := l.GetGlobal(fname).(*lua.LFunction)
		if !ok {
			return nil, fmt.Errorf("not a function: %s", lfunc)
		}
		return lfunc, nil
	}
}

func getGlobals(L *lua.LState, sel func(L *lua.LState, k, v lua.LValue) bool) []string {
	var sels []string
	globals := L.Get(lua.GlobalsIndex).(*lua.LTable)
	L.ForEach(globals, func(k, v lua.LValue) {
		s, ok := k.(lua.LString)
		if !ok {
			return
		}
		if sel(L, k, v) {
			sels = append(sels, string(s))
		}
	})
	return sels
}

func errTraceback(L *lua.LState) int {
	msg := L.Get(1)
	L.SetTop(0)
	L.Push(L.GetField(L.GetGlobal("debug"), "traceback"))
	L.Push(msg)
	L.Push(lua.LNumber(3))
	L.Call(2, 1)
	return 1
}
<|endoftext|>


<commit_before>package libkb

import (
	"fmt"
	"sync"

	"github.com/keybase/client/go/protocol/keybase1"
)

// AppState tracks the state of foreground/background status of the app in which the service
// is running in.
type AppState struct {
	Contextified
	sync.Mutex

	state     keybase1.AppState
	updateChs []chan keybase1.AppState
}

// NewAppState returns a new AppState
func NewAppState(g *GlobalContext) *AppState {
	return &AppState{
		Contextified: NewContextified(g),
		state:        keybase1.AppState_FOREGROUND,
	}
}

// NextUpdate returns a channel that triggers when the app state changes
func (a *AppState) NextUpdate(lastState *keybase1.AppState) chan keybase1.AppState {
	a.Lock()
	defer a.Unlock()
	ch := make(chan keybase1.AppState, 1)
	if lastState != nil && *lastState != a.state {
		ch <- a.state
	} else {
		a.updateChs = append(a.updateChs, ch)
	}
	return ch
}

// Update updates the current app state, and notifies any waiting calls from NextUpdate
func (a *AppState) Update(state keybase1.AppState) {
	a.Lock()
	defer a.Unlock()
	defer a.G().Trace(fmt.Sprintf("AppState.Update(%v)", state), func() error { return nil })()
	if a.state != state {
		a.G().Log.Debug("AppState.Update: useful update: %v, we are currently in state: %v",
			state, a.state)
		a.state = state
		for _, ch := range a.updateChs {
			ch <- state
		}
		// cancel RPCs if we go into the background
		switch a.state {
		case keybase1.AppState_BACKGROUND:
			a.G().RPCCanceller.CancelLiveContexts()
		}
		a.updateChs = nil
	} else {
		a.G().Log.Debug("AppState.Update: ignoring update: %v, we are currently in state: %v",
			state, a.state)
	}
}

// State returns the current app state
func (a *AppState) State() keybase1.AppState {
	a.Lock()
	defer a.Unlock()
	return a.state
}
<commit_msg>turn off the context cancel on bkg<commit_after>package libkb

import (
	"fmt"
	"sync"

	"github.com/keybase/client/go/protocol/keybase1"
)

// AppState tracks the state of foreground/background status of the app in which the service
// is running in.
type AppState struct {
	Contextified
	sync.Mutex

	state     keybase1.AppState
	updateChs []chan keybase1.AppState
}

// NewAppState returns a new AppState
func NewAppState(g *GlobalContext) *AppState {
	return &AppState{
		Contextified: NewContextified(g),
		state:        keybase1.AppState_FOREGROUND,
	}
}

// NextUpdate returns a channel that triggers when the app state changes
func (a *AppState) NextUpdate(lastState *keybase1.AppState) chan keybase1.AppState {
	a.Lock()
	defer a.Unlock()
	ch := make(chan keybase1.AppState, 1)
	if lastState != nil && *lastState != a.state {
		ch <- a.state
	} else {
		a.updateChs = append(a.updateChs, ch)
	}
	return ch
}

// Update updates the current app state, and notifies any waiting calls from NextUpdate
func (a *AppState) Update(state keybase1.AppState) {
	a.Lock()
	defer a.Unlock()
	defer a.G().Trace(fmt.Sprintf("AppState.Update(%v)", state), func() error { return nil })()
	if a.state != state {
		a.G().Log.Debug("AppState.Update: useful update: %v, we are currently in state: %v",
			state, a.state)
		a.state = state
		for _, ch := range a.updateChs {
			ch <- state
		}
		a.updateChs = nil
	} else {
		a.G().Log.Debug("AppState.Update: ignoring update: %v, we are currently in state: %v",
			state, a.state)
	}
}

// State returns the current app state
func (a *AppState) State() keybase1.AppState {
	a.Lock()
	defer a.Unlock()
	return a.state
}
<|endoftext|>


<commit_before>// Copyright 2015 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.

package service

import (
	"os"
	"path/filepath"
	"runtime"
	"strings"

	"golang.org/x/net/context"

	"github.com/keybase/client/go/engine"
	"github.com/keybase/client/go/libkb"
	keybase1 "github.com/keybase/client/go/protocol"
	rpc "github.com/keybase/go-framed-msgpack-rpc"
)

type ConfigHandler struct {
	libkb.Contextified
	xp     rpc.Transporter
	svc    *Service
	connID libkb.ConnectionID
}

func NewConfigHandler(xp rpc.Transporter, i libkb.ConnectionID, g *libkb.GlobalContext, svc *Service) *ConfigHandler {
	return &ConfigHandler{
		Contextified: libkb.NewContextified(g),
		xp:           xp,
		svc:          svc,
		connID:       i,
	}
}

func (h ConfigHandler) GetCurrentStatus(_ context.Context, sessionID int) (res keybase1.GetCurrentStatusRes, err error) {
	var cs libkb.CurrentStatus
	if cs, err = libkb.GetCurrentStatus(h.G()); err == nil {
		res = cs.Export()
	}
	return
}

func getPlatformInfo() keybase1.PlatformInfo {
	return keybase1.PlatformInfo{
		Os:        runtime.GOOS,
		Arch:      runtime.GOARCH,
		GoVersion: runtime.Version(),
	}
}

func (h ConfigHandler) GetExtendedStatus(_ context.Context, sessionID int) (res keybase1.ExtendedStatus, err error) {
	defer h.G().Trace("ConfigHandler::GetExtendedStatus", func() error { return err })()

	res.Standalone = h.G().Env.GetStandalone()
	res.LogDir = h.G().Env.GetLogDir()
	res.Clients = h.G().ConnectionManager.ListAllLabeledConnections()

	me, err := libkb.LoadMe(libkb.NewLoadUserArg(h.G()))
	if err != nil {
		h.G().Log.Debug("| died in LoadMe")
		return res, err
	}

	device, err := me.GetComputedKeyFamily().GetCurrentDevice(h.G())
	if err != nil {
		h.G().Log.Debug("| GetCurrentDevice failed: %s", err)
	} else {
		res.Device = device.ProtExport()
	}

	h.G().LoginState().Account(func(a *libkb.Account) {
		res.PassphraseStreamCached = a.PassphraseStreamCache().Valid()
		if a.LoginSession() != nil {
			res.Session = a.LoginSession().Status()
		}
	}, "ConfigHandler::GetExtendedStatus")

	// this isn't quite ideal, but if there's a delegated UpdateUI available, then electron is running and connected.
	if h.G().UIRouter != nil {
		updateUI, err := h.G().UIRouter.GetUpdateUI()
		if err == nil && updateUI != nil {
			res.DesktopUIConnected = true
		}
	}

	current, all, err := h.G().GetAllUserNames()
	if err != nil {
		h.G().Log.Debug("| died in GetAllUseranmes()")
		return res, err
	}
	res.DefaultUsername = current.String()
	p := make([]string, len(all))
	for i, u := range all {
		p[i] = u.String()
	}
	res.ProvisionedUsernames = p
	res.PlatformInfo = getPlatformInfo()

	return res, nil
}

func (h ConfigHandler) GetConfig(_ context.Context, sessionID int) (keybase1.Config, error) {
	var c keybase1.Config

	c.ServerURI = h.G().Env.GetServerURI()
	c.RunMode = string(h.G().Env.GetRunMode())
	var err error
	c.SocketFile, err = h.G().Env.GetSocketFile()
	if err != nil {
		return c, err
	}

	gpg := h.G().GetGpgClient()
	canExec, err := gpg.CanExec()
	if err == nil {
		c.GpgExists = canExec
		c.GpgPath = gpg.Path()
	}

	c.Version = libkb.VersionString()
	c.VersionShort = libkb.Version

	var v []string
	libkb.VersionMessage(func(s string) {
		v = append(v, s)
	})
	c.VersionFull = strings.Join(v, "\n")

	dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err == nil {
		c.Path = dir
	}

	c.ConfigPath = h.G().Env.GetConfigFilename()
	c.Label = h.G().Env.GetLabel()
	if h.svc != nil {
		if h.svc.ForkType == keybase1.ForkType_AUTO {
			c.IsAutoForked = true
		}
		c.ForkType = h.svc.ForkType
	}

	return c, nil
}

func (h ConfigHandler) SetUserConfig(_ context.Context, arg keybase1.SetUserConfigArg) (err error) {
	eng := engine.NewUserConfigEngine(&engine.UserConfigEngineArg{
		Key:   arg.Key,
		Value: arg.Value,
	}, h.G())

	ctx := &engine.Context{}
	err = engine.RunEngine(eng, ctx)
	if err != nil {
		return err
	}
	return nil
}

func (h ConfigHandler) HelloIAm(_ context.Context, arg keybase1.ClientDetails) error {
	return h.G().ConnectionManager.Label(h.connID, arg)
}
<commit_msg>Fix for when no me user available<commit_after>// Copyright 2015 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.

package service

import (
	"os"
	"path/filepath"
	"runtime"
	"strings"

	"golang.org/x/net/context"

	"github.com/keybase/client/go/engine"
	"github.com/keybase/client/go/libkb"
	keybase1 "github.com/keybase/client/go/protocol"
	rpc "github.com/keybase/go-framed-msgpack-rpc"
)

type ConfigHandler struct {
	libkb.Contextified
	xp     rpc.Transporter
	svc    *Service
	connID libkb.ConnectionID
}

func NewConfigHandler(xp rpc.Transporter, i libkb.ConnectionID, g *libkb.GlobalContext, svc *Service) *ConfigHandler {
	return &ConfigHandler{
		Contextified: libkb.NewContextified(g),
		xp:           xp,
		svc:          svc,
		connID:       i,
	}
}

func (h ConfigHandler) GetCurrentStatus(_ context.Context, sessionID int) (res keybase1.GetCurrentStatusRes, err error) {
	var cs libkb.CurrentStatus
	if cs, err = libkb.GetCurrentStatus(h.G()); err == nil {
		res = cs.Export()
	}
	return
}

func getPlatformInfo() keybase1.PlatformInfo {
	return keybase1.PlatformInfo{
		Os:        runtime.GOOS,
		Arch:      runtime.GOARCH,
		GoVersion: runtime.Version(),
	}
}

func (h ConfigHandler) GetExtendedStatus(_ context.Context, sessionID int) (res keybase1.ExtendedStatus, err error) {
	defer h.G().Trace("ConfigHandler::GetExtendedStatus", func() error { return err })()

	res.Standalone = h.G().Env.GetStandalone()
	res.LogDir = h.G().Env.GetLogDir()
	res.Clients = h.G().ConnectionManager.ListAllLabeledConnections()

	me, err := libkb.LoadMe(libkb.NewLoadUserArg(h.G()))
	if err != nil {
		h.G().Log.Debug("| could not load me user")
	} else {
		device, err := me.GetComputedKeyFamily().GetCurrentDevice(h.G())
		if err != nil {
			h.G().Log.Debug("| GetCurrentDevice failed: %s", err)
		} else {
			res.Device = device.ProtExport()
		}
	}

	h.G().LoginState().Account(func(a *libkb.Account) {
		res.PassphraseStreamCached = a.PassphraseStreamCache().Valid()
		if a.LoginSession() != nil {
			res.Session = a.LoginSession().Status()
		}
	}, "ConfigHandler::GetExtendedStatus")

	// this isn't quite ideal, but if there's a delegated UpdateUI available, then electron is running and connected.
	if h.G().UIRouter != nil {
		updateUI, err := h.G().UIRouter.GetUpdateUI()
		if err == nil && updateUI != nil {
			res.DesktopUIConnected = true
		}
	}

	current, all, err := h.G().GetAllUserNames()
	if err != nil {
		h.G().Log.Debug("| died in GetAllUseranmes()")
		return res, err
	}
	res.DefaultUsername = current.String()
	p := make([]string, len(all))
	for i, u := range all {
		p[i] = u.String()
	}
	res.ProvisionedUsernames = p
	res.PlatformInfo = getPlatformInfo()

	return res, nil
}

func (h ConfigHandler) GetConfig(_ context.Context, sessionID int) (keybase1.Config, error) {
	var c keybase1.Config

	c.ServerURI = h.G().Env.GetServerURI()
	c.RunMode = string(h.G().Env.GetRunMode())
	var err error
	c.SocketFile, err = h.G().Env.GetSocketFile()
	if err != nil {
		return c, err
	}

	gpg := h.G().GetGpgClient()
	canExec, err := gpg.CanExec()
	if err == nil {
		c.GpgExists = canExec
		c.GpgPath = gpg.Path()
	}

	c.Version = libkb.VersionString()
	c.VersionShort = libkb.Version

	var v []string
	libkb.VersionMessage(func(s string) {
		v = append(v, s)
	})
	c.VersionFull = strings.Join(v, "\n")

	dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err == nil {
		c.Path = dir
	}

	c.ConfigPath = h.G().Env.GetConfigFilename()
	c.Label = h.G().Env.GetLabel()
	if h.svc != nil {
		if h.svc.ForkType == keybase1.ForkType_AUTO {
			c.IsAutoForked = true
		}
		c.ForkType = h.svc.ForkType
	}

	return c, nil
}

func (h ConfigHandler) SetUserConfig(_ context.Context, arg keybase1.SetUserConfigArg) (err error) {
	eng := engine.NewUserConfigEngine(&engine.UserConfigEngineArg{
		Key:   arg.Key,
		Value: arg.Value,
	}, h.G())

	ctx := &engine.Context{}
	err = engine.RunEngine(eng, ctx)
	if err != nil {
		return err
	}
	return nil
}

func (h ConfigHandler) HelloIAm(_ context.Context, arg keybase1.ClientDetails) error {
	return h.G().ConnectionManager.Label(h.connID, arg)
}
<|endoftext|>