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

package tabwriter

import (
	"os";
	"io";
	"array";
	"utf8";
)

// ----------------------------------------------------------------------------
// Basic byteArray support

type byteArray struct {
	a []byte;
}

func (b *byteArray) Init(initial_size int) {
	b.a = make([]byte, initial_size)[0 : 0];
}

func (b *byteArray) Len() int {
	return len(b.a);
}

func (b *byteArray) clear() {
	b.a = b.a[0 : 0];
}

func (b *byteArray) slice(i, j int) []byte {
	return b.a[i : j];  // BUG should really be &b.a[i : j]
}

func (b *byteArray) append(s []byte) {
	a := b.a;
	n := len(a);
	m := n + len(s);

	if m > cap(a) {
		n2 := 2*n;
		if m > n2 {
			n2 = m;
		}
		b := make([]byte, n2);
		for i := 0; i < n; i++ {
			b[i] = a[i];
		}
		a = b;
	}

	a = a[0 : m];
	for i := len(s) - 1; i >= 0; i-- {
		a[n + i] = s[i];
	}
	b.a = a;
}

// ----------------------------------------------------------------------------
// Writer is a filter implementing the io.Write interface. It assumes
// that the incoming bytes represent UTF-8 encoded text consisting of
// lines of tab-terminated "cells". Cells in adjacent lines constitute
// a column. Writer rewrites the incoming text such that all cells in
// a column have the same width; thus it effectively aligns cells. It
// does this by adding padding where necessary. All characters (ASCII
// or not) are assumed to be of the same width - this may not be true
// for arbitrary UTF-8 characters visualized on the screen.
//
// Note that any text at the end of a line that is not tab-terminated
// is not a cell and does not enforce alignment of cells in adjacent
// rows. To make it a cell it needs to be tab-terminated. (For more
// information see http://nickgravgaard.com/elastictabstops/index.html)
//
// Formatting can be controlled via parameters:
//
// cellwidth	minimal cell width
// padding      additional cell padding
// padchar      ASCII char used for padding
//              if padchar == '\t', the Writer will assume that the
//              width of a '\t' in the formatted output is cellwidth,
//              and cells are left-aligned independent of align_left
//              (for correct-looking results, cellwidth must correspond
//              to the tabwidth in the viewer displaying the result)
// filter_html  ignores html tags and handles entities (starting with '&'
//              and ending in ';') as single characters (width = 1)

type Writer struct {
	// TODO should not export any of the fields
	// configuration
	writer io.Write;
	cellwidth int;
	padding int;
	padbytes [8]byte;
	align_left bool;
	filter_html bool;

	// current state
	html_char byte;  // terminating char of html tag/entity, or 0 ('>', ';', or 0)
	buf byteArray;  // collected text w/o tabs and newlines
	size int;  // size of incomplete cell in bytes
	width int;  // width of incomplete cell in runes up to buf[pos] w/o ignored sections
	pos int;  // buffer position up to which width of incomplete cell has been computed
	lines_size array.Array;  // list of lines; each line is a list of cell sizes in bytes
	lines_width array.Array;  // list of lines; each line is a list of cell widths in runes
	widths array.IntArray;  // list of column widths in runes - re-used during formatting
}

// Internal representation (current state):
//
// - all text written is appended to buf; tabs and newlines are stripped away
// - at any given time there is a (possibly empty) incomplete cell at the end
//   (the cell starts after a tab or newline)
// - size is the number of bytes belonging to the cell so far
// - width is text width in runes of that cell from the start of the cell to
//   position pos; html tags and entities are excluded from this width if html
//   filtering is enabled
// - the sizes and widths of processed text are kept in the lines_size and
//   lines_width arrays, which contain an array of sizes or widths for each line
// - the widths array is a temporary array with current widths used during
//   formatting; it is kept in Writer because it's re-used
//
//                    |<---------- size ---------->|
//                    |                            |
//                    |<- width ->|<- ignored ->|  |
//                    |           |             |  |
// [---processed---tab------------<tag>...</tag>...]
// ^                  ^                         ^
// |                  |                         |
// buf                start of incomplete cell  pos

func (b *Writer) addLine() {
	b.lines_size.Push(array.NewIntArray(0));
	b.lines_width.Push(array.NewIntArray(0));
}

func (b *Writer) Init(writer io.Write, cellwidth, padding int, padchar byte, align_left, filter_html bool) *Writer {
	if cellwidth < 0 {
		panic("negative cellwidth");
	}
	if padding < 0 {
		panic("negative padding");
	}
	b.writer = writer;
	b.cellwidth = cellwidth;
	b.padding = padding;
	for i := len(b.padbytes) - 1; i >= 0; i-- {
		b.padbytes[i] = padchar;
	}
	b.align_left = align_left || padchar == '\t';  // tab enforces left-alignment
	b.filter_html = filter_html;

	b.buf.Init(1024);
	b.lines_size.Init(0);
	b.lines_width.Init(0);
	b.widths.Init(0);
	b.addLine();  // the very first line

	return b;
}

func (b *Writer) line(i int) (*array.IntArray, *array.IntArray) {
	return
		b.lines_size.At(i).(*array.IntArray),
		b.lines_width.At(i).(*array.IntArray);
}

// debugging support
func (b *Writer) dump() {
	pos := 0;
	for i := 0; i < b.lines_size.Len(); i++ {
		line_size, line_width := b.line(i);
		print("(", i, ") ");
		for j := 0; j < line_size.Len(); j++ {
			s := line_size.At(j);
			print("[", string(b.buf.slice(pos, pos + s)), "]");
			pos += s;
		}
		print("\n");
	}
	print("\n");
}

func (b *Writer) write0(buf []byte) *os.Error {
	n, err := b.writer.Write(buf);
	if n != len(buf) && err == nil {
		err = os.EIO;
	}
	return err;
}

var newline = []byte{'\n'}

func (b *Writer) writePadding(textw, cellw int) (err *os.Error) {
	if b.padbytes[0] == '\t' {
		// make cell width a multiple of cellwidth
		cellw = ((cellw + b.cellwidth - 1) / b.cellwidth) * b.cellwidth;
	}

	n := cellw - textw;
	if n < 0 {
		panic("internal error");
	}

	if b.padbytes[0] == '\t' {
		n = (n + b.cellwidth - 1) / b.cellwidth;
	}

	for n > len(b.padbytes) {
		err = b.write0(b.padbytes);
		if err != nil {
			goto exit;
		}
		n -= len(b.padbytes);
	}
	err = b.write0(b.padbytes[0 : n]);

exit:
	return err;
}

func (b *Writer) writeLines(pos0 int, line0, line1 int) (pos int, err *os.Error) {
	pos = pos0;
	for i := line0; i < line1; i++ {
		line_size, line_width := b.line(i);
		for j := 0; j < line_size.Len(); j++ {
			s, w := line_size.At(j), line_width.At(j);

			if b.align_left {
				err = b.write0(b.buf.slice(pos, pos + s));
				if err != nil {
					goto exit;
				}
				pos += s;
				if j < b.widths.Len() {
					err = b.writePadding(w, b.widths.At(j));
					if err != nil {
						goto exit;
					}
				}

			} else {  // align right

				if j < b.widths.Len() {
					err = b.writePadding(w, b.widths.At(j));
					if err != nil {
						goto exit;
					}
				}
				err = b.write0(b.buf.slice(pos, pos + s));
				if err != nil {
					goto exit;
				}
				pos += s;
			}
		}

		if i+1 == b.lines_size.Len() {
			// last buffered line - we don't have a newline, so just write
			// any outstanding buffered data
			err = b.write0(b.buf.slice(pos, pos + b.size));
			pos += b.size;
		} else {
			// not the last line - write newline
			err = b.write0(newline);
		}
		if err != nil {
			goto exit;
		}
	}

exit:
	return pos, err;
}

func (b *Writer) format(pos0 int, line0, line1 int) (pos int, err *os.Error) {
	pos = pos0;
	column := b.widths.Len();
	last := line0;
	for this := line0; this < line1; this++ {
		line_size, line_width := b.line(this);

		if column < line_size.Len() - 1 {
			// cell exists in this column
			// (note that the last cell per line is ignored)

			// print unprinted lines until beginning of block
			pos, err = b.writeLines(pos, last, this);
			if err != nil {
				goto exit;
			}
			last = this;

			// column block begin
			width := b.cellwidth;  // minimal width
			for ; this < line1; this++ {
				line_size, line_width = b.line(this);
				if column < line_size.Len() - 1 {
					// cell exists in this column => update width
					w := line_width.At(column) + b.padding;
					if w > width {
						width = w;
					}
				} else {
					break
				}
			}
			// column block end

			// format and print all columns to the right of this column
			// (we know the widths of this column and all columns to the left)
			b.widths.Push(width);
			pos, err = b.format(pos, last, this);
			b.widths.Pop();
			last = this;
		}
	}

	// print unprinted lines until end
	pos, err = b.writeLines(pos, last, line1);

exit:
	return pos, err;
}

func (b *Writer) Flush() *os.Error {
	dummy, err := b.format(0, 0, b.lines_size.Len());
	// reset (even in the presence of errors)
	b.buf.clear();
	b.size, b.width = 0, 0;
	b.pos = 0;
	b.lines_size.Init(0);
	b.lines_width.Init(0);
	b.addLine();
	return err;
}

func unicodeLen(buf []byte) int {
	l := 0;
	for i := 0; i < len(buf); {
		if buf[i] < utf8.RuneSelf {
			i++;
		} else {
			rune, size := utf8.DecodeRune(buf[i : len(buf)]);
			i += size;
		}
		l++;
	}
	return l;
}

func (b *Writer) append(buf []byte) {
	b.buf.append(buf);
	b.size += len(buf);
}

/* export */ func (b *Writer) Write(buf []byte) (written int, err *os.Error) {
	i0, n := 0, len(buf);

	// split text into cells
	for i := 0; i < n; i++ {
		ch := buf[i];

		if b.html_char == 0 {
			// outside html tag/entity
			switch ch {
			case '\t', '\n':
				b.append(buf[i0 : i]);
				i0 = i + 1;  // exclude ch from (next) cell
				b.width += unicodeLen(b.buf.slice(b.pos, b.buf.Len()));
				b.pos = b.buf.Len();

				// terminate cell
				last_size, last_width := b.line(b.lines_size.Len() - 1);
				last_size.Push(b.size);
				last_width.Push(b.width);
				b.size, b.width = 0, 0;

				if ch == '\n' {
					b.addLine();
					if last_size.Len() == 1 {
						// The previous line has only one cell which does not have
						// an impact on the formatting of the following lines (the
						// last cell per line is ignored by format()), thus we can
						// flush the Writer contents.
						err = b.Flush();
						if err != nil {
							return i0, err;
						}
					}
				}

			case '<', '&':
				if b.filter_html {
					b.append(buf[i0 : i]);
					i0 = i;
					b.width += unicodeLen(b.buf.slice(b.pos, b.buf.Len()));
					b.pos = -1;  // preventative - should not be used (will cause index out of bounds)
					if ch == '<' {
						b.html_char = '>';
					} else {
						b.html_char = ';';
					}
				}
			}

		} else {
			// inside html tag/entity
			if ch == b.html_char {
				// reached the end of tag/entity
				b.append(buf[i0 : i + 1]);
				i0 = i + 1;
				if b.html_char == ';' {
					b.width++;  // count as one char
				}
				b.pos = b.buf.Len();
				b.html_char = 0;
			}
		}
	}

	// append leftover text
	b.append(buf[i0 : n]);
	return n, nil;
}

func New(writer io.Write, cellwidth, padding int, padchar byte, align_left, filter_html bool) *Writer {
	return new(Writer).Init(writer, cellwidth, padding, padchar, align_left, filter_html)
}
<commit_msg>- removed obsolete comments<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package tabwriter

import (
	"os";
	"io";
	"array";
	"utf8";
)

// ----------------------------------------------------------------------------
// Basic byteArray support

type byteArray struct {
	a []byte;
}

func (b *byteArray) Init(initial_size int) {
	b.a = make([]byte, initial_size)[0 : 0];
}

func (b *byteArray) Len() int {
	return len(b.a);
}

func (b *byteArray) clear() {
	b.a = b.a[0 : 0];
}

func (b *byteArray) slice(i, j int) []byte {
	return b.a[i : j];  // BUG should really be &b.a[i : j]
}

func (b *byteArray) append(s []byte) {
	a := b.a;
	n := len(a);
	m := n + len(s);

	if m > cap(a) {
		n2 := 2*n;
		if m > n2 {
			n2 = m;
		}
		b := make([]byte, n2);
		for i := 0; i < n; i++ {
			b[i] = a[i];
		}
		a = b;
	}

	a = a[0 : m];
	for i := len(s) - 1; i >= 0; i-- {
		a[n + i] = s[i];
	}
	b.a = a;
}

