<commit_before>/*
Package telnet provides TELNET and TELNETS client and server implementations
in a style similar to the "net/http" library that is part of the Go standard library,
including support for "middleware"; TELNETS is secure TELNET, with the TELNET protocol
over a secured TLS (or SSL) connection.

Example TELNET Server

ListenAndServe starts a TELNET server with a given address and handler.

	handler := telnet.EchoHandler

	err := telnet.ListenAndServe(":23", handler)
	if nil != err {
		panic(err)
	}

Example TELNETS Server

ListenAndServeTLS starts a (secure) TELNETS server with a given address and handler,
using the specified "cert.pem" and "key.pem" files.

	handler := telnet.EchoHandler

	err := telnet.ListenAndServeTLS(":992", "cert.pem", "key.pem", handler)
	if nil != err {
		panic(err)
	}

TELNET vs TELNETS

If you are communicating over the open Internet, you should be using (the secure) TELNETS and ListenAndServeTLS.

If you are communicating just on localhost, then using just (the un-secure) TELNET and telnet.ListenAndServe may be OK.

If you are not sure which to use, use TELNETS and ListenAndServeTLS.

Example TELNET Shell Server

The previous 2 exaple servers were very very simple. Specifically, they just echoed back whatever
you submitted to it.

If you typed:

	Apple Banana Cherry\r\n

... it would send back:

	Apple Banana Cherry\r\n

(Exactly the same data you sent it.)

A more useful TELNET server can be made using the "github.com/reiver/go-telnet/telsh" sub-package.

The `telsh` sub-package provides "middleware" that enables you to create a "shell" interface (also
called a "command line interface" or "CLI") which most people would expect when using TELNET OR TELNETS.

For example:

	package main

	import (
		"github.com/reiver/go-oi"
		"github.com/reiver/go-telnet"
		"github.com/reiver/go-telnet/telsh"

		"time"
	)

	func main() {

		shellHandler := telsh.NewShellHandler()

		commandName := "date"
		shellHandler.Register(commandName, danceProducer)

		commandName = "animate"
		shellHandler.Register(commandName, animateProducer)

		addr := ":23"
		if err := telnet.ListenAndServe(addr, shellHandler); nil != err {
			panic(err)
		}
	}

Note that in the example, so far, we have registered 2 commands: `date` and `animate`.

For this to actually work, we need to have code for the `date` and `animate` commands.

The actual implemenation for the `date` command could be done like the following:

	func dateHandlerFunc(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser) error {
		const layout = "Mon Jan 2 15:04:05 -0700 MST 2006"
		s := time.Now().Format(layout)

		if _, err := oi.LongWriteString(stdout, s); nil != err {
			return err
		}

		return nil
	}

	func dateProducerFunc(ctx telsh.Context, name string, args ...string) telsh.Handler{
		return telsh.PromoteHandlerFunc(dateHandler)
	}

	var dateProducer = ProducerFunc(dateProducerFunc)

Note that your "real" work is in the `dateHandlerFunc` func.

And the actual implementation for the `animate` command could as done as follows:

	func animateHandlerFunc(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser) error {

		for i:=0; i<20; i++ {
			oi.LongWriteString(stdout, "\r⠋")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠙")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠹")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠸")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠼")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠴")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠦")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠧")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠇")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠏")
			time.Sleep(50*time.Millisecond)
		}
		oi.LongWriteString(stdout, "\r \r\n")

		return nil
	}

	func animateProducerFunc(ctx telsh.Context, name string, args ...string) telsh.Handler{
		return telsh.PromoteHandlerFunc(animateHandler)
	}

	var animateProducer = ProducerFunc(animateProducerFunc)

Again, note that your "real" work is in the `animateHandlerFunc` func.

Generating PEM Files

If you are using the telnet.ListenAndServeTLS func or the telnet.Server.ListenAndServeTLS method, you will need to
supply "cert.pem" and "key.pem" files.

If you do not already have these files, the Go soure code contains a tool for generating these files for you.

It can be found at:

	$GOROOT/src/crypto/tls/generate_cert.go

So, for example, if your `$GOROOT` is the "/usr/local/go" directory, then it would be at:

	/usr/local/go/src/crypto/tls/generate_cert.go

If you run the command:

	go run $GOROOT/src/crypto/tls/generate_cert.go --help

... then you get the help information for "generate_cert.go".

Of course, you would replace or set `$GOROOT` with whatever your path actualy is. Again, for example,
if your `$GOROOT` is the "/usr/local/go" directory, then it would be:

	go run /usr/local/go/src/crypto/tls/generate_cert.go --help

To demonstrate the usage of "generate_cert.go", you might run the following to generate certificates
that were bound to the hosts `127.0.0.1` and `localhost`:

	go run /usr/local/go/src/crypto/tls/generate_cert.go --ca --host='127.0.0.1,localhost'

If you are not sure where "generate_cert.go" is on your computer, on Linux and Unix based systems, you might
be able to find the file with the command:

	locate /src/crypto/tls/generate_cert.go

(If it finds it, it should output the full path to this file.)

Terminal Codes

Terminal codes (also sometimes called 'terminal control codes') are used to issue various kinds of commands
to the terminal.

(Note that 'terminal control codes' are a completely separate concept for 'TELNET commands',
and the two should NOT be conflated or confused.)

The most common types of 'terminal codes' are the 'ANSI escape codes'. (Although there are other types too.)

ANSI Escape Codes

ANSI escape codes (also sometimes called 'ANSI escape sequences') are a common type of 'terminal code' used
to do things such as:

• moving the cursor,

• erasing the display,

• erasing the line,

• setting the graphics mode,

• setting the foregroup color,

• setting the background color,

• setting the screen resolution, and

• setting keyboard strings.

Setting The Foreground Color With ANSI Escape Codes

One of the abilities of ANSI escape codes is to set the foreground color.

Here is a table showing codes for this:

	| ANSI Color   | Go string    | Go []byte                       |
	| ------------ | ------------ | ------------------------------- |
	| Black        | `"\x1b[30m"` | `[]byte{27, '[', '3','0', 'm'}` |
	| Red          | `"\x1b[31m"` | `[]byte{27, '[', '3','1', 'm'}` |
	| Green        | `"\x1b[32m"` | `[]byte{27, '[', '3','2', 'm'}` |
	| Brown/Yellow | `"\x1b[33m"` | `[]byte{27, '[', '3','3', 'm'}` |
	| Blue         | `"\x1b[34m"` | `[]byte{27, '[', '3','4', 'm'}` |
	| Magenta      | `"\x1b[35m"` | `[]byte{27, '[', '3','5', 'm'}` |
	| Cyan         | `"\x1b[36m"` | `[]byte{27, '[', '3','6', 'm'}` |
	| Gray/White   | `"\x1b[37m"` | `[]byte{27, '[', '3','7', 'm'}` |

(Note that in the `[]byte` that the first `byte` is the number `27` (which
is the "escape" character) where the third and fouth characters are the
**not** number literals, but instead character literals `'3'` and whatever.)

Setting The Background Color With ANSI Escape Codes

Another of the abilities of ANSI escape codes is to set the background color.

	| ANSI Color   | Go string    | Go []byte                       |
	| ------------ | ------------ | ------------------------------- |
	| Black        | `"\x1b[40m"` | `[]byte{27, '[', '4','0', 'm'}` |
	| Red          | `"\x1b[41m"` | `[]byte{27, '[', '4','1', 'm'}` |
	| Green        | `"\x1b[42m"` | `[]byte{27, '[', '4','2', 'm'}` |
	| Brown/Yellow | `"\x1b[43m"` | `[]byte{27, '[', '4','3', 'm'}` |
	| Blue         | `"\x1b[44m"` | `[]byte{27, '[', '4','4', 'm'}` |
	| Magenta      | `"\x1b[45m"` | `[]byte{27, '[', '4','5', 'm'}` |
	| Cyan         | `"\x1b[46m"` | `[]byte{27, '[', '4','6', 'm'}` |
	| Gray/White   | `"\x1b[47m"` | `[]byte{27, '[', '4','7', 'm'}` |

(Note that in the `[]byte` that the first `byte` is the number `27` (which
is the "escape" character) where the third and fouth characters are the
**not** number literals, but instead character literals `'4'` and whatever.)

Using ANSI Escape Codes

In Go code, if I wanted to use an ANSI escape code to use a blue background,
a white foreground, and bold, I could do that with the ANSI escape code:

	"\x1b[44;37;1m"

Note that that start with byte value 27, which we have encoded as hexadecimal
as \x1b. Followed by the '[' character.

Coming after that is the sub-string "44", which is the code that sets our background color to blue.

We follow that with the ';' character (which separates codes).

And the after that comes the sub-string "37", which is the code that set our foreground color to white.

After that, we follow with another ";" character (which, again, separates codes).

And then we follow it the sub-string "1", which is the code that makes things bold.

And finally, the ANSI escape sequence is finished off with the 'm' character.

To show this in a more complete example, our `dateHandlerFunc` from before could incorporate ANSI escape sequences as follows:

	func dateHandlerFunc(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser) error {
		const layout = "Mon Jan 2 15:04:05 -0700 MST 2006"
		s := "\x1b[44;37;1m" + time.Now().Format(layout) + "\x1b[0m"

		if _, err := oi.LongWriteString(stdout, s); nil != err {
			return err
		}

		return nil
	}

Note that in that example, in addition to using the ANSI escape sequence "\x1b[44;37;1m"
to set the background color to blue, set the foreground color to white, and make it bold,
we also used the ANSI escape sequence "\x1b[0m" to reset the background and foreground colors
and boldness back to "normal".

*/
package telnet
<commit_msg>updated docs<commit_after>/*
Package telnet provides TELNET and TELNETS client and server implementations
in a style similar to the "net/http" library that is part of the Go standard library,
including support for "middleware"; TELNETS is secure TELNET, with the TELNET protocol
over a secured TLS (or SSL) connection.

Example TELNET Server

ListenAndServe starts a (un-secure) TELNET server with a given address and handler.

	handler := telnet.EchoHandler

	err := telnet.ListenAndServe(":23", handler)
	if nil != err {
		panic(err)
	}

Example TELNETS Server

ListenAndServeTLS starts a (secure) TELNETS server with a given address and handler,
using the specified "cert.pem" and "key.pem" files.

	handler := telnet.EchoHandler

	err := telnet.ListenAndServeTLS(":992", "cert.pem", "key.pem", handler)
	if nil != err {
		panic(err)
	}

TELNET vs TELNETS

If you are communicating over the open Internet, you should be using (the secure) TELNETS and ListenAndServeTLS.

If you are communicating just on localhost, then using just (the un-secure) TELNET and telnet.ListenAndServe may be OK.

If you are not sure which to use, use TELNETS and ListenAndServeTLS.

Example TELNET Shell Server

The previous 2 exaple servers were very very simple. Specifically, they just echoed back whatever
you submitted to it.

If you typed:

	Apple Banana Cherry\r\n

... it would send back:

	Apple Banana Cherry\r\n

(Exactly the same data you sent it.)

A more useful TELNET server can be made using the "github.com/reiver/go-telnet/telsh" sub-package.

The `telsh` sub-package provides "middleware" that enables you to create a "shell" interface (also
called a "command line interface" or "CLI") which most people would expect when using TELNET OR TELNETS.

For example:

	package main

	import (
		"github.com/reiver/go-oi"
		"github.com/reiver/go-telnet"
		"github.com/reiver/go-telnet/telsh"

		"time"
	)

	func main() {

		shellHandler := telsh.NewShellHandler()

		commandName := "date"
		shellHandler.Register(commandName, danceProducer)

		commandName = "animate"
		shellHandler.Register(commandName, animateProducer)

		addr := ":23"
		if err := telnet.ListenAndServe(addr, shellHandler); nil != err {
			panic(err)
		}
	}

Note that in the example, so far, we have registered 2 commands: `date` and `animate`.

For this to actually work, we need to have code for the `date` and `animate` commands.

The actual implemenation for the `date` command could be done like the following:

	func dateHandlerFunc(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser) error {
		const layout = "Mon Jan 2 15:04:05 -0700 MST 2006"
		s := time.Now().Format(layout)

		if _, err := oi.LongWriteString(stdout, s); nil != err {
			return err
		}

		return nil
	}

	func dateProducerFunc(ctx telsh.Context, name string, args ...string) telsh.Handler{
		return telsh.PromoteHandlerFunc(dateHandler)
	}

	var dateProducer = ProducerFunc(dateProducerFunc)

Note that your "real" work is in the `dateHandlerFunc` func.

And the actual implementation for the `animate` command could as done as follows:

	func animateHandlerFunc(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser) error {

		for i:=0; i<20; i++ {
			oi.LongWriteString(stdout, "\r⠋")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠙")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠹")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠸")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠼")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠴")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠦")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠧")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠇")
			time.Sleep(50*time.Millisecond)

			oi.LongWriteString(stdout, "\r⠏")
			time.Sleep(50*time.Millisecond)
		}
		oi.LongWriteString(stdout, "\r \r\n")

		return nil
	}

	func animateProducerFunc(ctx telsh.Context, name string, args ...string) telsh.Handler{
		return telsh.PromoteHandlerFunc(animateHandler)
	}

	var animateProducer = ProducerFunc(animateProducerFunc)

Again, note that your "real" work is in the `animateHandlerFunc` func.

Generating PEM Files

If you are using the telnet.ListenAndServeTLS func or the telnet.Server.ListenAndServeTLS method, you will need to
supply "cert.pem" and "key.pem" files.

If you do not already have these files, the Go soure code contains a tool for generating these files for you.

It can be found at:

	$GOROOT/src/crypto/tls/generate_cert.go

So, for example, if your `$GOROOT` is the "/usr/local/go" directory, then it would be at:

	/usr/local/go/src/crypto/tls/generate_cert.go

If you run the command:

	go run $GOROOT/src/crypto/tls/generate_cert.go --help

... then you get the help information for "generate_cert.go".

Of course, you would replace or set `$GOROOT` with whatever your path actualy is. Again, for example,
if your `$GOROOT` is the "/usr/local/go" directory, then it would be:

	go run /usr/local/go/src/crypto/tls/generate_cert.go --help

To demonstrate the usage of "generate_cert.go", you might run the following to generate certificates
that were bound to the hosts `127.0.0.1` and `localhost`:

	go run /usr/local/go/src/crypto/tls/generate_cert.go --ca --host='127.0.0.1,localhost'

If you are not sure where "generate_cert.go" is on your computer, on Linux and Unix based systems, you might
be able to find the file with the command:

	locate /src/crypto/tls/generate_cert.go

(If it finds it, it should output the full path to this file.)

Terminal Codes

Terminal codes (also sometimes called 'terminal control codes') are used to issue various kinds of commands
to the terminal.

(Note that 'terminal control codes' are a completely separate concept for 'TELNET commands',
and the two should NOT be conflated or confused.)

The most common types of 'terminal codes' are the 'ANSI escape codes'. (Although there are other types too.)

ANSI Escape Codes

ANSI escape codes (also sometimes called 'ANSI escape sequences') are a common type of 'terminal code' used
to do things such as:

• moving the cursor,

• erasing the display,

• erasing the line,

• setting the graphics mode,

• setting the foregroup color,

• setting the background color,

• setting the screen resolution, and

• setting keyboard strings.

Setting The Foreground Color With ANSI Escape Codes

One of the abilities of ANSI escape codes is to set the foreground color.

Here is a table showing codes for this:

	| ANSI Color   | Go string    | Go []byte                       |
	| ------------ | ------------ | ------------------------------- |
	| Black        | `"\x1b[30m"` | `[]byte{27, '[', '3','0', 'm'}` |
	| Red          | `"\x1b[31m"` | `[]byte{27, '[', '3','1', 'm'}` |
	| Green        | `"\x1b[32m"` | `[]byte{27, '[', '3','2', 'm'}` |
	| Brown/Yellow | `"\x1b[33m"` | `[]byte{27, '[', '3','3', 'm'}` |
	| Blue         | `"\x1b[34m"` | `[]byte{27, '[', '3','4', 'm'}` |
	| Magenta      | `"\x1b[35m"` | `[]byte{27, '[', '3','5', 'm'}` |
	| Cyan         | `"\x1b[36m"` | `[]byte{27, '[', '3','6', 'm'}` |
	| Gray/White   | `"\x1b[37m"` | `[]byte{27, '[', '3','7', 'm'}` |

(Note that in the `[]byte` that the first `byte` is the number `27` (which
is the "escape" character) where the third and fouth characters are the
**not** number literals, but instead character literals `'3'` and whatever.)

Setting The Background Color With ANSI Escape Codes

Another of the abilities of ANSI escape codes is to set the background color.

	| ANSI Color   | Go string    | Go []byte                       |
	| ------------ | ------------ | ------------------------------- |
	| Black        | `"\x1b[40m"` | `[]byte{27, '[', '4','0', 'm'}` |
	| Red          | `"\x1b[41m"` | `[]byte{27, '[', '4','1', 'm'}` |
	| Green        | `"\x1b[42m"` | `[]byte{27, '[', '4','2', 'm'}` |
	| Brown/Yellow | `"\x1b[43m"` | `[]byte{27, '[', '4','3', 'm'}` |
	| Blue         | `"\x1b[44m"` | `[]byte{27, '[', '4','4', 'm'}` |
	| Magenta      | `"\x1b[45m"` | `[]byte{27, '[', '4','5', 'm'}` |
	| Cyan         | `"\x1b[46m"` | `[]byte{27, '[', '4','6', 'm'}` |
	| Gray/White   | `"\x1b[47m"` | `[]byte{27, '[', '4','7', 'm'}` |

(Note that in the `[]byte` that the first `byte` is the number `27` (which
is the "escape" character) where the third and fouth characters are the
**not** number literals, but instead character literals `'4'` and whatever.)

Using ANSI Escape Codes

In Go code, if I wanted to use an ANSI escape code to use a blue background,
a white foreground, and bold, I could do that with the ANSI escape code:

	"\x1b[44;37;1m"

Note that that start with byte value 27, which we have encoded as hexadecimal
as \x1b. Followed by the '[' character.

Coming after that is the sub-string "44", which is the code that sets our background color to blue.

We follow that with the ';' character (which separates codes).

And the after that comes the sub-string "37", which is the code that set our foreground color to white.

After that, we follow with another ";" character (which, again, separates codes).

And then we follow it the sub-string "1", which is the code that makes things bold.

And finally, the ANSI escape sequence is finished off with the 'm' character.

To show this in a more complete example, our `dateHandlerFunc` from before could incorporate ANSI escape sequences as follows:

	func dateHandlerFunc(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser) error {
		const layout = "Mon Jan 2 15:04:05 -0700 MST 2006"
		s := "\x1b[44;37;1m" + time.Now().Format(layout) + "\x1b[0m"

		if _, err := oi.LongWriteString(stdout, s); nil != err {
			return err
		}

		return nil
	}

Note that in that example, in addition to using the ANSI escape sequence "\x1b[44;37;1m"
to set the background color to blue, set the foreground color to white, and make it bold,
we also used the ANSI escape sequence "\x1b[0m" to reset the background and foreground colors
and boldness back to "normal".

*/
package telnet
<|endoftext|>