// ----------------------------------------------------------------------------
// Writer is a filter implementing the io.Write interface. It assumes
// that the incoming bytes represent UTF-8 encoded text consisting of
// lines of tab-terminated "cells". Cells in adjacent lines constitute
// a column. Writer rewrites the incoming text such that all cells in
// a column have the same width; thus it effectively aligns cells. It
// does this by adding padding where necessary. All characters (ASCII
// or not) are assumed to be of the same width - this may not be true
// for arbitrary UTF-8 characters visualized on the screen.
//
// Note that any text at the end of a line that is not tab-terminated
// is not a cell and does not enforce alignment of cells in adjacent
// rows. To make it a cell it needs to be tab-terminated. (For more
// information see http://nickgravgaard.com/elastictabstops/index.html)
//
// Formatting can be controlled via parameters:
//
// cellwidth	minimal cell width
// padding      additional cell padding
// padchar      ASCII char used for padding
//              if padchar == '\t', the Writer will assume that the
//              width of a '\t' in the formatted output is cellwidth,
//              and cells are left-aligned independent of align_left
//              (for correct-looking results, cellwidth must correspond
//              to the tabwidth in the viewer displaying the result)
// filter_html  ignores html tags and handles entities (starting with '&'
//              and ending in ';') as single characters (width = 1)

type Writer struct {
	// configuration
	writer io.Write;
	cellwidth int;
	padding int;
	padbytes [8]byte;
	align_left bool;
	filter_html bool;

	// current state
	html_char byte;  // terminating char of html tag/entity, or 0 ('>', ';', or 0)
	buf byteArray;  // collected text w/o tabs and newlines
	size int;  // size of incomplete cell in bytes
	width int;  // width of incomplete cell in runes up to buf[pos] w/o ignored sections
	pos int;  // buffer position up to which width of incomplete cell has been computed
	lines_size array.Array;  // list of lines; each line is a list of cell sizes in bytes
	lines_width array.Array;  // list of lines; each line is a list of cell widths in runes
	widths array.IntArray;  // list of column widths in runes - re-used during formatting
}

// Internal representation (current state):
//
// - all text written is appended to buf; tabs and newlines are stripped away
// - at any given time there is a (possibly empty) incomplete cell at the end
//   (the cell starts after a tab or newline)
// - size is the number of bytes belonging to the cell so far
// - width is text width in runes of that cell from the start of the cell to
//   position pos; html tags and entities are excluded from this width if html
//   filtering is enabled
// - the sizes and widths of processed text are kept in the lines_size and
//   lines_width arrays, which contain an array of sizes or widths for each line
// - the widths array is a temporary array with current widths used during
//   formatting; it is kept in Writer because it's re-used
//
//                    |<---------- size ---------->|
//                    |                            |
//                    |<- width ->|<- ignored ->|  |
//                    |           |             |  |
// [---processed---tab------------<tag>...</tag>...]
// ^                  ^                         ^
// |                  |                         |
// buf                start of incomplete cell  pos

func (b *Writer) addLine() {
	b.lines_size.Push(array.NewIntArray(0));
	b.lines_width.Push(array.NewIntArray(0));
}

func (b *Writer) Init(writer io.Write, cellwidth, padding int, padchar byte, align_left, filter_html bool) *Writer {
	if cellwidth < 0 {
		panic("negative cellwidth");
	}
	if padding < 0 {
		panic("negative padding");
	}
	b.writer = writer;
	b.cellwidth = cellwidth;
	b.padding = padding;
	for i := len(b.padbytes) - 1; i >= 0; i-- {
		b.padbytes[i] = padchar;
	}
	b.align_left = align_left || padchar == '\t';  // tab enforces left-alignment
	b.filter_html = filter_html;

	b.buf.Init(1024);
	b.lines_size.Init(0);
	b.lines_width.Init(0);
	b.widths.Init(0);
	b.addLine();  // the very first line

	return b;
}

func (b *Writer) line(i int) (*array.IntArray, *array.IntArray) {
	return
		b.lines_size.At(i).(*array.IntArray),
		b.lines_width.At(i).(*array.IntArray);
}

// debugging support
func (b *Writer) dump() {
	pos := 0;
	for i := 0; i < b.lines_size.Len(); i++ {
		line_size, line_width := b.line(i);
		print("(", i, ") ");
		for j := 0; j < line_size.Len(); j++ {
			s := line_size.At(j);
			print("[", string(b.buf.slice(pos, pos + s)), "]");
			pos += s;
		}
		print("\n");
	}
	print("\n");
}

func (b *Writer) write0(buf []byte) *os.Error {
	n, err := b.writer.Write(buf);
	if n != len(buf) && err == nil {
		err = os.EIO;
	}
	return err;
}

var newline = []byte{'\n'}

func (b *Writer) writePadding(textw, cellw int) (err *os.Error) {
	if b.padbytes[0] == '\t' {
		// make cell width a multiple of cellwidth
		cellw = ((cellw + b.cellwidth - 1) / b.cellwidth) * b.cellwidth;
	}

	n := cellw - textw;
	if n < 0 {
		panic("internal error");
	}

	if b.padbytes[0] == '\t' {
		n = (n + b.cellwidth - 1) / b.cellwidth;
	}

	for n > len(b.padbytes) {
		err = b.write0(b.padbytes);
		if err != nil {
			goto exit;
		}
		n -= len(b.padbytes);
	}
	err = b.write0(b.padbytes[0 : n]);

exit:
	return err;
}

func (b *Writer) writeLines(pos0 int, line0, line1 int) (pos int, err *os.Error) {
	pos = pos0;
	for i := line0; i < line1; i++ {
		line_size, line_width := b.line(i);
		for j := 0; j < line_size.Len(); j++ {
			s, w := line_size.At(j), line_width.At(j);

			if b.align_left {
				err = b.write0(b.buf.slice(pos, pos + s));
				if err != nil {
					goto exit;
				}
				pos += s;
				if j < b.widths.Len() {
					err = b.writePadding(w, b.widths.At(j));
					if err != nil {
						goto exit;
					}
				}

			} else {  // align right

				if j < b.widths.Len() {
					err = b.writePadding(w, b.widths.At(j));
					if err != nil {
						goto exit;
					}
				}
				err = b.write0(b.buf.slice(pos, pos + s));
				if err != nil {
					goto exit;
				}
				pos += s;
			}
		}

		if i+1 == b.lines_size.Len() {
			// last buffered line - we don't have a newline, so just write
			// any outstanding buffered data
			err = b.write0(b.buf.slice(pos, pos + b.size));
			pos += b.size;
		} else {
			// not the last line - write newline
			err = b.write0(newline);
		}
		if err != nil {
			goto exit;
		}
	}

exit:
	return pos, err;
}

func (b *Writer) format(pos0 int, line0, line1 int) (pos int, err *os.Error) {
	pos = pos0;
	column := b.widths.Len();
	last := line0;
	for this := line0; this < line1; this++ {
		line_size, line_width := b.line(this);

		if column < line_size.Len() - 1 {
			// cell exists in this column
			// (note that the last cell per line is ignored)

			// print unprinted lines until beginning of block
			pos, err = b.writeLines(pos, last, this);
			if err != nil {
				goto exit;
			}
			last = this;

			// column block begin
			width := b.cellwidth;  // minimal width
			for ; this < line1; this++ {
				line_size, line_width = b.line(this);
				if column < line_size.Len() - 1 {
					// cell exists in this column => update width
					w := line_width.At(column) + b.padding;
					if w > width {
						width = w;
					}
				} else {
					break
				}
			}
			// column block end

			// format and print all columns to the right of this column
			// (we know the widths of this column and all columns to the left)
			b.widths.Push(width);
			pos, err = b.format(pos, last, this);
			b.widths.Pop();
			last = this;
		}
	}

	// print unprinted lines until end
	pos, err = b.writeLines(pos, last, line1);

exit:
	return pos, err;
}

func (b *Writer) Flush() *os.Error {
	dummy, err := b.format(0, 0, b.lines_size.Len());
	// reset (even in the presence of errors)
	b.buf.clear();
	b.size, b.width = 0, 0;
	b.pos = 0;
	b.lines_size.Init(0);
	b.lines_width.Init(0);
	b.addLine();
	return err;
}

func unicodeLen(buf []byte) int {
	l := 0;
	for i := 0; i < len(buf); {
		if buf[i] < utf8.RuneSelf {
			i++;
		} else {
			rune, size := utf8.DecodeRune(buf[i : len(buf)]);
			i += size;
		}
		l++;
	}
	return l;
}

func (b *Writer) append(buf []byte) {
	b.buf.append(buf);
	b.size += len(buf);
}

func (b *Writer) Write(buf []byte) (written int, err *os.Error) {
	i0, n := 0, len(buf);

	// split text into cells
	for i := 0; i < n; i++ {
		ch := buf[i];

		if b.html_char == 0 {
			// outside html tag/entity
			switch ch {
			case '\t', '\n':
				b.append(buf[i0 : i]);
				i0 = i + 1;  // exclude ch from (next) cell
				b.width += unicodeLen(b.buf.slice(b.pos, b.buf.Len()));
				b.pos = b.buf.Len();

				// terminate cell
				last_size, last_width := b.line(b.lines_size.Len() - 1);
				last_size.Push(b.size);
				last_width.Push(b.width);
				b.size, b.width = 0, 0;

				if ch == '\n' {
					b.addLine();
					if last_size.Len() == 1 {
						// The previous line has only one cell which does not have
						// an impact on the formatting of the following lines (the
						// last cell per line is ignored by format()), thus we can
						// flush the Writer contents.
						err = b.Flush();
						if err != nil {
							return i0, err;
						}
					}
				}

			case '<', '&':
				if b.filter_html {
					b.append(buf[i0 : i]);
					i0 = i;
					b.width += unicodeLen(b.buf.slice(b.pos, b.buf.Len()));
					b.pos = -1;  // preventative - should not be used (will cause index out of bounds)
					if ch == '<' {
						b.html_char = '>';
					} else {
						b.html_char = ';';
					}
				}
			}

		} else {
			// inside html tag/entity
			if ch == b.html_char {
				// reached the end of tag/entity
				b.append(buf[i0 : i + 1]);
				i0 = i + 1;
				if b.html_char == ';' {
					b.width++;  // count as one char
				}
				b.pos = b.buf.Len();
				b.html_char = 0;
			}
		}
	}

	// append leftover text
	b.append(buf[i0 : n]);
	return n, nil;
}

func New(writer io.Write, cellwidth, padding int, padchar byte, align_left, filter_html bool) *Writer {
	return new(Writer).Init(writer, cellwidth, padding, padchar, align_left, filter_html)
}
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Contributor: Aaron Meihm ameihm@mozilla.com [:alm]
package main

import (
	"encoding/json"
	"fmt"
	"github.com/jvehent/cljs"
	"mig.ninja/mig"
	"net/http"
	"strconv"
)

// Locate the manifest record that should be served to a given loader ID. Note
// the agent environment is also passed in here so the API can update the loader
// entry with the last-known state of the agent.
func locateManifestFromLoader(loaderid float64, agt mig.Agent) (mig.ManifestRecord, error) {
	var ret mig.ManifestRecord
	err := ctx.DB.UpdateLoaderEntry(loaderid, agt)
	if err != nil {
		return ret, err
	}
	manifestid, err := ctx.DB.ManifestIDFromLoaderID(loaderid)
	if err != nil {
		return ret, err
	}
	ret, err = ctx.DB.GetManifestFromID(manifestid)
	if err != nil {
		return ret, err
	}
	return ret, nil
}

// Manipulate the status of an existing manifest
func statusManifest(respWriter http.ResponseWriter, request *http.Request) {
	loc := fmt.Sprintf("%s%s", ctx.Server.Host, request.URL.String())
	opid := getOpID(request)
	resource := cljs.New(loc)
	defer func() {
		if e := recover(); e != nil {
			ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("%v", e)}.Err()
			resource.SetError(cljs.Error{Code: fmt.Sprintf("%.0f", opid), Message: fmt.Sprintf("%v", e)})
			respond(500, resource, respWriter, request)
		}
		ctx.Channels.Log <- mig.Log{OpID: opid, Desc: "leaving statusManifest()"}.Debug()
	}()

	err := request.ParseForm()
	if err != nil {
		panic(err)
	}

	ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("Received manifest status change request")}.Debug()

	manifestid, err := strconv.ParseFloat(request.FormValue("manifestid"), 64)
	if err != nil {
		panic(err)
	}
	sts := request.FormValue("status")
	// XXX We only support a change to staged here right now. Disabled
	// could be added as well, active we don't want as this should
	// always be set by the API based on the number of valid signatures
	// applied to the record.
	if sts == "staged" {
		err = ctx.DB.ManifestClearSignatures(manifestid)
		if err != nil {
			panic(err)
		}
		err = ctx.DB.ManifestUpdateStatus(manifestid)
		if err != nil {
			panic(err)
		}
	} else if sts == "disabled" {
		err = ctx.DB.ManifestDisable(manifestid)
		if err != nil {
			panic(err)
		}
	} else {
		panic("Invalid status specified, must be disabled or staged")
	}

	respond(200, resource, respWriter, request)
}

// Request to sign an existing manifest
func signManifest(respWriter http.ResponseWriter, request *http.Request) {
	loc := fmt.Sprintf("%s%s", ctx.Server.Host, request.URL.String())
	opid := getOpID(request)
	resource := cljs.New(loc)
	defer func() {
		if e := recover(); e != nil {
			ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("%v", e)}.Err()
			resource.SetError(cljs.Error{Code: fmt.Sprintf("%.0f", opid), Message: fmt.Sprintf("%v", e)})
			respond(500, resource, respWriter, request)
		}
		ctx.Channels.Log <- mig.Log{OpID: opid, Desc: "leaving signManifest()"}.Debug()
	}()

	err := request.ParseForm()
	if err != nil {
		panic(err)
	}

	ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("Received manifest sign request")}.Debug()

	manifestid, err := strconv.ParseFloat(request.FormValue("manifestid"), 64)
	if err != nil {
		panic(err)
	}
	sig := request.FormValue("signature")
	if sig == "" {
		panic("Invalid signature specified")
	}

	err = ctx.DB.ManifestAddSignature(manifestid, sig, getInvID(request))
	if err != nil {
		panic(err)
	}

	respond(200, resource, respWriter, request)
}

// Add a new manifest record
func newManifest(respWriter http.ResponseWriter, request *http.Request) {
	loc := fmt.Sprintf("%s%s", ctx.Server.Host, request.URL.String())
	opid := getOpID(request)
	resource := cljs.New(loc)
	defer func() {
		if e := recover(); e != nil {
			ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("%v", e)}.Err()
			resource.SetError(cljs.Error{Code: fmt.Sprintf("%.0f", opid), Message: fmt.Sprintf("%v", e)})
			respond(500, resource, respWriter, request)
		}
		ctx.Channels.Log <- mig.Log{OpID: opid, Desc: "leaving newManifest()"}.Debug()
	}()

	err := request.ParseForm()
	if err != nil {
		panic(err)
	}

	ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("Received new manifest request")}.Debug()

	mrstr := request.FormValue("manifest")
	if mrstr == "" {
		panic("no manifest record specified in form")
	}
	var mr mig.ManifestRecord
	err = json.Unmarshal([]byte(mrstr), &mr)
	if err != nil {
		panic(err)
	}
	err = mr.Validate()
	if err != nil {
		panic(err)
	}
	err = ctx.DB.ManifestAdd(mr)
	if err != nil {
		panic(err)
	}

	respond(200, resource, respWriter, request)
}

// Return information describing an existing manifest
func getManifest(respWriter http.ResponseWriter, request *http.Request) {
	loc := fmt.Sprintf("%s%s", ctx.Server.Host, request.URL.String())
	opid := getOpID(request)
	resource := cljs.New(loc)
	defer func() {
		if e := recover(); e != nil {
			ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("%v", e)}.Err()
			resource.SetError(cljs.Error{Code: fmt.Sprintf("%.0f", opid), Message: fmt.Sprintf("%v", e)})
			respond(500, resource, respWriter, request)
		}
		ctx.Channels.Log <- mig.Log{OpID: opid, Desc: "leaving getManifest()"}.Debug()
	}()
	mid, err := strconv.ParseFloat(request.URL.Query()["manifestid"][0], 64)
	if err != nil {
		err = fmt.Errorf("Wrong parameters 'manifestid': '%v'", err)
		panic(err)
	}

	var mr mig.ManifestRecord
	if mid > 0 {
		mr, err = ctx.DB.GetManifestFromID(mid)
		if err != nil {
			if fmt.Sprintf("%v", err) == "Error while retrieving manifest: 'sql: no rows in result set'" {
				resource.SetError(cljs.Error{
					Code:    fmt.Sprintf("%.0f", opid),
					Message: fmt.Sprintf("Manifest ID '%.0f' not found", mid)})
				respond(404, resource, respWriter, request)
				return
			} else {
				panic(err)
			}
		}
	} else {
		// bad request, return 400
		resource.SetError(cljs.Error{
			Code:    fmt.Sprintf("%.0f", opid),
			Message: fmt.Sprintf("Invalid Manifest ID '%.0f'", mid)})
		respond(400, resource, respWriter, request)
		return
	}
	mi, err := manifestRecordToItem(mr, ctx)
	if err != nil {
		panic(err)
	}
	resource.AddItem(mi)
	respond(200, resource, respWriter, request)
}

// API entry point used to request a file be sent to the loader from the API.
func getManifestFile(respWriter http.ResponseWriter, request *http.Request) {
	loc := fmt.Sprintf("%s%s", ctx.Server.Host, request.URL.String())
	opid := getOpID(request)
	resource := cljs.New(loc)
	defer func() {
		if e := recover(); e != nil {
			ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("%v", e)}.Err()
			resource.SetError(cljs.Error{Code: fmt.Sprintf("%.0f", opid), Message: fmt.Sprintf("%v", e)})
			respond(500, resource, respWriter, request)
		}
		ctx.Channels.Log <- mig.Log{OpID: opid, Desc: "leaving getManifestFile()"}.Debug()
	}()
	err := request.ParseForm()
	if err != nil {
		panic(err)
	}

	ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("Received manifest file request")}.Debug()

	var manifestParam mig.ManifestParameters
	err = json.Unmarshal([]byte(request.FormValue("parameters")), &manifestParam)
	if err != nil {
		panic(err)
	}
	err = manifestParam.ValidateFetch()
	if err != nil {
		panic(err)
	}

	loaderid := getLoaderID(request)
	if loaderid == 0 {
		panic("Request has no valid loader ID")
	}
	ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("Loader request for entry %v", loaderid)}.Debug()

	// Update the loader entry with the parameters, and locate a valid manifest
	mf, err := locateManifestFromLoader(loaderid, manifestParam.AgentIdentifier)
	if err != nil {
		panic(err)
	}
	data, err := mf.ManifestObject(manifestParam.Object)
	if err != nil {
		panic(err)
	}
	fetchresp := mig.ManifestFetchResponse{}
	fetchresp.Data = data

	// Send the response to the loader
	err = resource.AddItem(cljs.Item{
		Href: request.URL.String(),
		Data: []cljs.Data{
			{
				Name:  "content",
				Value: fetchresp,
			},
		}})
	if err != nil {
		panic(err)
	}
	respond(200, resource, respWriter, request)
}

// This API entry point is used by the loader to request a manifest file that
// indicates the most current version of the agent to be used. The loader
// sends some basic information in the request parameters so the API can decide
// which manifest to send the loader, and authenticate the loader instance.
//
// If the key passed in the request is not valid, the request will be rejected.
func getAgentManifest(respWriter http.ResponseWriter, request *http.Request) {
	loc := fmt.Sprintf("%s%s", ctx.Server.Host, request.URL.String())
	opid := getOpID(request)
	resource := cljs.New(loc)
	defer func() {
		if e := recover(); e != nil {
			ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("%v", e)}.Err()
			resource.SetError(cljs.Error{Code: fmt.Sprintf("%.0f", opid), Message: fmt.Sprintf("%v", e)})
			respond(500, resource, respWriter, request)
		}
		ctx.Channels.Log <- mig.Log{OpID: opid, Desc: "leaving getAgentManifest()"}.Debug()
	}()
	err := request.ParseForm()
	if err != nil {
		panic(err)
	}

	var manifestParam mig.ManifestParameters
	err = json.Unmarshal([]byte(request.FormValue("parameters")), &manifestParam)
	if err != nil {
		panic(err)
	}
	err = manifestParam.Validate()
	if err != nil {
		panic(err)
	}
	ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("Received manifest request")}.Debug()

	loaderid := getLoaderID(request)
	if loaderid == 0 {
		panic("Request has no valid loader ID")
	}

	// Update the loader entry with the parameters, and locate a valid manifest
	mf, err := locateManifestFromLoader(loaderid, manifestParam.AgentIdentifier)
	if err != nil {
		panic(err)
	}
	m, err := mf.ManifestResponse()
	if err != nil {
		panic(err)
	}

	// Send the manifest to the loader
	err = resource.AddItem(cljs.Item{
		Href: request.URL.String(),
		Data: []cljs.Data{
			{
				Name:  "manifest",
				Value: m,
			},
		}})
	if err != nil {
		panic(err)
	}
	respond(200, resource, respWriter, request)
}

func manifestRecordToItem(mr mig.ManifestRecord, ctx Context) (item cljs.Item, err error) {
	item.Href = fmt.Sprintf("%s/manifest?manifestid=%.0f", ctx.Server.BaseURL, mr.ID)
	item.Data = []cljs.Data{
		{Name: "manifest", Value: mr},
	}
	return
}
<commit_msg>[minor] small cleanup to loader api endpoint functions<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Contributor: Aaron Meihm ameihm@mozilla.com [:alm]
package main

import (
	"encoding/json"
	"fmt"
	"github.com/jvehent/cljs"
	"mig.ninja/mig"
	"net/http"
	"strconv"
)

// Locate the manifest record that should be served to a given loader ID. Note
// the agent environment is also passed in here so the API can update the loader
// entry with the last-known state of the agent.
func locateManifestFromLoader(loaderid float64, agt mig.Agent) (mig.ManifestRecord, error) {
	var ret mig.ManifestRecord
	err := ctx.DB.UpdateLoaderEntry(loaderid, agt)
	if err != nil {
		return ret, err
	}
	manifestid, err := ctx.DB.ManifestIDFromLoaderID(loaderid)
	if err != nil {
		return ret, err
	}
	ret, err = ctx.DB.GetManifestFromID(manifestid)
	if err != nil {
		return ret, err
	}
	return ret, nil
}

// Manipulate the status of an existing manifest
func statusManifest(respWriter http.ResponseWriter, request *http.Request) {
	loc := fmt.Sprintf("%s%s", ctx.Server.Host, request.URL.String())
	opid := getOpID(request)
	resource := cljs.New(loc)
	defer func() {
		if e := recover(); e != nil {
			ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("%v", e)}.Err()
			resource.SetError(cljs.Error{Code: fmt.Sprintf("%.0f", opid), Message: fmt.Sprintf("%v", e)})
			respond(500, resource, respWriter, request)
		}
		ctx.Channels.Log <- mig.Log{OpID: opid, Desc: "leaving statusManifest()"}.Debug()
	}()

	err := request.ParseForm()
	if err != nil {
		panic(err)
	}

	ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("Received manifest status change request")}.Debug()

	manifestid, err := strconv.ParseFloat(request.FormValue("manifestid"), 64)
	if err != nil {
		panic(err)
	}
	sts := request.FormValue("status")
	// XXX We only support a change to staged here right now. Disabled
	// could be added as well, active we don't want as this should
	// always be set by the API based on the number of valid signatures
	// applied to the record.
	if sts == "staged" {
		err = ctx.DB.ManifestClearSignatures(manifestid)
		if err != nil {
			panic(err)
		}
		err = ctx.DB.ManifestUpdateStatus(manifestid)
		if err != nil {
			panic(err)
		}
	} else if sts == "disabled" {
		err = ctx.DB.ManifestDisable(manifestid)
		if err != nil {
			panic(err)
		}
	} else {
		panic("Invalid status specified, must be disabled or staged")
	}

	respond(200, resource, respWriter, request)
}

// Request to sign an existing manifest
func signManifest(respWriter http.ResponseWriter, request *http.Request) {
	loc := fmt.Sprintf("%s%s", ctx.Server.Host, request.URL.String())
	opid := getOpID(request)
	resource := cljs.New(loc)
	defer func() {
		if e := recover(); e != nil {
			ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("%v", e)}.Err()
			resource.SetError(cljs.Error{Code: fmt.Sprintf("%.0f", opid), Message: fmt.Sprintf("%v", e)})
			respond(500, resource, respWriter, request)
		}
		ctx.Channels.Log <- mig.Log{OpID: opid, Desc: "leaving signManifest()"}.Debug()
	}()

	err := request.ParseForm()
	if err != nil {
		panic(err)
	}

	ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("Received manifest sign request")}.Debug()

	manifestid, err := strconv.ParseFloat(request.FormValue("manifestid"), 64)
	if err != nil {
		panic(err)
	}
	sig := request.FormValue("signature")
	if sig == "" {
		panic("Invalid signature specified")
	}

	err = ctx.DB.ManifestAddSignature(manifestid, sig, getInvID(request))
	if err != nil {
		panic(err)
	}

	respond(200, resource, respWriter, request)
}