<commit_before>// TODO: make `go generate` work on windows

// Embed the custom service handlers
// TODO: Once AWS lambda supports golang as first class, move the
// NodeJS custom action helpers into golang
//go:generate go run $GOPATH/src/github.com/mjibson/esc/main.go -o ./CONSTANTS.go -private -pkg sparta ./resources
//go:generate go run ./resources/awsbinary/insertTags.go ./CONSTANTS !lambdabinary

// Create a secondary CONSTANTS_AWSBINARY.go file with empty content.  The next step will insert the
// build tags at the head of each file so that they are mutually exclusive, similar to the
// lambdabinaryshims.go file
//go:generate go run $GOPATH/src/github.com/mjibson/esc/main.go -o ./CONSTANTS_AWSBINARY.go -private -pkg sparta ./resources/awsbinary/README.md
//go:generate go run ./resources/awsbinary/insertTags.go ./CONSTANTS_AWSBINARY lambdabinary

// cleanup
//go:generate rm -f ./resources/provision/node_modules.zip

/*
Package sparta transforms a set of golang functions into an Amazon Lambda deployable unit.

The deployable archive includes

	 	1. NodeJS proxy logic
	 	2. A golang binary
	 	3. Dynamically generated CloudFormation template that supports create/update & delete operations.
	 	4. If specified, CloudFormation custom resources to automatically configure S3/SNS push registration
		5. If specified, API Gateway provisioning logic via custom resources to make the golang functions publicly accessible.

See the Main() docs for more information and examples
*/
package sparta
<commit_msg>Run the stamp.sh file as part of go:generate<commit_after>//
//go:generate ./stamp.sh

// Embed the custom service handlers
// TODO: Once AWS lambda supports golang as first class, move the
// NodeJS custom action helpers into golang
//go:generate go run $GOPATH/src/github.com/mjibson/esc/main.go -o ./CONSTANTS.go -private -pkg sparta ./resources
//go:generate go run ./resources/awsbinary/insertTags.go ./CONSTANTS !lambdabinary

// Create a secondary CONSTANTS_AWSBINARY.go file with empty content.  The next step will insert the
// build tags at the head of each file so that they are mutually exclusive, similar to the
// lambdabinaryshims.go file
//go:generate go run $GOPATH/src/github.com/mjibson/esc/main.go -o ./CONSTANTS_AWSBINARY.go -private -pkg sparta ./resources/awsbinary/README.md
//go:generate go run ./resources/awsbinary/insertTags.go ./CONSTANTS_AWSBINARY lambdabinary

// cleanup
//go:generate rm -f ./resources/provision/node_modules.zip