// Add a new manifest record
func newManifest(respWriter http.ResponseWriter, request *http.Request) {
	loc := fmt.Sprintf("%s%s", ctx.Server.Host, request.URL.String())
	opid := getOpID(request)
	resource := cljs.New(loc)
	defer func() {
		if e := recover(); e != nil {
			ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("%v", e)}.Err()
			resource.SetError(cljs.Error{Code: fmt.Sprintf("%.0f", opid), Message: fmt.Sprintf("%v", e)})
			respond(500, resource, respWriter, request)
		}
		ctx.Channels.Log <- mig.Log{OpID: opid, Desc: "leaving newManifest()"}.Debug()
	}()

	err := request.ParseForm()
	if err != nil {
		panic(err)
	}

	ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("Received new manifest request")}.Debug()

	mrstr := request.FormValue("manifest")
	if mrstr == "" {
		panic("no manifest record specified in form")
	}
	var mr mig.ManifestRecord
	err = json.Unmarshal([]byte(mrstr), &mr)
	if err != nil {
		panic(err)
	}
	err = mr.Validate()
	if err != nil {
		panic(err)
	}
	err = ctx.DB.ManifestAdd(mr)
	if err != nil {
		panic(err)
	}

	respond(200, resource, respWriter, request)
}

// Return information describing an existing manifest
func getManifest(respWriter http.ResponseWriter, request *http.Request) {
	loc := fmt.Sprintf("%s%s", ctx.Server.Host, request.URL.String())
	opid := getOpID(request)
	resource := cljs.New(loc)
	defer func() {
		if e := recover(); e != nil {
			ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("%v", e)}.Err()
			resource.SetError(cljs.Error{Code: fmt.Sprintf("%.0f", opid), Message: fmt.Sprintf("%v", e)})
			respond(500, resource, respWriter, request)
		}
		ctx.Channels.Log <- mig.Log{OpID: opid, Desc: "leaving getManifest()"}.Debug()
	}()
	mid, err := strconv.ParseFloat(request.URL.Query()["manifestid"][0], 64)
	if err != nil {
		err = fmt.Errorf("Wrong parameters 'manifestid': '%v'", err)
		panic(err)
	}

	var mr mig.ManifestRecord
	if mid > 0 {
		mr, err = ctx.DB.GetManifestFromID(mid)
		if err != nil {
			if fmt.Sprintf("%v", err) == "Error while retrieving manifest: 'sql: no rows in result set'" {
				resource.SetError(cljs.Error{
					Code:    fmt.Sprintf("%.0f", opid),
					Message: fmt.Sprintf("Manifest ID '%.0f' not found", mid)})
				respond(404, resource, respWriter, request)
				return
			} else {
				panic(err)
			}
		}
	} else {
		// bad request, return 400
		resource.SetError(cljs.Error{
			Code:    fmt.Sprintf("%.0f", opid),
			Message: fmt.Sprintf("Invalid Manifest ID '%.0f'", mid)})
		respond(400, resource, respWriter, request)
		return
	}
	mi, err := manifestRecordToItem(mr, ctx)
	if err != nil {
		panic(err)
	}
	resource.AddItem(mi)
	respond(200, resource, respWriter, request)
}

// API entry point used to request a file be sent to the loader from the API.
// This would typically be called from a loader after it has received a
// manifest and determined updates to file system objects are required.
func getManifestFile(respWriter http.ResponseWriter, request *http.Request) {
	loc := fmt.Sprintf("%s%s", ctx.Server.Host, request.URL.String())
	opid := getOpID(request)
	resource := cljs.New(loc)
	defer func() {
		if e := recover(); e != nil {
			ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("%v", e)}.Err()
			resource.SetError(cljs.Error{Code: fmt.Sprintf("%.0f", opid), Message: fmt.Sprintf("%v", e)})
			respond(500, resource, respWriter, request)
		}
		ctx.Channels.Log <- mig.Log{OpID: opid, Desc: "leaving getManifestFile()"}.Debug()
	}()
	err := request.ParseForm()
	if err != nil {
		panic(err)
	}

	ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("Received manifest file request")}.Debug()

	var manifestParam mig.ManifestParameters
	err = json.Unmarshal([]byte(request.FormValue("parameters")), &manifestParam)
	if err != nil {
		panic(err)
	}
	err = manifestParam.ValidateFetch()
	if err != nil {
		panic(err)
	}

	loaderid := getLoaderID(request)
	if loaderid == 0 {
		panic("Request has no valid loader ID")
	}
	ctx.Channels.Log <- mig.Log{OpID: opid,
		Desc: fmt.Sprintf("Loader request from %v for %v",
			loaderid, manifestParam.Object)}.Debug()

	// Update the loader entry with the parameters, and locate a valid manifest
	mf, err := locateManifestFromLoader(loaderid, manifestParam.AgentIdentifier)
	if err != nil {
		panic(err)
	}
	data, err := mf.ManifestObject(manifestParam.Object)
	if err != nil {
		panic(err)
	}
	fetchresp := mig.ManifestFetchResponse{Data: data}

	// Send the response to the loader
	err = resource.AddItem(cljs.Item{
		Href: request.URL.String(),
		Data: []cljs.Data{
			{
				Name:  "content",
				Value: fetchresp,
			},
		}})
	if err != nil {
		panic(err)
	}
	respond(200, resource, respWriter, request)
}

// This API entry point is used by the loader to request a manifest file that
// indicates the most current version of the agent to be used. The loader
// sends some basic information in the request parameters so the API can decide
// which manifest to send the loader.
//
// If the key passed in the request is not valid, the request will be rejected.
func getAgentManifest(respWriter http.ResponseWriter, request *http.Request) {
	loc := fmt.Sprintf("%s%s", ctx.Server.Host, request.URL.String())
	opid := getOpID(request)
	resource := cljs.New(loc)
	defer func() {
		if e := recover(); e != nil {
			ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("%v", e)}.Err()
			resource.SetError(cljs.Error{Code: fmt.Sprintf("%.0f", opid), Message: fmt.Sprintf("%v", e)})
			respond(500, resource, respWriter, request)
		}
		ctx.Channels.Log <- mig.Log{OpID: opid, Desc: "leaving getAgentManifest()"}.Debug()
	}()
	err := request.ParseForm()
	if err != nil {
		panic(err)
	}

	ctx.Channels.Log <- mig.Log{OpID: opid, Desc: "Received manifest request"}.Debug()

	var manifestParam mig.ManifestParameters
	err = json.Unmarshal([]byte(request.FormValue("parameters")), &manifestParam)
	if err != nil {
		panic(err)
	}
	err = manifestParam.Validate()
	if err != nil {
		panic(err)
	}

	loaderid := getLoaderID(request)
	if loaderid == 0 {
		panic("Request has no valid loader ID")
	}

	// Update the loader entry with the parameters, and locate a valid manifest
	mf, err := locateManifestFromLoader(loaderid, manifestParam.AgentIdentifier)
	if err != nil {
		panic(err)
	}
	m, err := mf.ManifestResponse()
	if err != nil {
		panic(err)
	}

	// Send the manifest to the loader
	err = resource.AddItem(cljs.Item{
		Href: request.URL.String(),
		Data: []cljs.Data{
			{
				Name:  "manifest",
				Value: m,
			},
		}})
	if err != nil {
		panic(err)
	}
	respond(200, resource, respWriter, request)
}

func manifestRecordToItem(mr mig.ManifestRecord, ctx Context) (item cljs.Item, err error) {
	item.Href = fmt.Sprintf("%s/manifest?manifestid=%.0f", ctx.Server.BaseURL, mr.ID)
	item.Data = []cljs.Data{
		{Name: "manifest", Value: mr},
	}
	return
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"go/format"
	"io/ioutil"
	"log"
	"os"
	"strings"
)

var (
	packageName = flag.String("package", "main", "(Optional) Name of the package.")
	types       = flag.String("types", "", "Comma-separated list of type names, eg. 'int,string,CustomType'. The values can themselves be colon (:) separated to specify the names of entities in the generated, eg: int:I,string:Str,CustomType:CT.")
	testrun     = flag.Bool("test", false, "whether to display the generated code instead of writing out to a file.")
)

func usage() {
	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
	fmt.Fprintf(os.Stderr, "\tgen -package packageName -types Types\n")
	fmt.Fprintf(os.Stderr, "Example:\n")
	fmt.Fprintf(os.Stderr, "'gen -package mypackage -types string,int,customType,AnotherType' will create types 'stringList []string, intList []int, customTypeList []customType, AnotherTypeList []AnotherType' with the Map, Filter, Reduce, ReduceRight, Take, TakeWhile, Drop, DropWhile, Each, EachI methods on them. Additionally, methods named MapType1Type2 will be generated on these types for the remaining types. The package of the generated file will be 'mypackage' \n\n")
	fmt.Fprintf(os.Stderr, "'gen -types string,int:I,customType:CT,AnotherType:At' will create types 'stringList []string, IList []int, CTList []customType, AtList []AnotherType'. The 'stringList' type will have the Map, Filter, Reduce, ReduceRight, Take, TakeWhile, Drop, DropWhile, Each, EachI methods on it. Additionally, it will also have MapI, MapCt and MapAt methods. The package of the generated file will be 'main' \n\n")

	fmt.Fprintf(os.Stderr, "Flags:\n")
	flag.PrintDefaults()
}

func main() {
	flag.Usage = usage
	flag.Parse()

	if len(*types) == 0 {
		flag.Usage()
		os.Exit(2)
	}

	outputName := "fungen_auto.go"

	src := fmt.Sprintf(`// generated by fungen; DO NOT EDIT
            package %[1]s

            import "sync"

            `, *packageName)

	typeMap := getTypeMap(*types)

	for k1, v1 := range typeMap {
		src += generate(k1, v1+"List", typeMap)
		src = f(src)
	}

	if *testrun {
		fmt.Println(outputName)
		fmt.Println(src)
	} else {
		err := ioutil.WriteFile(outputName, []byte(src), 0644)
		if err != nil {
			log.Fatalf("writing output: %s", err)
		}
	}

}

func f(s string) string {
	formatted, err := format.Source([]byte(s))
	if err != nil {
		log.Fatal(err)
	}
	return string(formatted)
}

func getFileNameForTypes(t string, m map[string]string) string {
	if len(m) == 0 {
		return t
	}
	s := t
	for k, v := range m {
		if t == k {
			continue
		}
		s += "_" + v
	}
	return s
}

func getTypeMap(targets string) map[string]string {
	m := map[string]string{}
	if targets == "" {
		return m
	}

	targetParts := strings.Split(targets, ",")
	for _, t := range targetParts {
		tParts := strings.Split(t, ":")
		if len(tParts) == 1 {
			m[tParts[0]] = tParts[0]
		} else {
			m[tParts[0]] = tParts[1]
		}
	}

	return m
}

func generate(typeName, listname string, m map[string]string) string {
	code := ""
	code = fmt.Sprintf(`

            // %[2]s is the type for a list that holds members of type %[1]s
            type %[2]s []%[1]s
            `, typeName, listname)

	for k, v := range m {
		if k == typeName {
			code += getMapFunction(listname, typeName, k, "")
			code += getPMapFunction(listname, typeName, k, "")
		} else {
			code += getMapFunction(listname, typeName, k, v)
			code += getPMapFunction(listname, typeName, k, v)
		}

	}

	code += getFilterFunction(listname, typeName)
	code += getPFilterFunction(listname, typeName)
	code += getReduceFunction(listname, typeName)
	code += getReduceRightFunction(listname, typeName)
	code += getTakeFunction(listname, typeName)
	code += getTakeWhileFunction(listname, typeName)
	code += getDropFunction(listname, typeName)
	code += getDropWhileFunction(listname, typeName)
	code += getEachFunction(listname, typeName)
	code += getEachIFunction(listname, typeName)

	return code
}

func getMapFunction(listName, typeName, targetType, targetTypeName string) string {
	targetListName := targetType + "List"
	if targetTypeName == "" {
		targetListName = listName
	}

	return fmt.Sprintf(`
        // Map%[4]s is a method on %[1]s that takes a function of type %[2]s -> %[3]s and applies it to every member of %[1]s
        func (l %[1]s) Map%[4]s(f func(%[2]s) %[3]s) %[5]s {
            l2 := make(%[5]s, len(l))
            for i, t := range l {
                l2[i] = f(t)
            }
            return l2
        }
        `, listName, typeName, targetType, strings.Title(targetTypeName), targetListName)

}

func getPMapFunction(listName, typeName, targetType, targetTypeName string) string {
	targetListName := targetType + "List"
	if targetTypeName == "" {
		targetListName = listName
	}

	return fmt.Sprintf(`
        // PMap%[4]s is similar to Map%[4]s except that it executes the function on each member in parallel.
        func (l %[1]s) PMap%[4]s(f func(%[2]s) %[3]s) %[5]s {
            wg := sync.WaitGroup{}
            l2 := make(%[5]s, len(l))
            for i, t := range l {
                wg.Add(1)
                go func(i int, t %[2]s){
                    l2[i] = f(t)
                    wg.Done()
                }(i, t)
            }
            wg.Wait()
            return l2
        }
        `, listName, typeName, targetType, strings.Title(targetTypeName), targetListName)

}

func getFilterFunction(listName, typeName string) string {
	return fmt.Sprintf(`
        // Filter is a method on %[1]s that takes a function of type %[2]s -> bool returns a list of type %[1]s which contains all members from the original list for which the function returned true
        func (l %[1]s) Filter(f func(%[2]s) bool) %[1]s {
            l2 := []%[2]s{}
            for _, t := range l {
                if f(t) {
                    l2 = append(l2, t)
                }
            }
            return l2
        }
        `, listName, typeName)
}

func getPFilterFunction(listName, typeName string) string {
	return fmt.Sprintf(`
        // PFilter is similar to the Filter method except that the filter is applied to all the elements in parallel. The order of resulting elements cannot be guaranteed.
        func (l %[1]s) PFilter(f func(%[2]s) bool) %[1]s {
            wg := sync.WaitGroup{}
            mutex := sync.Mutex{}
            l2 := []%[2]s{}
            for _, t := range l {
                wg.Add(1)
                go func(t %[2]s){
                    if f(t) {
                        mutex.Lock()
                        l2 = append(l2, t)
                        mutex.Unlock()
                    }
                    wg.Done()
                }(t)
            }
            wg.Wait()
            return l2
        }
        `, listName, typeName)
}

func getEachFunction(listName, typeName string) string {
	return fmt.Sprintf(`
        // Each is a method on %[1]s that takes a function of type %[2]s -> void and applies the function to each member of the list and then returns the original list.
        func (l %[1]s) Each(f func(%[2]s)) %[1]s {
            for _, t := range l {
                f(t)
            }
            return l
        }
        `, listName, typeName)
}

func getEachIFunction(listName, typeName string) string {
	return fmt.Sprintf(`
        // EachI is a method on %[1]s that takes a function of type (int, %[2]s) -> void and applies the function to each member of the list and then returns the original list. The int parameter to the function is the index of the element.
        func (l %[1]s) EachI(f func(int, %[2]s)) %[1]s {
            for i, t := range l {
                f(i, t)
            }
            return l
        }
        `, listName, typeName)
}

func getDropWhileFunction(listName, typeName string) string {
	return fmt.Sprintf(`
        // DropWhile is a method on %[1]s that takes a function of type %[2]s -> bool and returns a list of type %[1]s which excludes the first members from the original list for which the function returned true
        func (l %[1]s) DropWhile(f func(%[2]s) bool) %[1]s {
            for i, t := range l {
                if !f(t) {
                    return l[i:]
                }
            }
            var l2 %[1]s
            return l2
        }
        `, listName, typeName)
}

func getTakeWhileFunction(listName, typeName string) string {
	return fmt.Sprintf(`
        // TakeWhile is a method on %[1]s that takes a function of type %[2]s -> bool and returns a list of type %[1]s which includes only the first members from the original list for which the function returned true
        func (l %[1]s) TakeWhile(f func(%[2]s) bool) %[1]s {
            for i, t := range l {
                if !f(t) {
                    return l[:i]
                }
            }
            return l
        }
        `, listName, typeName)
}

func getTakeFunction(listName, typeName string) string {
	return fmt.Sprintf(`
        // Take is a method on %[1]s that takes an integer n and returns the first n elements of the original list. If the list contains fewer than n elements then the entire list is returned.
        func (l %[1]s) Take(n int) %[1]s {
            if len(l) >= n {
                return l[:n]
            }
            return l
        }
        `, listName, typeName)
}

func getDropFunction(listName, typeName string) string {
	return fmt.Sprintf(`
        // Drop is a method on %[1]s that takes an integer n and returns all but the first n elements of the original list. If the list contains fewer than n elements then an empty list is returned.
        func (l %[1]s) Drop(n int) %[1]s {
            if len(l) >= n {
                return l[n:]
            }
            var l2 %[1]s
            return l2
        }
        `, listName, typeName)
}

func getReduceFunction(listName, typename string) string {
	return fmt.Sprintf(`
        // Reduce is a method on %[1]s that takes a function of type (%[2]s, %[2]s) -> %[2]s and returns a %[2]s which is the result of applying the function to all members of the original list starting from the first member
        func (l %[1]s) Reduce(t1 %[2]s, f func(%[2]s, %[2]s) %[2]s) %[2]s {
            for _, t := range l {
                t1 = f(t1, t)
            }
            return t1
        }
        `, listName, typename)
}

func getReduceRightFunction(listName, typename string) string {
	return fmt.Sprintf(`
        // ReduceRight is a method on %[1]s that takes a function of type (%[2]s, %[2]s) -> %[2]s and returns a %[2]s which is the result of applying the function to all members of the original list starting from the last member
        func (l %[1]s) ReduceRight(t1 %[2]s, f func(%[2]s, %[2]s) %[2]s) %[2]s {
            for i := len(l) - 1; i >= 0; i-- {
                t := l[i]
                t1 = f(t, t1)
            }
            return t1
        }
        `, listName, typename)
}
<commit_msg>Added -filename option for set custom file name<commit_after>package main

import (
	"flag"
	"fmt"
	"go/format"
	"io/ioutil"
	"log"
	"os"
	"strings"
)

var (
	packageName = flag.String("package", "main", "(Optional) Name of the package.")
	types       = flag.String("types", "", "Comma-separated list of type names, eg. 'int,string,CustomType'. The values can themselves be colon (:) separated to specify the names of entities in the generated, eg: int:I,string:Str,CustomType:CT.")
	outputName  = flag.String("filename", "fungen_auto.go", "Filename for generated package")
	testrun     = flag.Bool("test", false, "whether to display the generated code instead of writing out to a file.")
)

func usage() {
	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
	fmt.Fprintf(os.Stderr, "\tgen -package packageName -types Types\n")
	fmt.Fprintf(os.Stderr, "Example:\n")
	fmt.Fprintf(os.Stderr, "'gen -package mypackage -types string,int,customType,AnotherType' will create types 'stringList []string, intList []int, customTypeList []customType, AnotherTypeList []AnotherType' with the Map, Filter, Reduce, ReduceRight, Take, TakeWhile, Drop, DropWhile, Each, EachI methods on them. Additionally, methods named MapType1Type2 will be generated on these types for the remaining types. The package of the generated file will be 'mypackage' \n\n")
	fmt.Fprintf(os.Stderr, "'gen -types string,int:I,customType:CT,AnotherType:At' will create types 'stringList []string, IList []int, CTList []customType, AtList []AnotherType'. The 'stringList' type will have the Map, Filter, Reduce, ReduceRight, Take, TakeWhile, Drop, DropWhile, Each, EachI methods on it. Additionally, it will also have MapI, MapCt and MapAt methods. The package of the generated file will be 'main' \n\n")

	fmt.Fprintf(os.Stderr, "Flags:\n")
	flag.PrintDefaults()
}

func main() {
	flag.Usage = usage
	flag.Parse()

	if len(*types) == 0 {
		flag.Usage()
		os.Exit(2)
	}

	src := fmt.Sprintf(`// generated by fungen; DO NOT EDIT
            package %[1]s

            import "sync"

            `, *packageName)

	typeMap := getTypeMap(*types)

	for k1, v1 := range typeMap {
		src += generate(k1, v1+"List", typeMap)
		src = f(src)
	}

	if *testrun {
		fmt.Println(*outputName)
		fmt.Println(src)
	} else {
		err := ioutil.WriteFile(*outputName, []byte(src), 0644)
		if err != nil {
			log.Fatalf("writing output: %s", err)
		}
	}

}

func f(s string) string {
	formatted, err := format.Source([]byte(s))
	if err != nil {
		log.Fatal(err)
	}
	return string(formatted)
}

func getFileNameForTypes(t string, m map[string]string) string {
	if len(m) == 0 {
		return t
	}
	s := t
	for k, v := range m {
		if t == k {
			continue
		}
		s += "_" + v
	}
	return s
}

func getTypeMap(targets string) map[string]string {
	m := map[string]string{}
	if targets == "" {
		return m
	}

	targetParts := strings.Split(targets, ",")
	for _, t := range targetParts {
		tParts := strings.Split(t, ":")
		if len(tParts) == 1 {
			m[tParts[0]] = tParts[0]
		} else {
			m[tParts[0]] = tParts[1]
		}
	}

	return m
}

func generate(typeName, listname string, m map[string]string) string {
	code := ""
	code = fmt.Sprintf(`

            // %[2]s is the type for a list that holds members of type %[1]s
            type %[2]s []%[1]s
            `, typeName, listname)

	for k, v := range m {
		if k == typeName {
			code += getMapFunction(listname, typeName, k, "")
			code += getPMapFunction(listname, typeName, k, "")
		} else {
			code += getMapFunction(listname, typeName, k, v)
			code += getPMapFunction(listname, typeName, k, v)
		}

	}

	code += getFilterFunction(listname, typeName)
	code += getPFilterFunction(listname, typeName)
	code += getReduceFunction(listname, typeName)
	code += getReduceRightFunction(listname, typeName)
	code += getTakeFunction(listname, typeName)
	code += getTakeWhileFunction(listname, typeName)
	code += getDropFunction(listname, typeName)
	code += getDropWhileFunction(listname, typeName)
	code += getEachFunction(listname, typeName)
	code += getEachIFunction(listname, typeName)

	return code
}

func getMapFunction(listName, typeName, targetType, targetTypeName string) string {
	targetListName := targetType + "List"
	if targetTypeName == "" {
		targetListName = listName
	}

	return fmt.Sprintf(`
        // Map%[4]s is a method on %[1]s that takes a function of type %[2]s -> %[3]s and applies it to every member of %[1]s
        func (l %[1]s) Map%[4]s(f func(%[2]s) %[3]s) %[5]s {
            l2 := make(%[5]s, len(l))
            for i, t := range l {
                l2[i] = f(t)
            }
            return l2
        }
        `, listName, typeName, targetType, strings.Title(targetTypeName), targetListName)

}

func getPMapFunction(listName, typeName, targetType, targetTypeName string) string {
	targetListName := targetType + "List"
	if targetTypeName == "" {
		targetListName = listName
	}

	return fmt.Sprintf(`
        // PMap%[4]s is similar to Map%[4]s except that it executes the function on each member in parallel.
        func (l %[1]s) PMap%[4]s(f func(%[2]s) %[3]s) %[5]s {
            wg := sync.WaitGroup{}
            l2 := make(%[5]s, len(l))
            for i, t := range l {
                wg.Add(1)
                go func(i int, t %[2]s){
                    l2[i] = f(t)
                    wg.Done()
                }(i, t)
            }
            wg.Wait()
            return l2
        }
        `, listName, typeName, targetType, strings.Title(targetTypeName), targetListName)

}

func getFilterFunction(listName, typeName string) string {
	return fmt.Sprintf(`
        // Filter is a method on %[1]s that takes a function of type %[2]s -> bool returns a list of type %[1]s which contains all members from the original list for which the function returned true
        func (l %[1]s) Filter(f func(%[2]s) bool) %[1]s {
            l2 := []%[2]s{}
            for _, t := range l {
                if f(t) {
                    l2 = append(l2, t)
                }
            }
            return l2
        }
        `, listName, typeName)
}

func getPFilterFunction(listName, typeName string) string {
	return fmt.Sprintf(`
        // PFilter is similar to the Filter method except that the filter is applied to all the elements in parallel. The order of resulting elements cannot be guaranteed.
        func (l %[1]s) PFilter(f func(%[2]s) bool) %[1]s {
            wg := sync.WaitGroup{}
            mutex := sync.Mutex{}
            l2 := []%[2]s{}
            for _, t := range l {
                wg.Add(1)
                go func(t %[2]s){
                    if f(t) {
                        mutex.Lock()
                        l2 = append(l2, t)
                        mutex.Unlock()
                    }
                    wg.Done()
                }(t)
            }
            wg.Wait()
            return l2
        }
        `, listName, typeName)
}

func getEachFunction(listName, typeName string) string {
	return fmt.Sprintf(`
        // Each is a method on %[1]s that takes a function of type %[2]s -> void and applies the function to each member of the list and then returns the original list.
        func (l %[1]s) Each(f func(%[2]s)) %[1]s {
            for _, t := range l {
                f(t)
            }
            return l
        }
        `, listName, typeName)
}

func getEachIFunction(listName, typeName string) string {
	return fmt.Sprintf(`
        // EachI is a method on %[1]s that takes a function of type (int, %[2]s) -> void and applies the function to each member of the list and then returns the original list. The int parameter to the function is the index of the element.
        func (l %[1]s) EachI(f func(int, %[2]s)) %[1]s {
            for i, t := range l {
                f(i, t)
            }
            return l
        }
        `, listName, typeName)
}

func getDropWhileFunction(listName, typeName string) string {
	return fmt.Sprintf(`
        // DropWhile is a method on %[1]s that takes a function of type %[2]s -> bool and returns a list of type %[1]s which excludes the first members from the original list for which the function returned true
        func (l %[1]s) DropWhile(f func(%[2]s) bool) %[1]s {
            for i, t := range l {
                if !f(t) {
                    return l[i:]
                }
            }
            var l2 %[1]s
            return l2
        }
        `, listName, typeName)
}