/*
Package sparta transforms a set of golang functions into an Amazon Lambda deployable unit.

The deployable archive includes

	 	1. NodeJS proxy logic
	 	2. A golang binary
	 	3. Dynamically generated CloudFormation template that supports create/update & delete operations.
	 	4. If specified, CloudFormation custom resources to automatically configure S3/SNS push registration
		5. If specified, API Gateway provisioning logic via custom resources to make the golang functions publicly accessible.

See the Main() docs for more information and examples
*/
package sparta
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013-2014 Kurt Jung (Gmail: kurt.w.jung)
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/*
Package gofpdf implements a PDF document generator with high level support for
text, drawing and images.

Features

• Choice of measurement unit, page format and margins

• Page header and footer management

• Automatic page breaks, line breaks, and text justification

• Inclusion of JPEG, PNG, GIF and basic path-only SVG images

• Colors, gradients and alpha channel transparency

• Outline bookmarks

• Internal and external links

• TrueType, Type1 and encoding support

• Page compression

• Lines, Bézier curves, arcs, and ellipses

• Rotation, scaling, skewing, translation, and mirroring

• Clipping

gofpdf has no dependencies other than the Go standard library. All tests pass
on Linux, Mac and Windows platforms. Like FPDF version 1.7, from which gofpdf
is derived, this package does not yet support UTF-8 source text.

Acknowledgments

This package's code and documentation are closely derived from the FPDF library
created by Olivier Plathey, and a number of font and image resources are copied
directly from it. Drawing support is adapted from the FPDF geometric figures
script by David Hernández Sanz. Transparency support is adapted from the FPDF
transparency script by Martin Hall-May. Support for gradients and clipping is
adapted from FPDF scripts by Andreas Würmser. Support for outline bookmarks is
adapted from Olivier Plathey by Manuel Cornes. Support for transformations is
adapted from the FPDF transformation script by Moritz Wagner and Andreas
Würmser. Lawrence Kesteloot provided code to allow an image's extent to be
determined prior to placement. Support for vertical alignment within a cell was
provided by Stefan Schroeder. Ivan Daniluk generalized the font and image
loading code to use the Reader interface while maintaining backward
compatibility. Bruno Michel has provided valuable assistance with the code.

The FPDF website is http://www.fpdf.org/.

License

gofpdf is copyrighted by Kurt Jung and is released under the MIT License.

Installation

To install the package on your system, run

	go get code.google.com/p/gofpdf

Later, to receive updates, run

	go get -u code.google.com/p/gofpdf

Quick Start

The following Go code generates a simple PDF.

	pdf := gofpdf.New("P", "mm", "A4", "../font")
	pdf.AddPage()
	pdf.SetFont("Arial", "B", 16)
	pdf.Cell(40, 10, "Hello, world")
	pdf.Output(os.Stdout)

See the tutorials in the fpdf_test.go file (shown as examples in this
documentation) for more advanced PDF examples.

Errors

If an error occurs in an Fpdf method, an internal error field is set. After
this occurs, Fpdf method calls typically return without performing any
operations and the error state is retained. This error management scheme
facilitates PDF generation since individual method calls do not need to be
examined for failure; it is generally sufficient to wait until after Output()
is called. For the same reason, if an error occurs in the calling application
during PDF generation, it may be desirable for the application to transfer the
error to the Fpdf instance by calling the SetError() method or the SetErrorf()
method. At any time during the life cycle of the Fpdf instance, the error state
can be determined with a call to Ok() or Err(). The error itself can be
retrieved with a call to Error().

Conversion Notes

This package is a relatively straightforward translation from the original FPDF
library written in PHP (despite the caveat in the introduction to Effective
Go). The API names have been retained even though the Go idiom would suggest
otherwise (for example, pdf.GetX() is used rather than simply pdf.X()). The
similarity of the two libraries makes the original FPDF website a good source
of information. It includes a forum and FAQ.

However, some internal changes have been made. Page content is built up using
buffers (of type bytes.Buffer) rather than repeated string concatenation.
Errors are handled as explained above rather than panicking. Output is
generated through an interface of type io.Writer or io.WriteCloser. A number of
the original PHP methods behave differently based on the type of the arguments
that are passed to them; in these cases additional methods have been exported
to provide similar functionality. Font definition files are produced in JSON
rather than PHP.

Tutorials

A side effect of running "go test" is the production of the tutorial PDFs.
These can be found in the gofpdf/pdf directory after the tests complete.

Nonstandard Fonts

Nothing special is required to use the standard PDF fonts (courier, helvetica,
times, zapfdingbats) in your documents other than calling SetFont().

In order to use a different TrueType or Type1 font, you will need to generate a
font definition file and, if the font will be embedded into PDFs, a compressed
version of the font file. This is done by calling the MakeFont function or
using the included makefont command line utility. To create the utility, cd
into the makefont subdirectory and run "go build". This will produce a
standalone executable named makefont. Select the appropriate encoding file from
the font subdirectory and run the command as in the following example.

	./makefont --embed --enc=../font/cp1252.map --dst=../font ../font/calligra.ttf

In your PDF generation code, call AddFont() to load the font and, as with the
standard fonts, SetFont() to begin using it. See tutorial 7 for an example.
Good sources of free, open-source fonts include http://www.google.com/fonts/
and http://dejavu-fonts.org/.

Roadmap

• Handle UTF-8 source text natively. Until then, automatic translation of
UTF-8 runes to code page bytes is provided.

• Improve test coverage as reported by the coverage tool.

*/
package gofpdf
<commit_msg>Yet another documentation tweak<commit_after>/*
 * Copyright (c) 2013-2014 Kurt Jung (Gmail: kurt.w.jung)
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/*
Package gofpdf implements a PDF document generator with high level support for
text, drawing and images.

Features

• Choice of measurement unit, page format and margins

• Page header and footer management

• Automatic page breaks, line breaks, and text justification

• Inclusion of JPEG, PNG, GIF and basic path-only SVG images

• Colors, gradients and alpha channel transparency

• Outline bookmarks

• Internal and external links

• TrueType, Type1 and encoding support

• Page compression

• Lines, Bézier curves, arcs, and ellipses

• Rotation, scaling, skewing, translation, and mirroring

• Clipping

gofpdf has no dependencies other than the Go standard library. All tests pass
on Linux, Mac and Windows platforms. Like FPDF version 1.7, from which gofpdf
is derived, this package does not yet support UTF-8 fonts. However, support is
provided to translate UTF-8 runes to code page encodings.

Acknowledgments

This package's code and documentation are closely derived from the FPDF library
created by Olivier Plathey, and a number of font and image resources are copied
directly from it. Drawing support is adapted from the FPDF geometric figures
script by David Hernández Sanz. Transparency support is adapted from the FPDF
transparency script by Martin Hall-May. Support for gradients and clipping is
adapted from FPDF scripts by Andreas Würmser. Support for outline bookmarks is
adapted from Olivier Plathey by Manuel Cornes. Support for transformations is
adapted from the FPDF transformation script by Moritz Wagner and Andreas
Würmser. Lawrence Kesteloot provided code to allow an image's extent to be
determined prior to placement. Support for vertical alignment within a cell was
provided by Stefan Schroeder. Ivan Daniluk generalized the font and image
loading code to use the Reader interface while maintaining backward
compatibility. Bruno Michel has provided valuable assistance with the code.

The FPDF website is http://www.fpdf.org/.

License

gofpdf is copyrighted by Kurt Jung and is released under the MIT License.

Installation

To install the package on your system, run

	go get code.google.com/p/gofpdf

Later, to receive updates, run

	go get -u code.google.com/p/gofpdf

Quick Start

The following Go code generates a simple PDF.

	pdf := gofpdf.New("P", "mm", "A4", "../font")
	pdf.AddPage()
	pdf.SetFont("Arial", "B", 16)
	pdf.Cell(40, 10, "Hello, world")
	pdf.Output(os.Stdout)

See the tutorials in the fpdf_test.go file (shown as examples in this
documentation) for more advanced PDF examples.

Errors

If an error occurs in an Fpdf method, an internal error field is set. After
this occurs, Fpdf method calls typically return without performing any
operations and the error state is retained. This error management scheme
facilitates PDF generation since individual method calls do not need to be
examined for failure; it is generally sufficient to wait until after Output()
is called. For the same reason, if an error occurs in the calling application
during PDF generation, it may be desirable for the application to transfer the
error to the Fpdf instance by calling the SetError() method or the SetErrorf()
method. At any time during the life cycle of the Fpdf instance, the error state
can be determined with a call to Ok() or Err(). The error itself can be
retrieved with a call to Error().

Conversion Notes

This package is a relatively straightforward translation from the original FPDF
library written in PHP (despite the caveat in the introduction to Effective
Go). The API names have been retained even though the Go idiom would suggest
otherwise (for example, pdf.GetX() is used rather than simply pdf.X()). The
similarity of the two libraries makes the original FPDF website a good source
of information. It includes a forum and FAQ.

However, some internal changes have been made. Page content is built up using
buffers (of type bytes.Buffer) rather than repeated string concatenation.
Errors are handled as explained above rather than panicking. Output is
generated through an interface of type io.Writer or io.WriteCloser. A number of
the original PHP methods behave differently based on the type of the arguments
that are passed to them; in these cases additional methods have been exported
to provide similar functionality. Font definition files are produced in JSON
rather than PHP.

Tutorials

A side effect of running "go test" is the production of the tutorial PDFs.
These can be found in the gofpdf/pdf directory after the tests complete.

Nonstandard Fonts

Nothing special is required to use the standard PDF fonts (courier, helvetica,
times, zapfdingbats) in your documents other than calling SetFont().

In order to use a different TrueType or Type1 font, you will need to generate a
font definition file and, if the font will be embedded into PDFs, a compressed
version of the font file. This is done by calling the MakeFont function or
using the included makefont command line utility. To create the utility, cd
into the makefont subdirectory and run "go build". This will produce a
standalone executable named makefont. Select the appropriate encoding file from
the font subdirectory and run the command as in the following example.

	./makefont --embed --enc=../font/cp1252.map --dst=../font ../font/calligra.ttf

In your PDF generation code, call AddFont() to load the font and, as with the
standard fonts, SetFont() to begin using it. See tutorial 7 for an example.
Good sources of free, open-source fonts include http://www.google.com/fonts/
and http://dejavu-fonts.org/.

Roadmap

• Handle UTF-8 source text natively. Until then, automatic translation of
UTF-8 runes to code page bytes is provided.

• Improve test coverage as reported by the coverage tool.

*/
package gofpdf
<|endoftext|>


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

// Package gribigo_compliance_test invokes the compliance tests from gribigo.
package gribigo_compliance_test

import (
	"flag"
	"strings"
	"testing"

	"github.com/openconfig/featureprofiles/internal/attrs"
	"github.com/openconfig/featureprofiles/internal/deviations"
	"github.com/openconfig/featureprofiles/internal/fptest"
	"github.com/openconfig/gribigo/compliance"
	"github.com/openconfig/gribigo/fluent"
	"github.com/openconfig/ondatra"
	"github.com/openconfig/ondatra/telemetry"
	"github.com/openconfig/testt"
)

var (
	skipFIBACK          = flag.Bool("skip_fiback", false, "skip tests that rely on FIB ACK")
	skipSrvReorder      = flag.Bool("skip_reordering", true, "skip tests that rely on server side transaction reordering")
	skipImplicitReplace = flag.Bool("skip_implicit_replace", true, "skip tests for ADD operations that perform implicit replacement of existing entries")
	skipNonDefaultNINHG = flag.Bool("skip_non_default_ni_nhg", true, "skip tests that add entries to non-default network-instance")

	nonDefaultNI = flag.String("non_default_ni", "non-default-vrf", "non-default network-instance name")

	dutPort1 = attrs.Attributes{
		Desc:    "dutPort1",
		IPv4:    "192.0.2.0",
		IPv4Len: 31,
	}
	dutPort2 = attrs.Attributes{
		Desc:    "dutPort2",
		IPv4:    "192.0.2.2",
		IPv4Len: 31,
	}
	dutPort3 = attrs.Attributes{
		Desc:    "dutPort3",
		IPv4:    "192.0.2.4",
		IPv4Len: 31,
	}

	atePort1 = attrs.Attributes{
		Name:    "atePort1",
		IPv4:    "192.0.2.1",
		IPv4Len: 31,
	}
	atePort2 = attrs.Attributes{
		Name:    "atePort2",
		IPv4:    "192.0.2.3",
		IPv4Len: 31,
	}
	atePort3 = attrs.Attributes{
		Name:    "atePort3",
		IPv4:    "192.0.2.5",
		IPv4Len: 31,
	}
)

func TestMain(m *testing.M) {
	fptest.RunTests(m)
}