func getTakeWhileFunction(listName, typeName string) string {
	return fmt.Sprintf(`
        // TakeWhile is a method on %[1]s that takes a function of type %[2]s -> bool and returns a list of type %[1]s which includes only the first members from the original list for which the function returned true
        func (l %[1]s) TakeWhile(f func(%[2]s) bool) %[1]s {
            for i, t := range l {
                if !f(t) {
                    return l[:i]
                }
            }
            return l
        }
        `, listName, typeName)
}

func getTakeFunction(listName, typeName string) string {
	return fmt.Sprintf(`
        // Take is a method on %[1]s that takes an integer n and returns the first n elements of the original list. If the list contains fewer than n elements then the entire list is returned.
        func (l %[1]s) Take(n int) %[1]s {
            if len(l) >= n {
                return l[:n]
            }
            return l
        }
        `, listName, typeName)
}

func getDropFunction(listName, typeName string) string {
	return fmt.Sprintf(`
        // Drop is a method on %[1]s that takes an integer n and returns all but the first n elements of the original list. If the list contains fewer than n elements then an empty list is returned.
        func (l %[1]s) Drop(n int) %[1]s {
            if len(l) >= n {
                return l[n:]
            }
            var l2 %[1]s
            return l2
        }
        `, listName, typeName)
}

func getReduceFunction(listName, typename string) string {
	return fmt.Sprintf(`
        // Reduce is a method on %[1]s that takes a function of type (%[2]s, %[2]s) -> %[2]s and returns a %[2]s which is the result of applying the function to all members of the original list starting from the first member
        func (l %[1]s) Reduce(t1 %[2]s, f func(%[2]s, %[2]s) %[2]s) %[2]s {
            for _, t := range l {
                t1 = f(t1, t)
            }
            return t1
        }
        `, listName, typename)
}

func getReduceRightFunction(listName, typename string) string {
	return fmt.Sprintf(`
        // ReduceRight is a method on %[1]s that takes a function of type (%[2]s, %[2]s) -> %[2]s and returns a %[2]s which is the result of applying the function to all members of the original list starting from the last member
        func (l %[1]s) ReduceRight(t1 %[2]s, f func(%[2]s, %[2]s) %[2]s) %[2]s {
            for i := len(l) - 1; i >= 0; i-- {
                t := l[i]
                t1 = f(t, t1)
            }
            return t1
        }
        `, listName, typename)
}
<|endoftext|>


<commit_before>package martini

import (
	"net/http"
)

type Router interface {
	Get(string, ...Handler)
	Post(string, ...Handler)
	Put(string, ...Handler)
	Delete(string, ...Handler)

	Handle(http.ResponseWriter, *http.Request, Context)
}

type router struct {
	routes []route
}

func NewRouter() Router {
	return &router{}
}

func (r *router) Get(pattern string, h ...Handler) {
	r.addRoute("GET", pattern, h)
}

func (r *router) Post(pattern string, h ...Handler) {
	r.addRoute("POST", pattern, h)
}

func (r *router) Put(pattern string, h ...Handler) {
	r.addRoute("PUT", pattern, h)
}

func (r *router) Delete(pattern string, h ...Handler) {
	r.addRoute("DELETE", pattern, h)
}

func (r *router) Handle(res http.ResponseWriter, req *http.Request, context Context) {
	for _, route := range r.routes {
		// Be super strict for now. Eventually we will have some
		// super awesome pattern matching here. But not today
		if route.method == req.Method && req.URL.Path == route.pattern {
			err := context.Invoke(route.handle)
			if err != nil {
				panic(err)
			}
			return
		}
	}
}

func (r *router) addRoute(method string, pattern string, handlers []Handler) {
  // todo validate handlers
	r.routes = append(r.routes, route{method, pattern, handlers})
}

type route struct {
	method  string
	pattern string
	handlers []Handler
}

func (r route) handle(c Context) {
  for _, handler := range r.handlers {
    err := c.Invoke(handler)
    if err != nil {
      panic(err)
    }
  }
}
<commit_msg>JMS #2: Handler validation for route handlers<commit_after>package martini

import (
	"net/http"
)

type Router interface {
	Get(string, ...Handler)
	Post(string, ...Handler)
	Put(string, ...Handler)
	Delete(string, ...Handler)

	Handle(http.ResponseWriter, *http.Request, Context)
}

type router struct {
	routes []route
}

func NewRouter() Router {
	return &router{}
}

func (r *router) Get(pattern string, h ...Handler) {
	r.addRoute("GET", pattern, h)
}

func (r *router) Post(pattern string, h ...Handler) {
	r.addRoute("POST", pattern, h)
}

func (r *router) Put(pattern string, h ...Handler) {
	r.addRoute("PUT", pattern, h)
}

func (r *router) Delete(pattern string, h ...Handler) {
	r.addRoute("DELETE", pattern, h)
}

func (r *router) Handle(res http.ResponseWriter, req *http.Request, context Context) {
	for _, route := range r.routes {
		// Be super strict for now. Eventually we will have some
		// super awesome pattern matching here. But not today
		if route.method == req.Method && req.URL.Path == route.pattern {
			err := context.Invoke(route.handle)
			if err != nil {
				panic(err)
			}
			return
		}
	}
}

func (r *router) addRoute(method string, pattern string, handlers []Handler) {
	route := route{method, pattern, handlers}
	if route.validate() == nil {
		r.routes = append(r.routes, route)
	}
}

type route struct {
	method   string
	pattern  string
	handlers []Handler
}

func (r route) validate() error {
	for _, handler := range r.handlers {
		err := validateHandler(handler)
		if err != nil {
			return err
		}
	}
	return nil
}