var moreSkipReasons = map[string]string{
	"Get for installed NH - FIB ACK":                                         "NH FIB_ACK is not needed",
	"Flush non-default network instances preserves the default":              "b/232836921",
	"Election - Ensure that a client with mismatched parameters is rejected": "b/233111738",
}

func shouldSkip(tt *compliance.TestSpec) string {
	switch {
	case *skipFIBACK && tt.In.RequiresFIBACK:
		return "This RequiresFIBACK test is skipped by --skip_fiback"
	case *skipSrvReorder && tt.In.RequiresServerReordering:
		return "This RequiresServerReordering test is skipped by --skip_reordering"
	case *skipImplicitReplace && tt.In.RequiresImplicitReplace:
		return "This RequiresImplicitReplace test is skipped by --skip_implicit_replace"
	case *skipNonDefaultNINHG && tt.In.RequiresNonDefaultNINHG:
		return "This RequiresNonDefaultNINHG test is skipped by --skip_non_default_ni_nhg"
	}
	return moreSkipReasons[tt.In.ShortName]
}

func TestCompliance(t *testing.T) {
	dut := ondatra.DUT(t, "dut")
	configureDUT(t, dut)

	ate := ondatra.ATE(t, "ate")
	configureATE(t, ate)

	gribic := dut.RawAPIs().GRIBI().Default(t)

	for _, tt := range compliance.TestSuite {
		t.Run(tt.In.ShortName, func(t *testing.T) {
			if reason := shouldSkip(tt); reason != "" {
				t.Skip(reason)
			}

			compliance.SetDefaultNetworkInstanceName(*deviations.DefaultNetworkInstance)
			compliance.SetNonDefaultVRFName(*nonDefaultNI)

			c := fluent.NewClient()
			c.Connection().WithStub(gribic)

			sc := fluent.NewClient()
			sc.Connection().WithStub(gribic)

			opts := []compliance.TestOpt{
				compliance.SecondClient(sc),
			}

			if tt.FatalMsg != "" {
				if got := testt.ExpectFatal(t, func(t testing.TB) {
					tt.In.Fn(c, t, opts...)
				}); !strings.Contains(got, tt.FatalMsg) {
					t.Fatalf("did not get expected fatal error, got: %s, want: %s", got, tt.FatalMsg)
				}
				return
			}

			if tt.ErrorMsg != "" {
				if got := testt.ExpectError(t, func(t testing.TB) {
					tt.In.Fn(c, t, opts...)
				}); !strings.Contains(strings.Join(got, " "), tt.ErrorMsg) {
					t.Fatalf("did not get expected error, got: %s, want: %s", got, tt.ErrorMsg)
				}
				return
			}

			// Any unexpected error will be caught by being called directly on t from the fluent library.
			tt.In.Fn(c, t, opts...)
		})
	}
}

// configureDUT configures port1-3 on the DUT.
func configureDUT(t *testing.T, dut *ondatra.DUTDevice) {
	p1 := dut.Port(t, "port1")
	p2 := dut.Port(t, "port2")
	p3 := dut.Port(t, "port3")

	dut.Config().Interface(p1.Name()).Replace(t, dutPort1.NewInterface(p1.Name()))
	dut.Config().Interface(p2.Name()).Replace(t, dutPort2.NewInterface(p2.Name()))
	dut.Config().Interface(p3.Name()).Replace(t, dutPort3.NewInterface(p3.Name()))

	d := &telemetry.Device{}
	ni := d.GetOrCreateNetworkInstance(*nonDefaultNI)
	ni.Type = telemetry.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_L3VRF
	ni.GetOrCreateProtocol(telemetry.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, "static")
	dut.Config().NetworkInstance(*nonDefaultNI).Replace(t, ni)

	nip := dut.Config().NetworkInstance(*nonDefaultNI)
	fptest.LogYgot(t, "nonDefaultNI", nip, nip.Get(t))
}

// configreATE configures port1-3 on the ATE.
func configureATE(t *testing.T, ate *ondatra.ATEDevice) *ondatra.ATETopology {
	top := ate.Topology().New()

	p1 := ate.Port(t, "port1")
	p2 := ate.Port(t, "port2")
	p3 := ate.Port(t, "port3")

	atePort1.AddToATE(top, p1, &dutPort1)
	atePort2.AddToATE(top, p2, &dutPort2)
	atePort3.AddToATE(top, p3, &dutPort3)

	top.Push(t).StartProtocols(t)

	return top
}
<commit_msg>OTG Test - TE-15.1: gRIBI Compliance (#616)<commit_after>// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package gribigo_compliance_test invokes the compliance tests from gribigo.
package gribigo_compliance_test

import (
	"flag"
	"strings"
	"testing"

	"github.com/open-traffic-generator/snappi/gosnappi"
	"github.com/openconfig/featureprofiles/internal/attrs"
	"github.com/openconfig/featureprofiles/internal/deviations"
	"github.com/openconfig/featureprofiles/internal/fptest"
	"github.com/openconfig/gribigo/compliance"
	"github.com/openconfig/gribigo/fluent"
	"github.com/openconfig/ondatra"
	"github.com/openconfig/ondatra/telemetry"
	"github.com/openconfig/testt"
)

var (
	skipFIBACK          = flag.Bool("skip_fiback", false, "skip tests that rely on FIB ACK")
	skipSrvReorder      = flag.Bool("skip_reordering", true, "skip tests that rely on server side transaction reordering")
	skipImplicitReplace = flag.Bool("skip_implicit_replace", true, "skip tests for ADD operations that perform implicit replacement of existing entries")
	skipNonDefaultNINHG = flag.Bool("skip_non_default_ni_nhg", true, "skip tests that add entries to non-default network-instance")

	nonDefaultNI = flag.String("non_default_ni", "non-default-vrf", "non-default network-instance name")

	dutPort1 = attrs.Attributes{
		Desc:    "dutPort1",
		IPv4:    "192.0.2.0",
		IPv4Len: 31,
	}
	dutPort2 = attrs.Attributes{
		Desc:    "dutPort2",
		IPv4:    "192.0.2.2",
		IPv4Len: 31,
	}
	dutPort3 = attrs.Attributes{
		Desc:    "dutPort3",
		IPv4:    "192.0.2.4",
		IPv4Len: 31,
	}

	atePort1 = attrs.Attributes{
		Name:    "atePort1",
		MAC:     "02:00:01:01:01:01",
		IPv4:    "192.0.2.1",
		IPv4Len: 31,
	}
	atePort2 = attrs.Attributes{
		Name:    "atePort2",
		MAC:     "02:00:02:01:01:01",
		IPv4:    "192.0.2.3",
		IPv4Len: 31,
	}
	atePort3 = attrs.Attributes{
		Name:    "atePort3",
		MAC:     "02:00:03:01:01:01",
		IPv4:    "192.0.2.5",
		IPv4Len: 31,
	}
)

func TestMain(m *testing.M) {
	fptest.RunTests(m)
}

var moreSkipReasons = map[string]string{
	"Get for installed NH - FIB ACK":                                         "NH FIB_ACK is not needed",
	"Flush non-default network instances preserves the default":              "b/232836921",
	"Election - Ensure that a client with mismatched parameters is rejected": "b/233111738",
}

func shouldSkip(tt *compliance.TestSpec) string {
	switch {
	case *skipFIBACK && tt.In.RequiresFIBACK:
		return "This RequiresFIBACK test is skipped by --skip_fiback"
	case *skipSrvReorder && tt.In.RequiresServerReordering:
		return "This RequiresServerReordering test is skipped by --skip_reordering"
	case *skipImplicitReplace && tt.In.RequiresImplicitReplace:
		return "This RequiresImplicitReplace test is skipped by --skip_implicit_replace"
	case *skipNonDefaultNINHG && tt.In.RequiresNonDefaultNINHG:
		return "This RequiresNonDefaultNINHG test is skipped by --skip_non_default_ni_nhg"
	}
	return moreSkipReasons[tt.In.ShortName]
}

func TestCompliance(t *testing.T) {
	dut := ondatra.DUT(t, "dut")
	configureDUT(t, dut)

	ate := ondatra.ATE(t, "ate")
	configureATE(t, ate)

	gribic := dut.RawAPIs().GRIBI().Default(t)

	for _, tt := range compliance.TestSuite {
		t.Run(tt.In.ShortName, func(t *testing.T) {
			if reason := shouldSkip(tt); reason != "" {
				t.Skip(reason)
			}

			compliance.SetDefaultNetworkInstanceName(*deviations.DefaultNetworkInstance)
			compliance.SetNonDefaultVRFName(*nonDefaultNI)

			c := fluent.NewClient()
			c.Connection().WithStub(gribic)

			sc := fluent.NewClient()
			sc.Connection().WithStub(gribic)

			opts := []compliance.TestOpt{
				compliance.SecondClient(sc),
			}

			if tt.FatalMsg != "" {
				if got := testt.ExpectFatal(t, func(t testing.TB) {
					tt.In.Fn(c, t, opts...)
				}); !strings.Contains(got, tt.FatalMsg) {
					t.Fatalf("did not get expected fatal error, got: %s, want: %s", got, tt.FatalMsg)
				}
				return
			}

			if tt.ErrorMsg != "" {
				if got := testt.ExpectError(t, func(t testing.TB) {
					tt.In.Fn(c, t, opts...)
				}); !strings.Contains(strings.Join(got, " "), tt.ErrorMsg) {
					t.Fatalf("did not get expected error, got: %s, want: %s", got, tt.ErrorMsg)
				}
				return
			}

			// Any unexpected error will be caught by being called directly on t from the fluent library.
			tt.In.Fn(c, t, opts...)
		})
	}
}

// configureDUT configures port1-3 on the DUT.
func configureDUT(t *testing.T, dut *ondatra.DUTDevice) {
	p1 := dut.Port(t, "port1")
	p2 := dut.Port(t, "port2")
	p3 := dut.Port(t, "port3")

	dut.Config().Interface(p1.Name()).Replace(t, dutPort1.NewInterface(p1.Name()))
	dut.Config().Interface(p2.Name()).Replace(t, dutPort2.NewInterface(p2.Name()))
	dut.Config().Interface(p3.Name()).Replace(t, dutPort3.NewInterface(p3.Name()))

	d := &telemetry.Device{}
	ni := d.GetOrCreateNetworkInstance(*nonDefaultNI)
	ni.Type = telemetry.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_L3VRF
	ni.GetOrCreateProtocol(telemetry.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, "static")
	dut.Config().NetworkInstance(*nonDefaultNI).Replace(t, ni)

	nip := dut.Config().NetworkInstance(*nonDefaultNI)
	fptest.LogYgot(t, "nonDefaultNI", nip, nip.Get(t))
}

// configreATE configures port1-3 on the ATE.
func configureATE(t *testing.T, ate *ondatra.ATEDevice) gosnappi.Config {
	top := ate.OTG().NewConfig(t)

	p1 := ate.Port(t, "port1")
	p2 := ate.Port(t, "port2")
	p3 := ate.Port(t, "port3")

	addToOTG(top, p1, &atePort1, &dutPort1)
	addToOTG(top, p2, &atePort2, &dutPort2)
	addToOTG(top, p3, &atePort3, &dutPort3)

	ate.OTG().PushConfig(t, top)
	ate.OTG().StartProtocols(t)

	return top
}

// addToOTG adds elements to a gosnappi configuration
func addToOTG(top gosnappi.Config, ap *ondatra.Port, port, peer *attrs.Attributes) {
	top.Ports().Add().SetName(ap.ID())
	dev := top.Devices().Add().SetName(port.Name)
	eth := dev.Ethernets().Add().SetName(port.Name + ".Eth")
	eth.SetPortName(ap.ID()).SetMac(port.MAC)

	if port.MTU > 0 {
		eth.SetMtu(int32(port.MTU))
	}
	if port.IPv4 != "" {
		ip := eth.Ipv4Addresses().Add().SetName(dev.Name() + ".IPv4")
		ip.SetAddress(port.IPv4).SetGateway(peer.IPv4).SetPrefix(int32(port.IPv4Len))
	}
	if port.IPv6 != "" {
		ip := eth.Ipv4Addresses().Add().SetName(dev.Name() + ".IPv6")
		ip.SetAddress(port.IPv6).SetGateway(peer.IPv6).SetPrefix(int32(port.IPv6Len))
	}
}
<|endoftext|>


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

/*
Compatibility

The gohg client library is created with Go1 (v1.0.3). It is tested against
Mercurial 2.5.2, both on Windows 7 and Ubuntu 12.04.

Currently there is no mechanism to handle differences in possibilities between
different Mercurial versions.

Import the package

Start with importing the gohg package:
  import . "bitbucket.org/gohg/gohg"

Connecting the Mercurial Command Server

All interaction with the Hg CS happens through the HgClient type, of which you
have to create an instance:

  hc :=  NewHgClient()

Then you can connect the Hg CS:

  err := hc.Connect("hg", "~/myrepo", nil)
   4                 1        2        3

1. The Hg executable:

The first parameter is the Mercurial command to use (which 'hg'). You can leave
it blanc to let the gohg tool use the default Mercurial command on the system.
Having a parameter for the Hg command allows for using a different Hg version,
for testing purposes for instance.

2. The repository path:

The second parameter is the path to the repository you want to work on. You can
leave it blanc to have gohg use the repository it can find for the current path
(searching upward in the folder tree eventually).

3. The config for the session:

The third parameter allows to provide extra configuration for the session.
Though this is currently not implemented yet.

4. The returnvalue:

The HgClient.Connect() method returns an error, so you can check if the
connection succeeded, and if it is safe to go on or not.

Once the work is done, you can disconnect the Hg CS. We advise to use a typical
Go idiom for this:

  err := hc.Connect("hg", "~/myrepo", nil)
  if err != nil {
      log.Fatal(err)
  }
  defer hc.Disconnect()
  // do the real work here

Commands

Now that we have a connection to a Hg CS we can do some work with the
repository. This is done with commands, implemented as methods for the HgClient
type. Each command has the same name as the corresponding Hg command, except it
starts with a capital letter.

  log, err := hc.Log(Limit(2))
  if err != nil {
      fmt.Printf(err)
  }

Commands normally return a byte slice containing the resulting data, and an
error type. But there are exceptions (see api docs hereafter).

  log, err := hc.Log()          // log is a byte slice
  err := hc.Init("~/mynewrepo") // only returns an error
  version , err:= hc.Version()  // version is a string

Parameters and Options

In the gohg tool, parameters are used to pass-in any arguments for a command
that are not options. They are passed in first, before any options, as a string
or a string slice, depending on the command. These parameters typically contain
revisions, paths or filenames and so.

  log, err := hc.Log("myfile")
  heads, err := hc.Heads("foobranch")

Options to commands use the same name as the long form of the Mercurial option
they represent, and start with a capital letter (as do all exported symbols in
Go). An option can be of type bool, int or string. You just pass the value as
the parameter to the option. You can combine any options, just as you can on the
commandline. Options can be passed in more than once if appropriate (see the
ones marked with '[+]' in the Mercurial help).

  log, err := hc.Log(Verbose(true))
  log, err := hc.Log(Limit(2))
  log, err := hc.Log(User("John Doe"), User("me"))

In contrast with the typical commandline usage of the Hg commands, all options
have to be passed after the parameter(s) to the command, because the quantity of
options is variable. This is just a Go constraint of the implementation making
it possible to pass a variable number of options.

  log, err := hc.Log("myfile", Verbose(true), Limit(2))

The gohg tool only checks if the options the caller gives are valid for that
command. It does not check if the values are valid for the combination of that
command and that option, as that is done by Mercurial. No need to do double
work. If an option is not valid for a command, it is silently ignored, so it is
not passed to the Hg CS.

Some options are not implemented, as they seemed not relevant for use with this
tool (for instance: the global --color option, or the --print0 option for
status).

Limitations

The following config settings are fixated in the code (at least for now):
  encoding=utf-8
  ui.interactive=False
  extensions.color=!

As mentioned earlier, passing config info is not implemented yet.

Currently there is no support for any extensions to Mercurial.

License

Copyright 2012, The gohg Authors. All rights reserved.

Use of this source code is governed by a BSD style license that can be found in
the LICENSE.md file.

*/
package gohg
<commit_msg>doc: added Dependencies, Installation and Issues sections<commit_after>// Copyright 2012, The gohg Authors. All rights reserved.
// Use of this source code is governed by a BSD style license
// that can be found in the LICENSE file.

/*
Compatibility

The gohg client library is created with Go1 (v1.0.3). It is tested against
Mercurial 2.5.2, both on Windows 7 and Ubuntu 12.04.

Currently there is no mechanism to handle differences in possibilities between
different Mercurial versions.

Dependencies

Only Go and it's standard library. Though I'm using gocov for checking test
coverage (see https://github.com/axw/gocov).

Installation

At the commandline type:
  go get [-u] bitbucket.org/gohg/gohg
  go install bitbucket.org/gohg/gohg
  go test -v bitbucket.org/gohg/gohg

Import the package

Start with importing the gohg package:
  import . "bitbucket.org/gohg/gohg"

Connecting the Mercurial Command Server

All interaction with the Hg CS happens through the HgClient type, of which you
have to create an instance:

  hc :=  NewHgClient()

Then you can connect the Hg CS:

  err := hc.Connect("hg", "~/myrepo", nil)
   4                 1        2        3

1. The Hg executable:

The first parameter is the Mercurial command to use (which 'hg'). You can leave
it blanc to let the gohg tool use the default Mercurial command on the system.
Having a parameter for the Hg command allows for using a different Hg version,
for testing purposes for instance.

2. The repository path:

The second parameter is the path to the repository you want to work on. You can
leave it blanc to have gohg use the repository it can find for the current path
(searching upward in the folder tree eventually).

3. The config for the session:

The third parameter allows to provide extra configuration for the session.
Though this is currently not implemented yet.

4. The returnvalue:

The HgClient.Connect() method returns an error, so you can check if the
connection succeeded, and if it is safe to go on or not.

Once the work is done, you can disconnect the Hg CS. We advise to use a typical
Go idiom for this:

  err := hc.Connect("hg", "~/myrepo", nil)
  if err != nil {
      log.Fatal(err)
  }
  defer hc.Disconnect()
  // do the real work here

Commands

Now that we have a connection to a Hg CS we can do some work with the
repository. This is done with commands, implemented as methods for the HgClient
type. Each command has the same name as the corresponding Hg command, except it
starts with a capital letter.

  log, err := hc.Log(Limit(2))
  if err != nil {
      fmt.Printf(err)
  }

Commands normally return a byte slice containing the resulting data, and an
error type. But there are exceptions (see api docs hereafter).

  log, err := hc.Log()          // log is a byte slice
  err := hc.Init("~/mynewrepo") // only returns an error
  version , err:= hc.Version()  // version is a string

Parameters and Options

In the gohg tool, parameters are used to pass-in any arguments for a command
that are not options. They are passed in first, before any options, as a string
or a string slice, depending on the command. These parameters typically contain
revisions, paths or filenames and so.

  log, err := hc.Log("myfile")
  heads, err := hc.Heads("foobranch")

Options to commands use the same name as the long form of the Mercurial option
they represent, and start with a capital letter (as do all exported symbols in
Go). An option can be of type bool, int or string. You just pass the value as
the parameter to the option. You can combine any options, just as you can on the
commandline. Options can be passed in more than once if appropriate (see the
ones marked with '[+]' in the Mercurial help).

  log, err := hc.Log(Verbose(true))
  log, err := hc.Log(Limit(2))
  log, err := hc.Log(User("John Doe"), User("me"))

In contrast with the typical commandline usage of the Hg commands, all options
have to be passed after the parameter(s) to the command, because the quantity of
options is variable. This is just a Go constraint of the implementation making
it possible to pass a variable number of options.

  log, err := hc.Log("myfile", Verbose(true), Limit(2))

The gohg tool only checks if the options the caller gives are valid for that
command. It does not check if the values are valid for the combination of that
command and that option, as that is done by Mercurial. No need to do double
work. If an option is not valid for a command, it is silently ignored, so it is
not passed to the Hg CS.

Some options are not implemented, as they seemed not relevant for use with this
tool (for instance: the global --color option, or the --print0 option for
status).

Limitations

The following config settings are fixated in the code (at least for now):
  encoding=utf-8
  ui.interactive=False
  extensions.color=!

As mentioned earlier, passing config info is not implemented yet.

Currently there is no support for any extensions to Mercurial.

Issues

If you experience any issues using the gohg tool, please register an issue using
the Bitbucket issue tracker at https://bitbucket.org/gohg/gohg/issues.

You can also register any enhancement requests or suggestions for improvement
there.

License

Copyright 2012, The gohg Authors. All rights reserved.

Use of this source code is governed by a BSD style license that can be found in
the LICENSE.md file.

*/
package gohg
<|endoftext|>


<commit_before>/*
Package toml provides facilities for decoding TOML configuration files
via reflection.

Specification: https://github.com/mojombo/toml

Use github.com/BurntSushi/toml/tomlv to check whether a file is valid
TOML or not, with helpful error messages.
*/
package toml
<commit_msg>Include more details in package level docs.<commit_after>/*
Package toml provides facilities for decoding and encoding TOML configuration
files via reflection. There is also support for delaying decoding with
the Primitive type, and querying the set of keys in a TOML document with the
MetaData type.

The specification implemented: https://github.com/mojombo/toml

The sub-command github.com/BurntSushi/toml/cmd/tomlv can be used to verify
whether a file is a valid TOML document. It can also be used to print the
type of each key in a TOML document.

Testing

There are two important types of tests used for this package. The first is
contained inside '*_test.go' files and uses the standard Go unit testing
framework. These tests are primarily devoted to holistically testing the
decoder and encoder.

The second type of testing is used to verify the implementation's adherence
to the TOML specification. These tests have been factored into their own
project: https://github.com/BurntSushi/toml-test

The reason the tests are in a separate project is so that they can be used by
any implementation of TOML. Namely, it is language agnostic.
*/
package toml
<|endoftext|>


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

// Doc is a simple document printer that produces the doc comments for its
// argument symbols, plus a link to the full documentation and a pointer to
// the source. It has a more Go-like UI than godoc. It can also search for
// symbols by looking in all packages, and case is ignored. For instance:
//	doc isupper
// will find unicode.IsUpper.
//
// The -pkg flag retrieves package-level doc comments only.
//
// Usage:
//	doc pkg.name   # "doc io.Writer"
//	doc pkg name   # "doc fmt Printf"
//	doc name       # "doc isupper" (finds unicode.IsUpper)
//	doc -pkg pkg   # "doc fmt"
//
// The pkg is the last element of the package path;
// no slashes (ast.Node not go/ast.Node).
//
// Flags
//	-c(onst) -f(unc) -i(nterface) -m(ethod) -s(truct) -t(ype) -v(ar)
// restrict hits to declarations of the corresponding kind.
// Flags
//	-doc -src -url
// restrict printing to the documentation, source path, or godoc URL.
package main

import (
	"bytes"
	"flag"
	"fmt"
	"go/ast"
	"go/build"
	"go/parser"
	"go/printer"
	"go/token"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"runtime"
	"strings"
	"unicode"
	"unicode/utf8"
)

const usageDoc = `Find documentation for names.
usage:
	doc pkg.name   # "doc io.Writer"
	doc pkg name   # "doc fmt Printf"
	doc name       # "doc isupper" finds unicode.IsUpper
	doc -pkg pkg   # "doc fmt"
pkg is the last component of any package, e.g. fmt, parser
name is the name of an exported symbol; case is ignored in matches.
Flags
	-c(onst) -f(unc) -i(nterface) -m(ethod) -s(truct) -t(ype) -v(ar)
restrict hits to declarations of the corresponding kind.
Flags
	-doc -src -url
restrict printing to the documentation, source path, or godoc URL.
`

func usage() {
	fmt.Fprintf(os.Stderr, usageDoc)
	os.Exit(2)
}

var (
	// If none is set, all are set.
	constantFlag  = flag.Bool("const", false, "show doc for consts only")
	functionFlag  = flag.Bool("func", false, "show doc for funcs only")
	interfaceFlag = flag.Bool("interface", false, "show doc for interfaces only")
	methodFlag    = flag.Bool("method", false, "show doc for methods only")
	packageFlag   = flag.Bool("package", false, "show top-level package doc only")
	structFlag    = flag.Bool("struct", false, "show doc for structs only")
	typeFlag      = flag.Bool("type", false, "show doc for types only")
	variableFlag  = flag.Bool("var", false, "show  doc for vars only")
)

var (
	// If none is set, all are set.
	docFlag = flag.Bool("doc", false, "restrict output to documentation only")
	srcFlag = flag.Bool("src", false, "restrict output to source file only")
	urlFlag = flag.Bool("url", false, "restrict output to godoc URL only")
)

func init() {
	flag.BoolVar(constantFlag, "c", false, "alias for -const")
	flag.BoolVar(functionFlag, "f", false, "alias for -func")
	flag.BoolVar(interfaceFlag, "i", false, "alias for -interface")
	flag.BoolVar(methodFlag, "m", false, "alias for -method")
	flag.BoolVar(packageFlag, "pkg", false, "alias for -package")
	flag.BoolVar(structFlag, "s", false, "alias for -struct")
	flag.BoolVar(typeFlag, "t", false, "alias for -type")
	flag.BoolVar(variableFlag, "v", false, "alias for -var")
}

func main() {
	flag.Parse()
	if !(*constantFlag || *functionFlag || *interfaceFlag || *methodFlag || *packageFlag || *structFlag || *typeFlag || *variableFlag) { // none set
		*constantFlag = true
		*functionFlag = true
		*methodFlag = true
		// Not package! It's special.
		*typeFlag = true
		*variableFlag = true
	}
	if !(*docFlag || *srcFlag || *urlFlag) {
		*docFlag = true
		*srcFlag = true
		*urlFlag = true
	}
	var pkg, name string
	switch flag.NArg() {
	case 1:
		if *packageFlag {
			pkg = flag.Arg(0)
		} else if strings.Contains(flag.Arg(0), ".") {
			pkg, name = split(flag.Arg(0))
		} else {
			name = flag.Arg(0)
		}
	case 2:
		if *packageFlag {
			usage()
		}
		pkg, name = flag.Arg(0), flag.Arg(1)
	default:
		usage()
	}
	for _, path := range paths(pkg) {
		lookInDirectory(path, name)
	}
}

var slash = string(filepath.Separator)
var slashDot = string(filepath.Separator) + "."
var goRootSrcPkg = filepath.Join(runtime.GOROOT(), "src", "pkg")
var goPaths = splitGopath()

func split(arg string) (pkg, name string) {
	str := strings.Split(arg, ".")
	if len(str) != 2 {
		usage()
	}
	return str[0], str[1]
}

func paths(pkg string) []string {
	pkgs := pathsFor(runtime.GOROOT(), pkg)
	for _, root := range goPaths {
		pkgs = append(pkgs, pathsFor(root, pkg)...)
	}
	return pkgs
}

func splitGopath() []string {
	gopath := os.Getenv("GOPATH")
	if gopath == "" {
		return nil
	}
	return strings.Split(gopath, string(os.PathListSeparator))
}

// pathsFor recursively walks the tree looking for possible directories for the package:
// those whose basename is pkg.
func pathsFor(root, pkg string) []string {
	root = path.Join(root, "src")
	pkgPaths := make([]string, 0, 10)
	visit := func(pathName string, f os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		// One package per directory. Ignore the files themselves.
		if !f.IsDir() {
			return nil
		}
		// No .hg or other dot nonsense please.
		if strings.Contains(pathName, slashDot) {
			return filepath.SkipDir
		}
		// Is the last element of the path correct
		if pkg == "" || filepath.Base(pathName) == pkg {
			pkgPaths = append(pkgPaths, pathName)
		}
		return nil
	}

	filepath.Walk(root, visit)
	return pkgPaths
}

// lookInDirectory looks in the package (if any) in the directory for the named exported identifier.
func lookInDirectory(directory, name string) {
	pkg, err := build.Default.ImportDir(directory, 0)
	if err != nil {
		// If it's just that there are no go source files, that's fine.
		if _, nogo := err.(*build.NoGoError); nogo {
			return
		}
		// Non-fatal: we are doing a recursive walk and there may be other directories.
		return
	}
	var fileNames []string
	fileNames = append(fileNames, pkg.GoFiles...)
	prefixDirectory(directory, fileNames)
	doPackage(fileNames, name)
}

// prefixDirectory places the directory name on the beginning of each name in the list.
func prefixDirectory(directory string, names []string) {
	if directory != "." {
		for i, name := range names {
			names[i] = filepath.Join(directory, name)
		}
	}
}

// File is a wrapper for the state of a file used in the parser.
// The parse tree walkers are all methods of this type.
type File struct {
	fset       *token.FileSet
	name       string
	ident      string
	pathPrefix string
	urlPrefix  string
	file       *ast.File
	comments   ast.CommentMap
}

// doPackage analyzes the single package constructed from the named files, looking for
// the definition of ident.
func doPackage(fileNames []string, ident string) {
	var files []*File
	var astFiles []*ast.File
	fs := token.NewFileSet()
	for _, name := range fileNames {
		f, err := os.Open(name)
		if err != nil {
			// Warn but continue to next package.
			fmt.Fprintf(os.Stderr, "%s: %s", name, err)
			return
		}
		defer f.Close()
		data, err := ioutil.ReadAll(f)
		if err != nil {
			fmt.Fprintf(os.Stderr, "%s: %s", name, err)
			return
		}
		parsedFile, err := parser.ParseFile(fs, name, bytes.NewReader(data), parser.ParseComments)
		if err != nil {
			// Noisy - just ignore.
			// fmt.Fprintf(os.Stderr, "%s: %s", name, err)
			return
		}
		urlPrefix := "http://golang.org/pkg"
		pathPrefix := goRootSrcPkg
		if !strings.HasPrefix(name, goRootSrcPkg) {
			urlPrefix = "http://godoc.org"
			for _, path := range goPaths {
				p := filepath.Join(path, "src")
				if strings.HasPrefix(name, p) {
					pathPrefix = p
					break
				}
			}
		}
		thisFile := &File{
			fset:       fs,
			name:       name,
			ident:      ident,
			file:       parsedFile,
			pathPrefix: pathPrefix,
			urlPrefix:  urlPrefix,
			comments:   ast.NewCommentMap(fs, parsedFile, parsedFile.Comments),
		}
		files = append(files, thisFile)
		astFiles = append(astFiles, parsedFile)
	}
	for _, file := range files {
		if *packageFlag {
			file.pkgComments()
		} else {
			ast.Walk(file, file.file)
		}
	}
}

// Visit implements the ast.Visitor interface.
func (f *File) Visit(node ast.Node) ast.Visitor {
	switch n := node.(type) {
	case *ast.GenDecl:
		// Variables, constants, types.
		for _, spec := range n.Specs {
			switch spec := spec.(type) {
			case *ast.ValueSpec:
				if *constantFlag && n.Tok == token.CONST || *variableFlag && n.Tok == token.VAR {
					tag := "pkg-constants"
					if n.Tok == token.VAR {
						tag = "pkg-variables"
					}
					for _, ident := range spec.Names {
						if equal(ident.Name, f.ident) {
							f.printNode(n, n.Doc, f.nameURL(tag))
							break
						}
					}
				}
			case *ast.TypeSpec:
				if equal(spec.Name.Name, f.ident) {
					if *typeFlag {
						f.printNode(spec, spec.Doc, f.nameURL(spec.Name.Name))
						break
					}
					switch spec.Type.(type) {
					case *ast.InterfaceType:
						if *interfaceFlag {
							f.printNode(spec, spec.Doc, f.nameURL(spec.Name.Name))
						}
					case *ast.StructType:
						if *structFlag {
							f.printNode(spec, spec.Doc, f.nameURL(spec.Name.Name))
						}
					}
				}
			case *ast.ImportSpec:
				continue // Don't care.
			}
		}
	case *ast.FuncDecl:
		// Methods, top-level functions.
		if equal(n.Name.Name, f.ident) {
			n.Body = nil // Do not print the function body.
			if *methodFlag && n.Recv != nil {
				f.printNode(n, n.Doc, f.methodURL(n.Recv.List[0].Type, n.Name.Name))
			} else if *functionFlag && n.Recv == nil {
				f.printNode(n, n.Doc, f.nameURL(n.Name.Name))
			}
		}
	}
	return f
}

func equal(n1, n2 string) bool {
	// n1 must  be exported.
	r, _ := utf8.DecodeRuneInString(n1)
	if !unicode.IsUpper(r) {
		return false
	}
	return strings.ToLower(n1) == strings.ToLower(n2)
}

func (f *File) printNode(node ast.Node, comments *ast.CommentGroup, url string) {
	fmt.Printf("%s%s%s", url, f.sourcePos(f.fset.Position(node.Pos())), f.docs(node, comments))
}

func (f *File) docs(node ast.Node, comments *ast.CommentGroup) []byte {
	if !*docFlag {
		return nil
	}
	commentedNode := printer.CommentedNode{Node: node}
	if comments != nil {
		commentedNode.Comments = []*ast.CommentGroup{comments}
	}
	var b bytes.Buffer
	printer.Fprint(&b, f.fset, &commentedNode)
	b.Write([]byte("\n\n")) // Add a blank line between entries if we print documentation.
	return b.Bytes()
}

func (f *File) pkgComments() {
	doc := f.file.Doc
	if doc == nil {
		return
	}
	fmt.Printf("%spackage %s\n%s\n\n", f.packageURL(), f.sourcePos(f.fset.Position(doc.Pos())), f.file.Name.Name, doc.Text())
}

func (f *File) packageURL() string {
	s := strings.TrimPrefix(f.name, f.pathPrefix)
	// Now we have a path with a final file name. Drop it.
	if i := strings.LastIndex(s, slash); i > 0 {
		s = s[:i+1]
	}
	return f.urlPrefix + s
}

func (f *File) sourcePos(posn token.Position) string {
	if !*srcFlag {
		return ""
	}
	return fmt.Sprintf("%s:%d:\n", posn.Filename, posn.Line)
}

func (f *File) nameURL(name string) string {
	if !*urlFlag {
		return ""
	}
	return fmt.Sprintf("%s#%s\n", f.packageURL(), name)
}

func (f *File) methodURL(typ ast.Expr, name string) string {
	if !*urlFlag {
		return ""
	}
	var b bytes.Buffer
	printer.Fprint(&b, f.fset, typ)
	typeName := b.Bytes()
	if len(typeName) > 0 && typeName[0] == '*' {
		typeName = typeName[1:]
	}
	return fmt.Sprintf("%s#%s.%s\n", f.packageURL(), typeName, name)
}
<commit_msg>doc: fix flag handling for -pkg<commit_after>// Copyright 2013 The rspace Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Doc is a simple document printer that produces the doc comments for its
// argument symbols, plus a link to the full documentation and a pointer to
// the source. It has a more Go-like UI than godoc. It can also search for
// symbols by looking in all packages, and case is ignored. For instance:
//	doc isupper
// will find unicode.IsUpper.
//
// The -pkg flag retrieves package-level doc comments only.
//
// Usage:
//	doc pkg.name   # "doc io.Writer"
//	doc pkg name   # "doc fmt Printf"
//	doc name       # "doc isupper" (finds unicode.IsUpper)
//	doc -pkg pkg   # "doc fmt"
//
// The pkg is the last element of the package path;
// no slashes (ast.Node not go/ast.Node).
//
// Flags
//	-c(onst) -f(unc) -i(nterface) -m(ethod) -s(truct) -t(ype) -v(ar)
// restrict hits to declarations of the corresponding kind.
// Flags
//	-doc -src -url
// restrict printing to the documentation, source path, or godoc URL.
package main

import (
	"bytes"
	"flag"
	"fmt"
	"go/ast"
	"go/build"
	"go/parser"
	"go/printer"
	"go/token"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"runtime"
	"strings"
	"unicode"
	"unicode/utf8"
)

const usageDoc = `Find documentation for names.
usage:
	doc pkg.name   # "doc io.Writer"
	doc pkg name   # "doc fmt Printf"
	doc name       # "doc isupper" finds unicode.IsUpper
	doc -pkg pkg   # "doc fmt"
pkg is the last component of any package, e.g. fmt, parser
name is the name of an exported symbol; case is ignored in matches.
Flags
	-c(onst) -f(unc) -i(nterface) -m(ethod) -s(truct) -t(ype) -v(ar)
restrict hits to declarations of the corresponding kind.
Flags
	-doc -src -url
restrict printing to the documentation, source path, or godoc URL.
`

func usage() {
	fmt.Fprintf(os.Stderr, usageDoc)
	os.Exit(2)
}

var (
	// If none is set, all are set.
	constantFlag  = flag.Bool("const", false, "show doc for consts only")
	functionFlag  = flag.Bool("func", false, "show doc for funcs only")
	interfaceFlag = flag.Bool("interface", false, "show doc for interfaces only")
	methodFlag    = flag.Bool("method", false, "show doc for methods only")
	packageFlag   = flag.Bool("package", false, "show top-level package doc only")
	structFlag    = flag.Bool("struct", false, "show doc for structs only")
	typeFlag      = flag.Bool("type", false, "show doc for types only")
	variableFlag  = flag.Bool("var", false, "show  doc for vars only")
)

var (
	// If none is set, all are set.
	docFlag = flag.Bool("doc", false, "restrict output to documentation only")
	srcFlag = flag.Bool("src", false, "restrict output to source file only")
	urlFlag = flag.Bool("url", false, "restrict output to godoc URL only")
)

func init() {
	flag.BoolVar(constantFlag, "c", false, "alias for -const")
	flag.BoolVar(functionFlag, "f", false, "alias for -func")
	flag.BoolVar(interfaceFlag, "i", false, "alias for -interface")
	flag.BoolVar(methodFlag, "m", false, "alias for -method")
	flag.BoolVar(packageFlag, "pkg", false, "alias for -package")
	flag.BoolVar(structFlag, "s", false, "alias for -struct")
	flag.BoolVar(typeFlag, "t", false, "alias for -type")
	flag.BoolVar(variableFlag, "v", false, "alias for -var")
}

func main() {
	flag.Parse()
	if !(*constantFlag || *functionFlag || *interfaceFlag || *methodFlag || *packageFlag || *structFlag || *typeFlag || *variableFlag) { // none set
		*constantFlag = true
		*functionFlag = true
		*methodFlag = true
		// Not package! It's special.
		*typeFlag = true
		*variableFlag = true
	}
	if !(*docFlag || *srcFlag || *urlFlag) {
		*docFlag = true
		*srcFlag = true
		*urlFlag = true
	}
	var pkg, name string
	switch flag.NArg() {
	case 1:
		if *packageFlag {
			pkg = flag.Arg(0)
		} else if strings.Contains(flag.Arg(0), ".") {
			pkg, name = split(flag.Arg(0))
		} else {
			name = flag.Arg(0)
		}
	case 2:
		if *packageFlag {
			usage()
		}
		pkg, name = flag.Arg(0), flag.Arg(1)
	default:
		usage()
	}
	for _, path := range paths(pkg) {
		lookInDirectory(path, name)
	}
}

var slash = string(filepath.Separator)
var slashDot = string(filepath.Separator) + "."
var goRootSrcPkg = filepath.Join(runtime.GOROOT(), "src", "pkg")
var goPaths = splitGopath()

func split(arg string) (pkg, name string) {
	str := strings.Split(arg, ".")
	if len(str) != 2 {
		usage()
	}
	return str[0], str[1]
}

func paths(pkg string) []string {
	pkgs := pathsFor(runtime.GOROOT(), pkg)
	for _, root := range goPaths {
		pkgs = append(pkgs, pathsFor(root, pkg)...)
	}
	return pkgs
}

func splitGopath() []string {
	gopath := os.Getenv("GOPATH")
	if gopath == "" {
		return nil
	}
	return strings.Split(gopath, string(os.PathListSeparator))
}

// pathsFor recursively walks the tree looking for possible directories for the package:
// those whose basename is pkg.
func pathsFor(root, pkg string) []string {
	root = path.Join(root, "src")
	pkgPaths := make([]string, 0, 10)
	visit := func(pathName string, f os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		// One package per directory. Ignore the files themselves.
		if !f.IsDir() {
			return nil
		}
		// No .hg or other dot nonsense please.
		if strings.Contains(pathName, slashDot) {
			return filepath.SkipDir
		}
		// Is the last element of the path correct
		if pkg == "" || filepath.Base(pathName) == pkg {
			pkgPaths = append(pkgPaths, pathName)
		}
		return nil
	}

	filepath.Walk(root, visit)
	return pkgPaths
}

// lookInDirectory looks in the package (if any) in the directory for the named exported identifier.
func lookInDirectory(directory, name string) {
	pkg, err := build.Default.ImportDir(directory, 0)
	if err != nil {
		// If it's just that there are no go source files, that's fine.
		if _, nogo := err.(*build.NoGoError); nogo {
			return
		}
		// Non-fatal: we are doing a recursive walk and there may be other directories.
		return
	}
	var fileNames []string
	fileNames = append(fileNames, pkg.GoFiles...)
	prefixDirectory(directory, fileNames)
	doPackage(fileNames, name)
}

// prefixDirectory places the directory name on the beginning of each name in the list.
func prefixDirectory(directory string, names []string) {
	if directory != "." {
		for i, name := range names {
			names[i] = filepath.Join(directory, name)
		}
	}
}

// File is a wrapper for the state of a file used in the parser.
// The parse tree walkers are all methods of this type.
type File struct {
	fset       *token.FileSet
	name       string
	ident      string
	pathPrefix string
	urlPrefix  string
	file       *ast.File
	comments   ast.CommentMap
}

// doPackage analyzes the single package constructed from the named files, looking for
// the definition of ident.
func doPackage(fileNames []string, ident string) {
	var files []*File
	var astFiles []*ast.File
	fs := token.NewFileSet()
	for _, name := range fileNames {
		f, err := os.Open(name)
		if err != nil {
			// Warn but continue to next package.
			fmt.Fprintf(os.Stderr, "%s: %s", name, err)
			return
		}
		defer f.Close()
		data, err := ioutil.ReadAll(f)
		if err != nil {
			fmt.Fprintf(os.Stderr, "%s: %s", name, err)
			return
		}
		parsedFile, err := parser.ParseFile(fs, name, bytes.NewReader(data), parser.ParseComments)
		if err != nil {
			// Noisy - just ignore.
			// fmt.Fprintf(os.Stderr, "%s: %s", name, err)
			return
		}
		urlPrefix := "http://golang.org/pkg"
		pathPrefix := goRootSrcPkg
		if !strings.HasPrefix(name, goRootSrcPkg) {
			urlPrefix = "http://godoc.org"
			for _, path := range goPaths {
				p := filepath.Join(path, "src")
				if strings.HasPrefix(name, p) {
					pathPrefix = p
					break
				}
			}
		}
		thisFile := &File{
			fset:       fs,
			name:       name,
			ident:      ident,
			file:       parsedFile,
			pathPrefix: pathPrefix,
			urlPrefix:  urlPrefix,
			comments:   ast.NewCommentMap(fs, parsedFile, parsedFile.Comments),
		}
		files = append(files, thisFile)
		astFiles = append(astFiles, parsedFile)
	}
	for _, file := range files {
		if *packageFlag {
			file.pkgComments()
		} else {
			ast.Walk(file, file.file)
		}
	}
}

// Visit implements the ast.Visitor interface.
func (f *File) Visit(node ast.Node) ast.Visitor {
	switch n := node.(type) {
	case *ast.GenDecl:
		// Variables, constants, types.
		for _, spec := range n.Specs {
			switch spec := spec.(type) {
			case *ast.ValueSpec:
				if *constantFlag && n.Tok == token.CONST || *variableFlag && n.Tok == token.VAR {
					tag := "pkg-constants"
					if n.Tok == token.VAR {
						tag = "pkg-variables"
					}
					for _, ident := range spec.Names {
						if equal(ident.Name, f.ident) {
							f.printNode(n, n.Doc, f.nameURL(tag))
							break
						}
					}
				}
			case *ast.TypeSpec:
				if equal(spec.Name.Name, f.ident) {
					if *typeFlag {
						f.printNode(spec, spec.Doc, f.nameURL(spec.Name.Name))
						break
					}
					switch spec.Type.(type) {
					case *ast.InterfaceType:
						if *interfaceFlag {
							f.printNode(spec, spec.Doc, f.nameURL(spec.Name.Name))
						}
					case *ast.StructType:
						if *structFlag {
							f.printNode(spec, spec.Doc, f.nameURL(spec.Name.Name))
						}
					}
				}
			case *ast.ImportSpec:
				continue // Don't care.
			}
		}
	case *ast.FuncDecl:
		// Methods, top-level functions.
		if equal(n.Name.Name, f.ident) {
			n.Body = nil // Do not print the function body.
			if *methodFlag && n.Recv != nil {
				f.printNode(n, n.Doc, f.methodURL(n.Recv.List[0].Type, n.Name.Name))
			} else if *functionFlag && n.Recv == nil {
				f.printNode(n, n.Doc, f.nameURL(n.Name.Name))
			}
		}
	}
	return f
}

func equal(n1, n2 string) bool {
	// n1 must  be exported.
	r, _ := utf8.DecodeRuneInString(n1)
	if !unicode.IsUpper(r) {
		return false
	}
	return strings.ToLower(n1) == strings.ToLower(n2)
}

func (f *File) printNode(node ast.Node, comments *ast.CommentGroup, url string) {
	fmt.Printf("%s%s%s", url, f.sourcePos(f.fset.Position(node.Pos())), f.docs(node, comments))
}

func (f *File) docs(node ast.Node, comments *ast.CommentGroup) []byte {
	if !*docFlag {
		return nil
	}
	commentedNode := printer.CommentedNode{Node: node}
	if comments != nil {
		commentedNode.Comments = []*ast.CommentGroup{comments}
	}
	var b bytes.Buffer
	printer.Fprint(&b, f.fset, &commentedNode)
	b.Write([]byte("\n\n")) // Add a blank line between entries if we print documentation.
	return b.Bytes()
}

func (f *File) pkgComments() {
	doc := f.file.Doc
	if doc == nil {
		return
	}
	url := ""
	if *urlFlag {
		url = f.packageURL() + "\n"
	}
	docText := ""
	if *docFlag {
		docText = fmt.Sprintf("package %s\n%s\n\n", f.file.Name.Name, doc.Text())
	}
	fmt.Printf("%s%s%s", url, f.sourcePos(f.fset.Position(doc.Pos())), docText)
}

func (f *File) packageURL() string {
	s := strings.TrimPrefix(f.name, f.pathPrefix)
	// Now we have a path with a final file name. Drop it.
	if i := strings.LastIndex(s, slash); i > 0 {
		s = s[:i+1]
	}
	return f.urlPrefix + s
}

func (f *File) sourcePos(posn token.Position) string {
	if !*srcFlag {
		return ""
	}
	return fmt.Sprintf("%s:%d:\n", posn.Filename, posn.Line)
}

func (f *File) nameURL(name string) string {
	if !*urlFlag {
		return ""
	}
	return fmt.Sprintf("%s#%s\n", f.packageURL(), name)
}

func (f *File) methodURL(typ ast.Expr, name string) string {
	if !*urlFlag {
		return ""
	}
	var b bytes.Buffer
	printer.Fprint(&b, f.fset, typ)
	typeName := b.Bytes()
	if len(typeName) > 0 && typeName[0] == '*' {
		typeName = typeName[1:]
	}
	return fmt.Sprintf("%s#%s.%s\n", f.packageURL(), typeName, name)
}
<|endoftext|>


<commit_before>package temple

import (
	"bytes"
	"honnef.co/go/js/dom"
)

func ExecuteToEl(e Executor, el dom.Element, data interface{}) error {
	// TODO: use a buffer pool
	buf := bytes.NewBuffer([]byte{})
	if err := e.Execute(buf, data); err != nil {
		return err
	}
	el.SetInnerHTML(buf.String())
	return nil
}

func (t *Template) ExecuteToEl(el dom.Element, data interface{}) error {
	return ExecuteToEl(t, el, data)
}

func (p *Partial) ExecuteToEl(el dom.Element, data interface{}) error {
	return ExecuteToEl(p, el, data)
}

func (l *Layout) ExecuteToEl(el dom.Element, data interface{}) error {
	return ExecuteToEl(l, el, data)
}

func AddInlineTemplates() error {
	document := dom.GetWindow().Document()
	elements := document.QuerySelectorAll(`script[type="text/template"]`)
	for _, el := range elements {
		switch el.GetAttribute("data-kind") {
		case "template":
			if err := AddInlineTemplate(el); err != nil {
				return err
			}
		case "partial":
			if err := AddInlinePartial(el); err != nil {
				return err
			}
		case "layout":
			if err := AddInlineLayout(el); err != nil {
				return err
			}
		default:
			if err := AddInlineTemplate(el); err != nil {
				return err
			}
		}
	}
	return nil
}

func AddInlineTemplate(el dom.Element) error {
	return AddTemplate(el.ID(), el.InnerHTML())
}

func AddInlinePartial(el dom.Element) error {
	return AddPartial(el.ID(), el.InnerHTML())
}

func AddInlineLayout(el dom.Element) error {
	return AddLayout(el.ID(), el.InnerHTML())
}
<commit_msg>Rename AddInlineTemplates to ParseInlineTemplates<commit_after>package temple

import (
	"bytes"
	"honnef.co/go/js/dom"
)

func ExecuteToEl(e Executor, el dom.Element, data interface{}) error {
	// TODO: use a buffer pool
	buf := bytes.NewBuffer([]byte{})
	if err := e.Execute(buf, data); err != nil {
		return err
	}
	el.SetInnerHTML(buf.String())
	return nil
}

func (t *Template) ExecuteToEl(el dom.Element, data interface{}) error {
	return ExecuteToEl(t, el, data)
}

func (p *Partial) ExecuteToEl(el dom.Element, data interface{}) error {
	return ExecuteToEl(p, el, data)
}

func (l *Layout) ExecuteToEl(el dom.Element, data interface{}) error {
	return ExecuteToEl(l, el, data)
}

func ParseInlineTemplates() error {
	document := dom.GetWindow().Document()
	elements := document.QuerySelectorAll(`script[type="text/template"]`)
	for _, el := range elements {
		switch el.GetAttribute("data-kind") {
		case "template":
			if err := AddInlineTemplate(el); err != nil {
				return err
			}
		case "partial":
			if err := AddInlinePartial(el); err != nil {
				return err
			}
		case "layout":
			if err := AddInlineLayout(el); err != nil {
				return err
			}
		default:
			if err := AddInlineTemplate(el); err != nil {
				return err
			}
		}
	}
	return nil
}

func AddInlineTemplate(el dom.Element) error {
	return AddTemplate(el.ID(), el.InnerHTML())
}

func AddInlinePartial(el dom.Element) error {
	return AddPartial(el.ID(), el.InnerHTML())
}

func AddInlineLayout(el dom.Element) error {
	return AddLayout(el.ID(), el.InnerHTML())
}
<|endoftext|>


<commit_before>package libkb

func getUsernameIfProvisioned(m MetaContext, uc UserConfig) (ret NormalizedUsername, err error) {
	m.Debug("getUsernameIfProvisioned(%+v)", uc)
	did := uc.GetDeviceID()
	if did.IsNil() {
		m.Debug("- no valid username since nil deviceID")
		return ret, nil
	}
	err = checkDeviceValidForUID(m.Ctx(), m.G().GetUPAKLoader(), uc.GetUID(), did)
	switch err.(type) {
	case nil:
		m.Debug("- checks out")
		return uc.GetUsername(), nil
	case DeviceNotFoundError:
		m.Debug("- user was likely reset (%s)", err)
		return ret, nil
	case KeyRevokedError:
		m.Debug("- device was revoked (%s)", err)
		return ret, nil
	case UserDeletedError:
		m.Debug(" - user was deleted (%s)", err)
		return ret, nil
	case NotFoundError:
		// This can happen in development if the dev db is nuked or a mobile
		// device is connected to dev servers.
		m.Debug(" - user wasn't found (%s)", err)
		return ret, nil
	default:
		m.Debug("- unexpected error; propagating (%s)", err)
		return ret, err
	}
}

// GetAllProvisionedUsernames looks into the current config.json file, and finds all usernames
// that are currently provisioned on this device. That is, it filters out those that are on revoked
// devices or have reset their accounts. It uses UPAK loading for verifying the current user/device
// statuses, so should be fast if everything is cached recently.
func GetAllProvisionedUsernames(m MetaContext) (current NormalizedUsername, all []NormalizedUsername, err error) {

	m = m.WithLogTag("GAPU")
	defer m.Trace("GetAllProvisionedUsernames", func() error { return err })()

	currentUC, allUCs, err := m.G().Env.GetConfig().GetAllUserConfigs()
	if err != nil {
		return current, nil, err
	}

	if currentUC != nil {
		current, err = getUsernameIfProvisioned(m, *currentUC)
		if err != nil {
			m.Error("Error while checking user %q uid=%q, `current` will be nil", currentUC.GetUsername(), currentUC.GetUID())
		}
	}

	for _, uc := range allUCs {
		tmp, err := getUsernameIfProvisioned(m, uc)
		if err != nil {
			m.Error("Error while checking user %q uid=%q, skipping", uc.GetUsername(), uc.GetUID())
			continue
		}
		if !tmp.IsNil() {
			all = append(all, tmp)
		}
	}

	return current, all, nil
}
<commit_msg>server driven gapu (#18962)<commit_after>package libkb

import (
	"time"

	"github.com/davecgh/go-spew/spew"
	"github.com/keybase/client/go/protocol/keybase1"
)

func getUsernameIfProvisioned(m MetaContext, uc UserConfig) (ret NormalizedUsername, err error) {
	m.Debug("getUsernameIfProvisioned(%+v)", uc)
	did := uc.GetDeviceID()
	if did.IsNil() {
		m.Debug("- no valid username since nil deviceID")
		return ret, nil
	}
	err = checkDeviceValidForUID(m.Ctx(), m.G().GetUPAKLoader(), uc.GetUID(), did)
	switch err.(type) {
	case nil:
		m.Debug("- checks out")
		return uc.GetUsername(), nil
	case DeviceNotFoundError:
		m.Debug("- user was likely reset (%s)", err)
		return ret, nil
	case KeyRevokedError:
		m.Debug("- device was revoked (%s)", err)
		return ret, nil
	case UserDeletedError:
		m.Debug(" - user was deleted (%s)", err)
		return ret, nil
	case NotFoundError:
		// This can happen in development if the dev db is nuked or a mobile
		// device is connected to dev servers.
		m.Debug(" - user wasn't found (%s)", err)
		return ret, nil
	default:
		m.Debug("- unexpected error; propagating (%s)", err)
		return ret, err
	}
}

type deviceForUsersRet struct {
	AppStatusEmbed
	UserConfigs []deviceForUser `json:"user_configs"`
}
type deviceForUser struct {
	UID      keybase1.UID       `json:"uid"`
	DeviceID keybase1.DeviceID  `json:"device_id"`
	OK       bool               `json:"ok"`
	Username NormalizedUsername `json:"username"`
}

// GetAllProvisionedUsernames looks into the current config.json file, and
// finds all usernames that are currently provisioned on this device. Then, it
// asks the server to filter out revoked devices or reset users.
func GetAllProvisionedUsernames(mctx MetaContext) (current NormalizedUsername, all []NormalizedUsername, err error) {
	mctx = mctx.WithLogTag("GAPU")
	defer mctx.Trace("GetAllProvisionedUsernames", func() error { return err })()

	currentUC, allUCs, err := mctx.G().Env.GetConfig().GetAllUserConfigs()
	if err != nil {
		return current, nil, err
	}

	var userConfigs []deviceForUser
	if currentUC != nil {
		userConfigs = append(userConfigs, deviceForUser{UID: currentUC.GetUID(), DeviceID: currentUC.GetDeviceID()})
	}
	for _, uc := range allUCs {
		userConfigs = append(userConfigs, deviceForUser{UID: uc.GetUID(), DeviceID: uc.GetDeviceID()})
	}

	if len(userConfigs) == 0 {
		mctx.Debug("GAPU: no userConfigs to lookup")
		return current, nil, nil
	}

	payload := make(JSONPayload)
	payload["user_configs"] = userConfigs
	spew.Dump(payload)
	arg := APIArg{
		Endpoint:       "device/for_users",
		JSONPayload:    payload,
		SessionType:    APISessionTypeNONE,
		InitialTimeout: 5 * time.Second,
		RetryCount:     3,
	}

	resp := deviceForUsersRet{}
	err = mctx.G().API.PostDecode(mctx, arg, &resp)
	if err != nil {
		return "", nil, err
	}

	for _, userConfig := range resp.UserConfigs {
		if userConfig.OK {
			all = append(all, userConfig.Username)
			if userConfig.Username == currentUC.GetUsername() {
				current = userConfig.Username
			}
		}
	}

	return current, all, nil
}
<|endoftext|>