func (r route) handle(c Context) {
	for _, handler := range r.handlers {
		err := c.Invoke(handler)
		if err != nil {
			panic(err)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	_ "github.com/mattn/go-sqlite3"

	"github.com/Masterminds/squirrel"
	"github.com/jmoiron/sqlx"
	"gopkg.in/alecthomas/kingpin.v2"
)

// CountBuilder is a squirrel select builder whose columns match Count fields.
var CountBuilder = squirrel.Select().
	Column(squirrel.Alias(squirrel.Expr("LENGTH(sequence)"), "len")).
	Column(squirrel.Alias(squirrel.Expr("COUNT(*)"), "count")).
	Column(squirrel.Alias(squirrel.Expr("SUM(copy_number)"), "copyNum")).
	GroupBy("len").OrderBy("len")

// Count is a databases row with record count information.
type Count struct {
	SeqLen  int `db:"len"`
	Count   int `db:"count"`
	CopyNum int `db:"copyNum"`
}

const prog = "htsdb-size-distro"
const version = "0.1"
const descr = `Print the number of reads and read copies for each read size.
Provided SQL filter will apply to all counts.`

var (
	app = kingpin.New(prog, descr)

	dbFile = app.Flag("db", "File to SQLite database.").
		PlaceHolder("<file>").Required().String()
	tab = app.Flag("table", "Database table name.").
		Default("sample").String()
	where = app.Flag("where", "SQL filter to inject in WHERE clause.").
		PlaceHolder("<SQL>").String()
	as = app.Flag("as", "Name to print describing the count/s.").
		Default("all").String()
	header = app.Flag("header", "Print header line.").
		Bool()
)

func main() {
	// read command line args and options
	app.HelpFlag.Short('h')
	app.Version(version)
	_, err := app.Parse(os.Args[1:])
	if err != nil {
		kingpin.Fatalf("%s", err)
	}

	// assemble sqlx select builders
	countBuilder := CountBuilder.From(*tab)
	if *where != "" {
		countBuilder = countBuilder.Where(*where)
	}

	// open database connections.
	var db *sqlx.DB
	if db, err = sqlx.Connect("sqlite3", *dbFile); err != nil {
		panic(err)
	}

	// prepare statements.
	query, _, err := countBuilder.ToSql()
	if err != nil {
		panic(err)
	}

	// get the count
	var counts []Count
	if err = db.Select(&counts, query); err != nil {
		panic(err)
	}

	// print results.
	if *header == true {
		fmt.Printf("category\tlen\tcount\tcopyNumber\n")
	}
	idx := 0
	for _, c := range counts {
		for c.SeqLen > idx {
			fmt.Printf("%s\t%d\t%d\t%d\n", *as, idx, 0, 0)
			idx++
		}
		idx = c.SeqLen + 1
		fmt.Printf("%s\t%d\t%d\t%d\n", *as, c.SeqLen, c.Count, c.CopyNum)
	}
}
<commit_msg>htsdb-size-distro: new option to use alignment length<commit_after>package main

import (
	"fmt"
	"os"

	_ "github.com/mattn/go-sqlite3"

	"github.com/Masterminds/squirrel"
	"github.com/jmoiron/sqlx"
	"gopkg.in/alecthomas/kingpin.v2"
)

// CountBuilder is a squirrel select builder whose columns match Count fields.
var CountBuilder = squirrel.Select().
	Column(squirrel.Alias(squirrel.Expr("LENGTH(sequence)"), "len")).
	Column(squirrel.Alias(squirrel.Expr("COUNT(*)"), "count")).
	Column(squirrel.Alias(squirrel.Expr("SUM(copy_number)"), "copyNum")).
	GroupBy("len").OrderBy("len")

// AlignLenBuilder is a squirrel select builder that describes a query for the
// alignment length and whose columns match the fields of Count.
var AlignLenBuilder = squirrel.Select().
	Column(squirrel.Alias(squirrel.Expr("stop - start + 1"), "len")).
	Column(squirrel.Alias(squirrel.Expr("COUNT(*)"), "count")).
	Column(squirrel.Alias(squirrel.Expr("SUM(copy_number)"), "copyNum")).
	GroupBy("len").OrderBy("len")

// Count is a databases row with record count information.
type Count struct {
	SeqLen  int `db:"len"`
	Count   int `db:"count"`
	CopyNum int `db:"copyNum"`
}

const prog = "htsdb-size-distro"
const version = "0.2"
const descr = `Print the number of reads and read copies for each read/alignment size.
Provided SQL filter will apply to all counts.`

var (
	app = kingpin.New(prog, descr)

	dbFile = app.Flag("db", "File to SQLite database.").
		PlaceHolder("<file>").Required().String()
	tab = app.Flag("table", "Database table name.").
		Default("sample").String()
	where = app.Flag("where", "SQL filter to inject in WHERE clause.").
		PlaceHolder("<SQL>").String()
	as = app.Flag("as", "Name to print describing the count/s.").
		Default("all").String()
	header = app.Flag("header", "Print header line.").
		Bool()
	alignLen = app.Flag("align-len", "Use alignment length instead of read length.").
			Bool()
)

func main() {
	// read command line args and options
	app.HelpFlag.Short('h')
	app.Version(version)
	_, err := app.Parse(os.Args[1:])
	if err != nil {
		kingpin.Fatalf("%s", err)
	}

	// assemble sqlx select builders
	countBuilder := CountBuilder.From(*tab)
	if *alignLen == true {
		countBuilder = AlignLenBuilder.From(*tab)
	}
	if *where != "" {
		countBuilder = countBuilder.Where(*where)
	}

	// open database connections.
	var db *sqlx.DB
	if db, err = sqlx.Connect("sqlite3", *dbFile); err != nil {
		panic(err)
	}

	// prepare statements.
	query, _, err := countBuilder.ToSql()
	if err != nil {
		panic(err)
	}

	// get the count
	var counts []Count
	if err = db.Select(&counts, query); err != nil {
		panic(err)
	}

	// print results.
	if *header == true {
		fmt.Printf("category\tlen\tcount\tcopyNumber\n")
	}
	idx := 0
	for _, c := range counts {
		for c.SeqLen > idx {
			fmt.Printf("%s\t%d\t%d\t%d\n", *as, idx, 0, 0)
			idx++
		}
		idx = c.SeqLen + 1
		fmt.Printf("%s\t%d\t%d\t%d\n", *as, c.SeqLen, c.Count, c.CopyNum)
	}
}
<|endoftext|>


<commit_before>package goxp

import (
	"fmt"
	"net/http"
	"reflect"
	"regxp"
	"strconv"
	"sync"
)

// Params is a map of name/value pairs for named routes. An instance of goxp.Params is available to be injected into any route handler.
type Params map[string]string

// Router is GoXp's de-facto interface. Supports HTTP verbs, stacked handlers, and dependency injection
// Idea is to use booster rather than injection
type Router interface {
	Routes

	// Group adds a group where related routes can be added.
	Group(string, func(Router), ...Handler)
	// Get adds a route for a HTTP GET request to the specified mathcing pattern.
	Get(string, ...Handler) Route
	// Patch adds a route for a HTTP PATCH request to the specified matching pattern.
	Patch(string, ...Handler) Route
	// Post adds a route for a HTTP POST request to the specified matching pattern.
	Post(string, ...Handler) Route
	// Put adds a route for a HTTP Put request to the specified matching pattern.
	Put(string, ...Handler) Route
	// Delete adds a route for a HTTP DELETE request to the specified matching pattern.
	Delete(string, ...Handler) Route
	// Options adds a route for HTTP OPTIONS request to the specified matching pattern.
	Options(string, ...Handler) Route
	// Head adds a route for HTTP HEAD request to the specified matching pattern.
	Head(string, ...Handler) Route
	// Any adds a route for a HTTP method request to the specified matching pattern.
	Any(string, ...Handler) Route
	// AddRoute adds a route for a given HTTP method request to the specified matching pattern.
	AddRoute(string, string, ...Handler) Route

	// NotFound sets the handlers that are called when a no route matches a request. Throws a basic 404 by default.
	NotFound(...Handler)

	// Handle is the entry point for routing. This is used as a goxp.Handler
	Handle(http.ResponseWriter, *http.Request, Context)
}

type router struct {
	routes     []*route
	notFounds  []Handler
	groups     []group
	routesLock sync.RWMutex
}

type group struct {
	pattern  string
	handlers []Handler
}

// NewRouter creates a new Router instance.
// If you aren't using ClassicGoXp, then you can add Routes as a
// service with:
//
//     m := goxp.New()
//     r := goxp.NewRouter()
//     m.MapTo(r, (*goxp.Routes)(nil))
//
// If you are using ClassicGoXp, then this is done for you.
func NewRouter() Router {
	return &router{notFounds: []Handler{http.NotFound}, groups: make([]group, 0)}
}

func (r *router) Group(pattern string, fn func(Router), h ...Handler) {
	r.groups = append(r.groups, group{pattern, h})
	fn(r)
	r.groups = r.groups[:len(r.groups)-1]
}

func (r *router) Get(pattern string, h ...Handler) Route {
	return r.addRoute("GET", pattern, h)
}

func (r *router) Patch(pattern string, h ...Handler) Route {
	return r.addRoute("PATCH", pattern, h)
}

func (r *router) Post(pattern string, h ...Handler) Router {
	return r.addRoute("POST", pattern, h)
}

func (r *router) Put(pattern string, h ...Handler) Router {
	return r.addRoute("PUT", pattern, h)
}

func (r *router) Delete(pattern string, h ...Handler) Route {
	return r.addRoute("DELETE", pattern, h)
}

func (r *router) Options(pattern string, h ...Handler) Route {
	return r.addRoute("OPTIONS", pattern, h)
}
<commit_msg>router.go +func Head<commit_after>package goxp

import (
	"fmt"
	"net/http"
	"reflect"
	"regxp"
	"strconv"
	"sync"
)

// Params is a map of name/value pairs for named routes. An instance of goxp.Params is available to be injected into any route handler.
type Params map[string]string

// Router is GoXp's de-facto interface. Supports HTTP verbs, stacked handlers, and dependency injection
// Idea is to use booster rather than injection
type Router interface {
	Routes

	// Group adds a group where related routes can be added.
	Group(string, func(Router), ...Handler)
	// Get adds a route for a HTTP GET request to the specified mathcing pattern.
	Get(string, ...Handler) Route
	// Patch adds a route for a HTTP PATCH request to the specified matching pattern.
	Patch(string, ...Handler) Route
	// Post adds a route for a HTTP POST request to the specified matching pattern.
	Post(string, ...Handler) Route
	// Put adds a route for a HTTP Put request to the specified matching pattern.
	Put(string, ...Handler) Route
	// Delete adds a route for a HTTP DELETE request to the specified matching pattern.
	Delete(string, ...Handler) Route
	// Options adds a route for HTTP OPTIONS request to the specified matching pattern.
	Options(string, ...Handler) Route
	// Head adds a route for HTTP HEAD request to the specified matching pattern.
	Head(string, ...Handler) Route
	// Any adds a route for a HTTP method request to the specified matching pattern.
	Any(string, ...Handler) Route
	// AddRoute adds a route for a given HTTP method request to the specified matching pattern.
	AddRoute(string, string, ...Handler) Route

	// NotFound sets the handlers that are called when a no route matches a request. Throws a basic 404 by default.
	NotFound(...Handler)

	// Handle is the entry point for routing. This is used as a goxp.Handler
	Handle(http.ResponseWriter, *http.Request, Context)
}

type router struct {
	routes     []*route
	notFounds  []Handler
	groups     []group
	routesLock sync.RWMutex
}

type group struct {
	pattern  string
	handlers []Handler
}

// NewRouter creates a new Router instance.
// If you aren't using ClassicGoXp, then you can add Routes as a
// service with:
//
//     m := goxp.New()
//     r := goxp.NewRouter()
//     m.MapTo(r, (*goxp.Routes)(nil))
//
// If you are using ClassicGoXp, then this is done for you.
func NewRouter() Router {
	return &router{notFounds: []Handler{http.NotFound}, groups: make([]group, 0)}
}

func (r *router) Group(pattern string, fn func(Router), h ...Handler) {
	r.groups = append(r.groups, group{pattern, h})
	fn(r)
	r.groups = r.groups[:len(r.groups)-1]
}

func (r *router) Get(pattern string, h ...Handler) Route {
	return r.addRoute("GET", pattern, h)
}

func (r *router) Patch(pattern string, h ...Handler) Route {
	return r.addRoute("PATCH", pattern, h)
}

func (r *router) Post(pattern string, h ...Handler) Router {
	return r.addRoute("POST", pattern, h)
}

func (r *router) Put(pattern string, h ...Handler) Router {
	return r.addRoute("PUT", pattern, h)
}

func (r *router) Delete(pattern string, h ...Handler) Route {
	return r.addRoute("DELETE", pattern, h)
}

func (r *router) Options(pattern string, h ...Handler) Route {
	return r.addRoute("OPTIONS", pattern, h)
}

func (r *router) Head(pattern string, h ...Handler) Route {
	return r.addRoute("HEAD", pattern, h)
}

<|endoftext|>


<commit_before>// Copyright 2012, 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package commands

import (
	gc "gopkg.in/check.v1"

	cmdtesting "github.com/juju/juju/cmd/testing"
	"github.com/juju/juju/juju/testing"
	coretesting "github.com/juju/juju/testing"
)

func badrun(c *gc.C, exit int, args ...string) string {
	args = append([]string{"juju"}, args...)
	return cmdtesting.BadRun(c, exit, args...)
}

type CmdSuite struct {
	testing.JujuConnSuite
}

var _ = gc.Suite(&CmdSuite{})

func initSSHCommand(args ...string) (*sshCommand, error) {
	com := &sshCommand{}
	return com, coretesting.InitCommand(com, args)
}

func (*CmdSuite) TestSSHCommandInit(c *gc.C) {
	// missing args
	_, err := initSSHCommand()
	c.Assert(err, gc.ErrorMatches, "no target name specified")
}

func initSCPCommand(args ...string) (*scpCommand, error) {
	com := &scpCommand{}
	return com, coretesting.InitCommand(com, args)
}

func (*CmdSuite) TestSCPCommandInit(c *gc.C) {
	// missing args
	_, err := initSCPCommand()
	c.Assert(err, gc.ErrorMatches, "at least two arguments required")

	// not enough args
	_, err = initSCPCommand("mysql/0:foo")
	c.Assert(err, gc.ErrorMatches, "at least two arguments required")
}
<commit_msg>Replace JujuConnSuite with the minimal required test suite.<commit_after>// Copyright 2012, 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package commands

import (
	gc "gopkg.in/check.v1"

	"github.com/juju/testing"

	cmdtesting "github.com/juju/juju/cmd/testing"
	coretesting "github.com/juju/juju/testing"
)

func badrun(c *gc.C, exit int, args ...string) string {
	args = append([]string{"juju"}, args...)
	return cmdtesting.BadRun(c, exit, args...)
}

type CmdSuite struct {
	testing.IsolationSuite
}

var _ = gc.Suite(&CmdSuite{})

func initSSHCommand(args ...string) (*sshCommand, error) {
	com := &sshCommand{}
	return com, coretesting.InitCommand(com, args)
}

func (*CmdSuite) TestSSHCommandInit(c *gc.C) {
	// missing args
	_, err := initSSHCommand()
	c.Assert(err, gc.ErrorMatches, "no target name specified")
}

func initSCPCommand(args ...string) (*scpCommand, error) {
	com := &scpCommand{}
	return com, coretesting.InitCommand(com, args)
}

func (*CmdSuite) TestSCPCommandInit(c *gc.C) {
	// missing args
	_, err := initSCPCommand()
	c.Assert(err, gc.ErrorMatches, "at least two arguments required")

	// not enough args
	_, err = initSCPCommand("mysql/0:foo")
	c.Assert(err, gc.ErrorMatches, "at least two arguments required")
}
<|endoftext|>


<commit_before>package cmd

import (
	"github.com/spf13/cobra"
	"github.com/spf13/viper"

	log "github.com/Sirupsen/logrus"
)

// createCmd represents the create command
var createCmd = &cobra.Command{
	Use:   "create",
	Short: "Create a new note",
	Long:  `Add a new note to notable server`,
	Run: func(cmd *cobra.Command, args []string) {
		// TODO: Work your own magic here
		log.Debugf("Creating a note on %s", viper.GetString("server"))
	},
}

func init() {
	RootCmd.AddCommand(createCmd)
	createCmd.Flags().StringP("subject", "s", "", "Subject for the note")
	createCmd.Flags().StringP("tags", "t", "", "Tags to associate")
	createCmd.Flags().StringP("content", "c", "", "Content for the note")

	viper.BindPFlag("create.subject", createCmd.Flags().Lookup("subject"))
	viper.BindPFlag("create.tags", createCmd.Flags().Lookup("tags"))
	viper.BindPFlag("create.content", createCmd.Flags().Lookup("content"))
}
<commit_msg>Importing non-existing package<commit_after>package cmd

import (
	"github.com/spf13/cobra"
	"github.com/spf13/viper"

	log "github.com/Sirupsen/logrus"
	notable "github.com/jmcfarlane/notable/model"
)

// createCmd represents the create command
var createCmd = &cobra.Command{
	Use:   "create",
	Short: "Create a new note",
	Long:  `Add a new note to notable server`,
	Run: func(cmd *cobra.Command, args []string) {
		// TODO: Work your own magic here
		log.Debugf("Creating a note on %s", viper.GetString("server"))
		log.WithFields(log.Fields{
			"Subject": viper.GetString("create.subject"),
			"Tags":    viper.GetString("create.tags"),
			"Content": viper.GetString("create.content"),
		}).Debug("Provided values")

		var note model.Note{}
	},
}

func init() {
	RootCmd.AddCommand(createCmd)
	createCmd.Flags().StringP("subject", "s", "", "Subject for the note")
	createCmd.Flags().StringP("tags", "t", "", "Tags to associate")
	createCmd.Flags().StringP("content", "c", "", "Content for the note")

	viper.BindPFlag("create.subject", createCmd.Flags().Lookup("subject"))
	viper.BindPFlag("create.tags", createCmd.Flags().Lookup("tags"))
	viper.BindPFlag("create.content", createCmd.Flags().Lookup("content"))
}
<|endoftext|>


<commit_before>/*
	GAData is a library for retrieving Google Analytics API (v3) data
*/

package gadata

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"
)

// Base constants
const (
	DataEndpoint string = "https://www.googleapis.com/analytics/v3/data/ga"
	Limit        int    = 5 // max requests / sec guard
)

// GaRequest is the Google Analytics request structure
type GaRequest struct {
	Id         string `json:"ids"`
	StartDate  string `json:"start-date"`
	EndDate    string `json:"end-date"`
	Metrics    string `json:"metrics"`
	Dimensions string `json:"dimensions"`
	Filters    string `json:"filters"`
	Segments   string `json:"segment"`
	Sort       string `json:"sort"`
	MaxResults int    `json:"max-results"`
}

// clipEmpty removes empty keys from struct
// ...so bad
func clipEmpty(out *url.Values, key string) {
	if len(out.Get(key)) == 0 {
		out.Del(key)
	}
}

// ToURLValues converts struct to url.Values struct
func (a *GaRequest) ToURLValues() (out url.Values) {
	out = url.Values{"ids": {a.Id},
		"start-date":  {a.StartDate},
		"end-date":    {a.EndDate},
		"metrics":     {a.Metrics},
		"dimensions":  {a.Dimensions},
		"filters":     {a.Filters},
		"segment":     {a.Segments},
		"sort":        {a.Sort},
		"max-results": {strconv.Itoa(a.MaxResults)},
	}
	clipEmpty(&out, "filters")
	clipEmpty(&out, "segment")
	if len(a.Sort) == 0 {
		clipEmpty(&out, "sort")
	}

	return
}

// Initial returned response
type GaResponse struct {
	Data string
	Pos  int
}

// Processed GA response
type CleanResponse struct {
	Columns []struct {
		Name  string `json:"name"`
		CType string `json:"columnType"`
		DType string `json:"dataType"`
	} `json:"columnHeaders"`
	Total map[string]string `json:"totalsForAllResults"`
	Rows  [][]string        `json:"rows"`
}

func (rawResponse GaResponse) Process() (data CleanResponse, ok bool) {
	if err := json.Unmarshal([]byte(rawResponse.Data), &data); err == nil {
		ok = true
	} else {
		fmt.Printf(err.Error())
	}
	return
}

// GAData is the primary Google Analytics API pull structure
type GAData struct {
	Auth     *OauthData
	Request  *GaRequest
	Response *GaResponse
}

// Initialise the GAData connection, ready to make a new request
func (g *GAData) Init() {
	g.Auth = new(OauthData)
	g.Auth.InitConnection()
}

// GetData queries GA API endpoint, returns response
func (g *GAData) GetData(key int, request *GaRequest) *GaResponse {
	out := request.ToURLValues().Encode()
	client := &http.Client{}
	req, err := http.NewRequest("GET", fmt.Sprintf("%s?%s", DataEndpoint, out), nil)
	checkError(err)
	req.Header.Add("Authorization", "Bearer "+g.Auth.tokens.AccessToken)
	resp, err := client.Do(req)
	// resp, err := http.Get(fmt.Sprintf("%s?%s", DataEndpoint, out))
	checkError(err)
	defer resp.Body.Close()
	contents, err := ioutil.ReadAll(resp.Body)
	checkError(err)

	// pass the response
	response := new(GaResponse)
	response.Data = string(contents)
	response.Pos = key
	if strings.Contains(response.Data, "Invalid Credentials") {
		log.Printf(response.Data)
		if err = g.Auth.refreshToken(); err == nil {
			return g.GetData(key, request)
		}
	}
	return response
}

// BatchGet runs all queries in parellel and returns the results (or times out)
func (g *GAData) BatchGet(requests []*GaRequest) (responses []*CleanResponse, err error) {
	ch := make(chan *GaResponse)
	for a, b := range requests {
		// if we hit max requests limit / sec, sleep for 1 sec.
		if a%Limit == 0 {
			time.Sleep(1 * time.Second)
		}
		go func(x int, z *GaRequest) { ch <- g.GetData(x, z) }(a, b)
	}
	responses = make([]*CleanResponse, len(requests))
	for i := 0; i < len(requests); i++ {
		select {
		case result := <-ch:
			if out, ok := result.Process(); ok {
				responses[result.Pos] = &out
			}
		// 60 sec timeout
		case <-time.After(60 * time.Second):
			return
		}
	}

	return
}
<commit_msg>cleaned up batch querying and token refresh functionalities<commit_after>/*
	GAData is a library for retrieving Google Analytics API (v3) data
*/

package gadata

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"
)

// Base constants
const (
	DataEndpoint string = "https://www.googleapis.com/analytics/v3/data/ga"
	Limit        int    = 5 // max requests / sec guard
)

// GaRequest is the Google Analytics request structure
type GaRequest struct {
	Id         string `json:"ids"`
	StartDate  string `json:"start-date"`
	EndDate    string `json:"end-date"`
	Metrics    string `json:"metrics"`
	Dimensions string `json:"dimensions"`
	Filters    string `json:"filters"`
	Segments   string `json:"segment"`
	Sort       string `json:"sort"`
	MaxResults int    `json:"max-results"`
	Attempts   int
}

// clipEmpty removes empty keys from struct
// ...so bad
func clipEmpty(out *url.Values, key string) {
	if len(out.Get(key)) == 0 {
		out.Del(key)
	}
}

// ToURLValues converts struct to url.Values struct
func (a *GaRequest) ToURLValues() (out url.Values) {
	out = url.Values{"ids": {a.Id},
		"start-date":  {a.StartDate},
		"end-date":    {a.EndDate},
		"metrics":     {a.Metrics},
		"dimensions":  {a.Dimensions},
		"filters":     {a.Filters},
		"segment":     {a.Segments},
		"sort":        {a.Sort},
		"max-results": {strconv.Itoa(a.MaxResults)},
	}
	clipEmpty(&out, "filters")
	clipEmpty(&out, "segment")
	if len(a.Sort) == 0 {
		clipEmpty(&out, "sort")
	}

	return
}

// Initial returned response
type GaResponse struct {
	Data string
	Pos  int
}

// Processed GA response
type CleanResponse struct {
	Columns []struct {
		Name  string `json:"name"`
		CType string `json:"columnType"`
		DType string `json:"dataType"`
	} `json:"columnHeaders"`
	Total map[string]string `json:"totalsForAllResults"`
	Rows  [][]string        `json:"rows"`
}

func (rawResponse GaResponse) Process() (data CleanResponse, ok bool) {
	if err := json.Unmarshal([]byte(rawResponse.Data), &data); err == nil {
		ok = true
	} else {
		fmt.Printf(err.Error())
	}
	return
}

// GAData is the primary Google Analytics API pull structure
type GAData struct {
	Auth     *OauthData
	Request  *GaRequest
	Response *GaResponse
}

// Initialise the GAData connection, ready to make a new request
func (g *GAData) Init() {
	g.Auth = new(OauthData)
	g.Auth.InitConnection()
}

// GetData queries GA API endpoint, returns response
func (g *GAData) GetData(key int, request *GaRequest) *GaResponse {
	out := request.ToURLValues().Encode()
	client := &http.Client{}
	req, err := http.NewRequest("GET", fmt.Sprintf("%s?%s", DataEndpoint, out), nil)
	checkError(err)
	req.Header.Add("Authorization", "Bearer "+g.Auth.tokens.AccessToken)
	resp, err := client.Do(req)
	// resp, err := http.Get(fmt.Sprintf("%s?%s", DataEndpoint, out))
	checkError(err)
	defer resp.Body.Close()
	contents, err := ioutil.ReadAll(resp.Body)
	checkError(err)

	// pass the response
	response := new(GaResponse)
	response.Data = string(contents)
	response.Pos = key
	if strings.Contains(response.Data, "Invalid Credentials") {
		log.Printf(response.Data)
		if err = g.Auth.refreshToken(); err == nil {
			return g.GetData(key, request)
		}
	} else if strings.Contains(response.Data, "userRateLimitExceeded") { // Retry if hitting limit max 5 times
		if request.Attempts < 5 {
			time.Sleep(1 * time.Second)
			request.Attempts += 1
			g.GetData(key, request)
		}

	}
	if strings.Contains(response.Data, "\"error\"") {
		log.Println(response.Data)
	}
	return response
}

// BatchGet runs all queries in parellel and returns the results (or times out)
func (g *GAData) BatchGet(requests []*GaRequest) (responses []*CleanResponse, err error) {
	responses = make([]*CleanResponse, len(requests))
	ch := make(chan *GaResponse)
	// Start with a single request to ensure connectivity / token validity
	_, ok := g.GetData(0, requests[0]).Process()
	if ok {
		for a, b := range requests {
			// if we hit max requests limit / sec, sleep for 1 sec.
			if a%Limit == 0 {
				time.Sleep(1 * time.Second)
			}
			go func(x int, z *GaRequest) { ch <- g.GetData(x, z) }(a, b)
		}

		for i := 0; i < len(requests); i++ {
			select {
			case result := <-ch:
				if out, ok := result.Process(); ok {
					responses[result.Pos] = &out
				}
			// 60 sec timeout
			case <-time.After(60 * time.Second):
				return
			}
		}
	}

	return
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"os"

	"github.com/cloudfoundry-incubator/cf-debug-server"
	"github.com/cloudfoundry-incubator/cf-lager"
	"github.com/cloudfoundry-incubator/cf-tcp-router/configurer"
	"github.com/cloudfoundry-incubator/cf-tcp-router/handlers"
	"github.com/cloudfoundry-incubator/cf-tcp-router/models"
	"github.com/cloudfoundry-incubator/cf-tcp-router/routing_table"
	"github.com/cloudfoundry/dropsonde"
	"github.com/pivotal-golang/lager"
	"github.com/tedsuo/ifrit"
	"github.com/tedsuo/ifrit/grouper"
	"github.com/tedsuo/ifrit/http_server"
	"github.com/tedsuo/ifrit/sigmon"
)

var serverAddress = flag.String(
	"address",
	"",
	"The host:port that the server is bound to.",
)

var tcpLoadBalancer = flag.String(
	"tcpLoadBalancer",
	configurer.HaProxyConfigurer,
	"The tcp load balancer to use.",
)

var tcpLoadBalancerBaseCfg = flag.String(
	"tcpLoadBalancerBaseConfig",
	"",
	"The tcp load balancer base configuration file name. This contains the basic header information.",
)

var tcpLoadBalancerCfg = flag.String(
	"tcpLoadBalancerConfig",
	"",
	"The tcp load balancer configuration file name.",
)

const (
	dropsondeDestination = "localhost:3457"
	dropsondeOrigin      = "receptor"
)

func main() {
	cf_debug_server.AddFlags(flag.CommandLine)
	cf_lager.AddFlags(flag.CommandLine)
	flag.Parse()

	logger, reconfigurableSink := cf_lager.New("router-configurer")
	logger.Info("starting")

	initializeDropsonde(logger)

	routingTable := models.NewRoutingTable()
	configurer := configurer.NewConfigurer(logger,
		*tcpLoadBalancer, *tcpLoadBalancerBaseCfg, *tcpLoadBalancerCfg)
	updater := routing_table.NewUpdater(logger, routingTable, configurer)

	handler := handlers.New(logger, updater)

	members := grouper.Members{
		{"server", http_server.New(*serverAddress, handler)},
	}

	if dbgAddr := cf_debug_server.DebugAddress(flag.CommandLine); dbgAddr != "" {
		members = append(grouper.Members{
			{"debug-server", cf_debug_server.Runner(dbgAddr, reconfigurableSink)},
		}, members...)
	}

	group := grouper.NewOrdered(os.Interrupt, members)

	monitor := ifrit.Invoke(sigmon.New(group))

	logger.Info("started")

	err := <-monitor.Wait()
	if err != nil {
		logger.Error("exited-with-failure", err)
		os.Exit(1)
	}

	logger.Info("exited")
}

func initializeDropsonde(logger lager.Logger) {
	err := dropsonde.Initialize(dropsondeDestination, dropsondeOrigin)
	if err != nil {
		logger.Error("failed to initialize dropsonde: %v", err)
	}
}
<commit_msg>No reference to receptor<commit_after>package main

import (
	"flag"
	"os"

	"github.com/cloudfoundry-incubator/cf-debug-server"
	"github.com/cloudfoundry-incubator/cf-lager"
	"github.com/cloudfoundry-incubator/cf-tcp-router/configurer"
	"github.com/cloudfoundry-incubator/cf-tcp-router/handlers"
	"github.com/cloudfoundry-incubator/cf-tcp-router/models"
	"github.com/cloudfoundry-incubator/cf-tcp-router/routing_table"
	"github.com/cloudfoundry/dropsonde"
	"github.com/pivotal-golang/lager"
	"github.com/tedsuo/ifrit"
	"github.com/tedsuo/ifrit/grouper"
	"github.com/tedsuo/ifrit/http_server"
	"github.com/tedsuo/ifrit/sigmon"
)

var serverAddress = flag.String(
	"address",
	"",
	"The host:port that the server is bound to.",
)

var tcpLoadBalancer = flag.String(
	"tcpLoadBalancer",
	configurer.HaProxyConfigurer,
	"The tcp load balancer to use.",
)

var tcpLoadBalancerBaseCfg = flag.String(
	"tcpLoadBalancerBaseConfig",
	"",
	"The tcp load balancer base configuration file name. This contains the basic header information.",
)

var tcpLoadBalancerCfg = flag.String(
	"tcpLoadBalancerConfig",
	"",
	"The tcp load balancer configuration file name.",
)

const (
	dropsondeDestination = "localhost:3457"
	dropsondeOrigin      = "router-configurer"
)

func main() {
	cf_debug_server.AddFlags(flag.CommandLine)
	cf_lager.AddFlags(flag.CommandLine)
	flag.Parse()

	logger, reconfigurableSink := cf_lager.New("router-configurer")
	logger.Info("starting")

	initializeDropsonde(logger)

	routingTable := models.NewRoutingTable()
	configurer := configurer.NewConfigurer(logger,
		*tcpLoadBalancer, *tcpLoadBalancerBaseCfg, *tcpLoadBalancerCfg)
	updater := routing_table.NewUpdater(logger, routingTable, configurer)

	handler := handlers.New(logger, updater)

	members := grouper.Members{
		{"server", http_server.New(*serverAddress, handler)},
	}

	if dbgAddr := cf_debug_server.DebugAddress(flag.CommandLine); dbgAddr != "" {
		members = append(grouper.Members{
			{"debug-server", cf_debug_server.Runner(dbgAddr, reconfigurableSink)},
		}, members...)
	}

	group := grouper.NewOrdered(os.Interrupt, members)

	monitor := ifrit.Invoke(sigmon.New(group))

	logger.Info("started")

	err := <-monitor.Wait()
	if err != nil {
		logger.Error("exited-with-failure", err)
		os.Exit(1)
	}

	logger.Info("exited")
}

func initializeDropsonde(logger lager.Logger) {
	err := dropsonde.Initialize(dropsondeDestination, dropsondeOrigin)
	if err != nil {
		logger.Error("failed to initialize dropsonde: %v", err)
	}
}
<|endoftext|>