<commit_before>package isolated

import (
	"fmt"

	. "code.cloudfoundry.org/cli/cf/util/testhelpers/matchers"
	"code.cloudfoundry.org/cli/integration/helpers"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
)

var _ = Describe("route command", func() {
	Context("Help", func() {
		It("appears in cf help -a", func() {
			session := helpers.CF("help", "-a")
			Eventually(session).Should(Exit(0))
			Expect(session).To(HaveCommandInCategoryWithDescription("route", "ROUTES", "Display route details and mapped destinations"))
		})

		It("displays the help information", func() {
			session := helpers.CF("route", "--help")
			Eventually(session).Should(Say(`NAME:`))
			Eventually(session).Should(Say(`route - Display route details and mapped destinations`))
			Eventually(session).Should(Say(`\n`))

			Eventually(session).Should(Say(`USAGE:`))
			Eventually(session).Should(Say(`Display an HTTP route:`))
			Eventually(session).Should(Say(`cf route DOMAIN \[--hostname HOSTNAME\] \[--path PATH\]\n`))
			Eventually(session).Should(Say(`Display a TCP route:`))
			Eventually(session).Should(Say(`cf route DOMAIN --port PORT\n`))
			Eventually(session).Should(Say(`\n`))

			Eventually(session).Should(Say(`EXAMPLES:`))
			Eventually(session).Should(Say(`cf route example.com                      # example.com`))
			Eventually(session).Should(Say(`cf route example.com -n myhost --path foo # myhost.example.com/foo`))
			Eventually(session).Should(Say(`cf route example.com --path foo           # example.com/foo`))
			Eventually(session).Should(Say(`cf route example.com --port 5000          # example.com:5000`))
			Eventually(session).Should(Say(`\n`))

			Eventually(session).Should(Say(`OPTIONS:`))
			Eventually(session).Should(Say(`--hostname, -n\s+Hostname used to identify the HTTP route`))
			Eventually(session).Should(Say(`--path\s+Path used to identify the HTTP route`))
			Eventually(session).Should(Say(`--port\s+Port used to identify the TCP route`))
			Eventually(session).Should(Say(`\n`))

			Eventually(session).Should(Say(`SEE ALSO:`))
			Eventually(session).Should(Say(`create-route, delete-route, routes`))

			Eventually(session).Should(Exit(0))
		})
	})

	When("the environment is not setup correctly", func() {
		It("fails with the appropriate errors", func() {
			helpers.CheckEnvironmentTargetedCorrectly(true, false, ReadOnlyOrg, "route", "some-domain")
		})
	})

	When("the environment is set up correctly", func() {
		var (
			userName  string
			orgName   string
			spaceName string
		)

		BeforeEach(func() {
			orgName = helpers.NewOrgName()
			spaceName = helpers.NewSpaceName()

			helpers.SetupCF(orgName, spaceName)
			userName, _ = helpers.GetCredentials()
		})

		AfterEach(func() {
			helpers.QuickDeleteOrg(orgName)
		})

		When("the domain exists", func() {
			var (
				domainName string
			)

			BeforeEach(func() {
				domainName = helpers.NewDomainName()
			})

			When("the route exists", func() {
				var (
					domain   helpers.Domain
					hostname string
					path     string
				)

				When("it's an HTTP route", func() {
					BeforeEach(func() {
						domain = helpers.NewDomain(orgName, domainName)
						hostname = "key-lime-pie"
						path = "/some-path"
						domain.CreatePrivate()
						Eventually(helpers.CF("create-app", "killer")).Should(Exit(0))
						Eventually(helpers.CF("create-route", domain.Name, "--hostname", hostname, "--path", path)).Should(Exit(0))
						Eventually(helpers.CF("map-route", "killer", domain.Name, "--hostname", hostname, "--path", path)).Should(Exit(0))
					})

					AfterEach(func() {
						domain.Delete()
					})

					It("displays the route summary and exits without failing", func() {
						session := helpers.CF("route", domainName, "--hostname", hostname, "--path", path)
						Eventually(session).Should(Say(`Showing route %s\.%s%s in org %s / space %s as %s\.\.\.`, hostname, domainName, path, orgName, spaceName, userName))
						Eventually(session).Should(Say(`domain:\s+%s`, domainName))
						Eventually(session).Should(Say(`host:\s+%s`, hostname))
						Eventually(session).Should(Say(`port:\s+\n`))
						Eventually(session).Should(Say(`path:\s+%s`, path))
						Eventually(session).Should(Say(`protocol:\s+http`))
						Eventually(session).Should(Say(`\n`))
						Eventually(session).Should(Say(`Destinations:`))
						Eventually(session).Should(Say(`\s+app\s+process\s+port\s+protocol`))
						Eventually(session).Should(Say(`\s+killer\s+web\s+8080\s+http1`))
						Eventually(session).Should(Exit(0))
					})
				})

				When("it's a TCP route", func() {
					var (
						routerGroup helpers.RouterGroup
						port        int
						tcpDomain   helpers.Domain
					)

					BeforeEach(func() {
						routerGroup = helpers.NewRouterGroup(helpers.NewRouterGroupName(), "1024-2048")
						routerGroup.Create()

						tcpDomain = helpers.NewDomain(orgName, helpers.NewDomainName("TCP-DOMAIN"))
						tcpDomain.CreateWithRouterGroup(routerGroup.Name)

						port = 1024

						Eventually(helpers.CF("create-app", "killer")).Should(Exit(0))
						Eventually(helpers.CF("create-route", tcpDomain.Name, "--port", fmt.Sprintf("%d", port))).Should(Exit(0))
						Eventually(helpers.CF("map-route", "killer", tcpDomain.Name, "--port", "1024")).Should(Exit(0))
					})

					AfterEach(func() {
						tcpDomain.DeleteShared()
						routerGroup.Delete()
					})

					It("displays the route summary and exits without failing", func() {
						session := helpers.CF("route", tcpDomain.Name, "--port", fmt.Sprintf("%d", port))
						Eventually(session).Should(Say(`Showing route %s:%d in org %s / space %s as %s\.\.\.`, tcpDomain.Name, port, orgName, spaceName, userName))
						Eventually(session).Should(Say(`domain:\s+%s`, tcpDomain.Name))
						Eventually(session).Should(Say(`host:\s+\n`))
						Eventually(session).Should(Say(`port:\s+%d`, port))
						Eventually(session).Should(Say(`path:\s+\n`))
						Eventually(session).Should(Say(`protocol:\s+tcp`))
						Eventually(session).Should(Say(`\n`))
						Eventually(session).Should(Say(`Destinations:`))
						Eventually(session).Should(Say(`\s+app\s+process\s+port\s+protocol`))
						Eventually(session).Should(Say(`\s+killer\s+web\s+8080\s+tcp`))
						Eventually(session).Should(Exit(0))
					})
				})
			})

			When("the route does not exist", func() {
				var domain helpers.Domain

				BeforeEach(func() {
					domain = helpers.NewDomain(orgName, domainName)
					domain.Create()
				})

				AfterEach(func() {
					domain.Delete()
				})

				When("no flags are used", func() {
					It("checks the route", func() {
						session := helpers.CF("route", domainName)
						Eventually(session).Should(Say(`Showing route %s in org %s / space %s as %s\.\.\.`, domainName, orgName, spaceName, userName))
						Eventually(session.Err).Should(Say(`Route with host '', domain '%s', and path '/' not found\.`, domainName))
						Eventually(session).Should(Exit(1))
					})
				})

				When("passing in a hostname", func() {
					It("checks the route with the hostname", func() {
						hostname := "tiramisu"
						session := helpers.CF("route", domainName, "-n", hostname)
						Eventually(session).Should(Say(`Showing route %s.%s in org %s / space %s as %s\.\.\.`, hostname, domainName, orgName, spaceName, userName))
						Eventually(session.Err).Should(Say(`Route with host '%s', domain '%s', and path '/' not found\.`, hostname, domainName))
						Eventually(session).Should(Exit(1))
					})
				})

				When("passing in hostname and path with a leading '/'", func() {
					It("checks the route with hostname and path", func() {
						hostname := "tiramisu"
						pathString := "/recipes"
						session := helpers.CF("route", domainName, "-n", hostname, "--path", pathString)
						Eventually(session).Should(Say(`Showing route %s.%s%s in org %s / space %s as %s\.\.\.`, hostname, domainName, pathString, orgName, spaceName, userName))
						Eventually(session.Err).Should(Say(`Route with host '%s', domain '%s', and path '%s' not found`, hostname, domainName, pathString))
						Eventually(session).Should(Exit(1))
					})
				})
			})
		})

		When("the domain does not exist", func() {
			It("displays error and exits 1", func() {
				session := helpers.CF("route", "some-domain")
				Eventually(session).Should(Say(`FAILED`))
				Eventually(session.Err).Should(Say(`Domain 'some-domain' not found.`))
				Eventually(session).Should(Exit(1))
			})
		})

		When("the domain is not specified", func() {
			It("displays error and exits 1", func() {
				session := helpers.CF("route")
				Eventually(session.Err).Should(Say("Incorrect Usage: the required argument `DOMAIN` was not provided\n"))
				Eventually(session.Err).Should(Say("\n"))
				Eventually(session).Should(Say("NAME:\n"))
				Eventually(session).Should(Exit(1))
			})
		})
	})
})
<commit_msg>Refactoring route command integration test<commit_after>package isolated

import (
	"fmt"

	"code.cloudfoundry.org/cli/api/cloudcontroller/ccversion"
	. "code.cloudfoundry.org/cli/cf/util/testhelpers/matchers"
	"code.cloudfoundry.org/cli/integration/helpers"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
)

var _ = Describe("route command", func() {
	Context("Help", func() {
		It("appears in cf help -a", func() {
			session := helpers.CF("help", "-a")
			Eventually(session).Should(Exit(0))
			Expect(session).To(HaveCommandInCategoryWithDescription("route", "ROUTES", "Display route details and mapped destinations"))
		})

		It("displays the help information", func() {
			session := helpers.CF("route", "--help")
			Eventually(session).Should(Say(`NAME:`))
			Eventually(session).Should(Say(`route - Display route details and mapped destinations`))
			Eventually(session).Should(Say(`\n`))

			Eventually(session).Should(Say(`USAGE:`))
			Eventually(session).Should(Say(`Display an HTTP route:`))
			Eventually(session).Should(Say(`cf route DOMAIN \[--hostname HOSTNAME\] \[--path PATH\]\n`))
			Eventually(session).Should(Say(`Display a TCP route:`))
			Eventually(session).Should(Say(`cf route DOMAIN --port PORT\n`))
			Eventually(session).Should(Say(`\n`))

			Eventually(session).Should(Say(`EXAMPLES:`))
			Eventually(session).Should(Say(`cf route example.com                      # example.com`))
			Eventually(session).Should(Say(`cf route example.com -n myhost --path foo # myhost.example.com/foo`))
			Eventually(session).Should(Say(`cf route example.com --path foo           # example.com/foo`))
			Eventually(session).Should(Say(`cf route example.com --port 5000          # example.com:5000`))
			Eventually(session).Should(Say(`\n`))

			Eventually(session).Should(Say(`OPTIONS:`))
			Eventually(session).Should(Say(`--hostname, -n\s+Hostname used to identify the HTTP route`))
			Eventually(session).Should(Say(`--path\s+Path used to identify the HTTP route`))
			Eventually(session).Should(Say(`--port\s+Port used to identify the TCP route`))
			Eventually(session).Should(Say(`\n`))

			Eventually(session).Should(Say(`SEE ALSO:`))
			Eventually(session).Should(Say(`create-route, delete-route, routes`))

			Eventually(session).Should(Exit(0))
		})
	})

	When("the environment is not setup correctly", func() {
		It("fails with the appropriate errors", func() {
			helpers.CheckEnvironmentTargetedCorrectly(true, false, ReadOnlyOrg, "route", "some-domain")
		})
	})

	When("the environment is set up correctly", func() {
		var (
			userName  string
			orgName   string
			spaceName string
		)

		BeforeEach(func() {
			orgName = helpers.NewOrgName()
			spaceName = helpers.NewSpaceName()

			helpers.SetupCF(orgName, spaceName)
			userName, _ = helpers.GetCredentials()
		})

		AfterEach(func() {
			helpers.QuickDeleteOrg(orgName)
		})

		When("the domain exists", func() {
			var (
				domainName string
			)

			BeforeEach(func() {
				domainName = helpers.NewDomainName()
			})

			When("the route exists", func() {
				var (
					domain   helpers.Domain
					hostname string
					path     string
				)

				When("it's an HTTP route", func() {
					BeforeEach(func() {
						domain = helpers.NewDomain(orgName, domainName)
						hostname = "key-lime-pie"
						path = "/some-path"
						domain.CreatePrivate()
						Eventually(helpers.CF("create-app", "killer")).Should(Exit(0))
						Eventually(helpers.CF("create-route", domain.Name, "--hostname", hostname, "--path", path)).Should(Exit(0))
						Eventually(helpers.CF("map-route", "killer", domain.Name, "--hostname", hostname, "--path", path)).Should(Exit(0))
					})

					AfterEach(func() {
						domain.Delete()
					})

					It("displays the route summary and exits without failing", func() {
						session := helpers.CF("route", domainName, "--hostname", hostname, "--path", path)
						Eventually(session).Should(Say(`Showing route %s\.%s%s in org %s / space %s as %s\.\.\.`, hostname, domainName, path, orgName, spaceName, userName))
						Eventually(session).Should(Say(`domain:\s+%s`, domainName))
						Eventually(session).Should(Say(`host:\s+%s`, hostname))
						Eventually(session).Should(Say(`port:\s+\n`))
						Eventually(session).Should(Say(`path:\s+%s`, path))
						Eventually(session).Should(Say(`protocol:\s+http`))
						Eventually(session).Should(Say(`\n`))
						Eventually(session).Should(Say(`Destinations:`))
						Eventually(session).Should(Say(`\s+app\s+process\s+port\s+protocol`))
						Eventually(session).Should(Exit(0))
					})

					It("displays the protocol in the route summary and exits without failing", func() {
						helpers.SkipIfVersionLessThan(ccversion.MinVersionHTTP2RoutingV3)
						session := helpers.CF("route", domainName, "--hostname", hostname, "--path", path)
						Eventually(session).Should(Say(`\s+killer\s+web\s+8080\s+http1`))
						Eventually(session).Should(Exit(0))
					})
				})

				When("it's a TCP route", func() {
					var (
						routerGroup helpers.RouterGroup
						port        int
						tcpDomain   helpers.Domain
					)

					BeforeEach(func() {
						routerGroup = helpers.NewRouterGroup(helpers.NewRouterGroupName(), "1024-2048")
						routerGroup.Create()

						tcpDomain = helpers.NewDomain(orgName, helpers.NewDomainName("TCP-DOMAIN"))
						tcpDomain.CreateWithRouterGroup(routerGroup.Name)

						port = 1024

						Eventually(helpers.CF("create-app", "killer")).Should(Exit(0))
						Eventually(helpers.CF("create-route", tcpDomain.Name, "--port", fmt.Sprintf("%d", port))).Should(Exit(0))
						Eventually(helpers.CF("map-route", "killer", tcpDomain.Name, "--port", "1024")).Should(Exit(0))
					})

					AfterEach(func() {
						tcpDomain.DeleteShared()
						routerGroup.Delete()
					})

					It("displays the route summary and exits without failing", func() {
						session := helpers.CF("route", tcpDomain.Name, "--port", fmt.Sprintf("%d", port))
						Eventually(session).Should(Say(`Showing route %s:%d in org %s / space %s as %s\.\.\.`, tcpDomain.Name, port, orgName, spaceName, userName))
						Eventually(session).Should(Say(`domain:\s+%s`, tcpDomain.Name))
						Eventually(session).Should(Say(`host:\s+\n`))
						Eventually(session).Should(Say(`port:\s+%d`, port))
						Eventually(session).Should(Say(`path:\s+\n`))
						Eventually(session).Should(Say(`protocol:\s+tcp`))
						Eventually(session).Should(Say(`\n`))
						Eventually(session).Should(Say(`Destinations:`))
						Eventually(session).Should(Say(`\s+app\s+process\s+port\s+protocol`))
						Eventually(session).Should(Exit(0))
					})

					It("displays the protocol in the route summary and exits without failing", func() {
						helpers.SkipIfVersionLessThan(ccversion.MinVersionHTTP2RoutingV3)
						session := helpers.CF("route", tcpDomain.Name, "--port", fmt.Sprintf("%d", port))
						Eventually(session).Should(Say(`\s+killer\s+web\s+8080\s+tcp`))
						Eventually(session).Should(Exit(0))
					})
				})
			})

			When("the route does not exist", func() {
				var domain helpers.Domain

				BeforeEach(func() {
					domain = helpers.NewDomain(orgName, domainName)
					domain.Create()
				})

				AfterEach(func() {
					domain.Delete()
				})

				When("no flags are used", func() {
					It("checks the route", func() {
						session := helpers.CF("route", domainName)
						Eventually(session).Should(Say(`Showing route %s in org %s / space %s as %s\.\.\.`, domainName, orgName, spaceName, userName))
						Eventually(session.Err).Should(Say(`Route with host '', domain '%s', and path '/' not found\.`, domainName))
						Eventually(session).Should(Exit(1))
					})
				})

				When("passing in a hostname", func() {
					It("checks the route with the hostname", func() {
						hostname := "tiramisu"
						session := helpers.CF("route", domainName, "-n", hostname)
						Eventually(session).Should(Say(`Showing route %s.%s in org %s / space %s as %s\.\.\.`, hostname, domainName, orgName, spaceName, userName))
						Eventually(session.Err).Should(Say(`Route with host '%s', domain '%s', and path '/' not found\.`, hostname, domainName))
						Eventually(session).Should(Exit(1))
					})
				})

				When("passing in hostname and path with a leading '/'", func() {
					It("checks the route with hostname and path", func() {
						hostname := "tiramisu"
						pathString := "/recipes"
						session := helpers.CF("route", domainName, "-n", hostname, "--path", pathString)
						Eventually(session).Should(Say(`Showing route %s.%s%s in org %s / space %s as %s\.\.\.`, hostname, domainName, pathString, orgName, spaceName, userName))
						Eventually(session.Err).Should(Say(`Route with host '%s', domain '%s', and path '%s' not found`, hostname, domainName, pathString))
						Eventually(session).Should(Exit(1))
					})
				})
			})
		})

		When("the domain does not exist", func() {
			It("displays error and exits 1", func() {
				session := helpers.CF("route", "some-domain")
				Eventually(session).Should(Say(`FAILED`))
				Eventually(session.Err).Should(Say(`Domain 'some-domain' not found.`))
				Eventually(session).Should(Exit(1))
			})
		})

		When("the domain is not specified", func() {
			It("displays error and exits 1", func() {
				session := helpers.CF("route")
				Eventually(session.Err).Should(Say("Incorrect Usage: the required argument `DOMAIN` was not provided\n"))
				Eventually(session.Err).Should(Say("\n"))
				Eventually(session).Should(Say("NAME:\n"))
				Eventually(session).Should(Exit(1))
			})
		})
	})
})
<|endoftext|>


<commit_before>package presilo

import (
	"fmt"
	"strings"
)

/*
  Generates valid CSharp code for a given schema.
*/
func GenerateCSharp(schema *ObjectSchema, module string, tabstyle string) string {

	var buffer *BufferedFormatString

	buffer = NewBufferedFormatString(tabstyle)

	generateCSharpImports(schema, buffer)
	buffer.Print("\n")
	generateCSharpNamespace(schema, buffer, module)
	buffer.Print("\n")
	generateCSharpTypeDeclaration(schema, buffer)
	buffer.Print("\n")
	generateCSharpConstructor(schema, buffer)
	buffer.Print("\n")
	generateCSharpFunctions(schema, buffer)
	buffer.AddIndentation(-1)
	buffer.Print("\n}")
	buffer.AddIndentation(-1)
	buffer.Print("\n}")

	return buffer.String()
}

func generateCSharpImports(schema *ObjectSchema, buffer *BufferedFormatString) {

	buffer.Print("using System;")

	// import regex if we need it
	if containsRegexpMatch(schema) {
		buffer.Print("\nusing System.Text.RegularExpressions;")
	}

	buffer.Print("\n")
}

func generateCSharpNamespace(schema *ObjectSchema, buffer *BufferedFormatString, module string) {

	buffer.Printf("namespace %s\n{", module)
	buffer.AddIndentation(1)
}

func generateCSharpTypeDeclaration(schema *ObjectSchema, buffer *BufferedFormatString) {

	var subschema TypeSchema
	var propertyName string

	buffer.Printf("public class %s\n{", ToCamelCase(schema.Title))
	buffer.AddIndentation(1)

	for propertyName, subschema = range schema.Properties {

		buffer.Printf("\nprotected %s %s;", generateCSharpTypeForSchema(subschema), ToJavaCase(propertyName))
	}
}

func generateCSharpConstructor(schema *ObjectSchema, buffer *BufferedFormatString) {

	var subschema TypeSchema
	var declarations, setters []string
	var propertyName string
	var toWrite string

	buffer.Printf("\npublic %s(", ToCamelCase(schema.Title))

	for _, propertyName = range schema.RequiredProperties {

		subschema = schema.Properties[propertyName]
		propertyName = ToJavaCase(propertyName)

		toWrite = fmt.Sprintf("%s %s", generateCSharpTypeForSchema(subschema), propertyName)
		declarations = append(declarations, toWrite)

		toWrite = fmt.Sprintf("\nset%s(%s);", ToCamelCase(propertyName), propertyName)
		setters = append(setters, toWrite)
	}

	buffer.Print(strings.Join(declarations, ","))
	buffer.Print(")\n{")
	buffer.AddIndentation(1)

	for _, setter := range setters {
		buffer.Print(setter)
	}

	buffer.AddIndentation(-1)
	buffer.Print("\n}\n")
}

func generateCSharpFunctions(schema *ObjectSchema, buffer *BufferedFormatString) {

	var subschema TypeSchema
	var propertyName, properName, camelName, typeName string

	for propertyName, subschema = range schema.Properties {

		properName = ToJavaCase(propertyName)
		camelName = ToCamelCase(propertyName)
		typeName = generateCSharpTypeForSchema(subschema)

		// getter
		buffer.Printf("\npublic %s get%s()\n{", typeName, camelName)
		buffer.AddIndentation(1)

		buffer.Printf("\nreturn this.%s;", properName)

		buffer.AddIndentation(-1)
		buffer.Print("\n}")

		// setter
		buffer.Printf("\npublic void set%s(%s value)\n{", camelName, typeName)
		buffer.AddIndentation(1)

		switch subschema.GetSchemaType() {
		case SCHEMATYPE_STRING:
			generateCSharpStringSetter(subschema.(*StringSchema), buffer)
		case SCHEMATYPE_INTEGER:
			fallthrough
		case SCHEMATYPE_NUMBER:
			generateCSharpNumericSetter(subschema.(NumericSchemaType), buffer)
		case SCHEMATYPE_OBJECT:
			generateCSharpObjectSetter(subschema.(*ObjectSchema), buffer)
		case SCHEMATYPE_ARRAY:
			generateCSharpArraySetter(subschema.(*ArraySchema), buffer)
		}

		buffer.Printf("\n%s = value;", properName)
		buffer.AddIndentation(-1)
		buffer.Print("\n}\n")
	}
}

func generateCSharpStringSetter(schema *StringSchema, buffer *BufferedFormatString) {

	generateCSharpNullCheck(buffer)

	if schema.MinLength != nil {
		generateCSharpRangeCheck(*schema.MinLength, "value.Length", "was shorter than allowable minimum", "%d", false, "<", "", buffer)
	}

	if schema.MaxLength != nil {
		generateCSharpRangeCheck(*schema.MaxLength, "value.Length", "was longer than allowable maximum", "%d", false, ">", "", buffer)
	}

	if schema.Pattern != nil {

		buffer.Printf("\nRegex regex = new Regex(\"%s\");", sanitizeQuotedString(*schema.Pattern))
		buffer.Printf("\nif(!regex.IsMatch(value))\n{")
		buffer.AddIndentation(1)

		buffer.Printf("\nthrow new Exception(\"Value '\"+value+\"' did not match pattern '%s'\");", *schema.Pattern)

		buffer.AddIndentation(-1)
		buffer.Print("\n}")
	}
}

func generateCSharpNumericSetter(schema NumericSchemaType, buffer *BufferedFormatString) {

	if schema.HasMinimum() {
		generateCSharpRangeCheck(schema.GetMinimum(), "value", "is under the allowable minimum", schema.GetConstraintFormat(), schema.IsExclusiveMinimum(), "<=", "<", buffer)
	}

	if schema.HasMaximum() {
		generateCSharpRangeCheck(schema.GetMaximum(), "value", "is over the allowable maximum", schema.GetConstraintFormat(), schema.IsExclusiveMaximum(), ">=", ">", buffer)
	}

	if schema.HasEnum() {
		generateCSharpEnumCheck(schema, buffer, schema.GetEnum(), "", "")
	}

	if schema.HasMultiple() {

		buffer.Printf("\nif(value %% %f != 0)\n{", schema.GetMultiple())
		buffer.AddIndentation(1)

		buffer.Printf("\nthrow new Exception(\"Property '\"+value+\"' was not a multiple of %s\");", schema.GetMultiple())

		buffer.AddIndentation(-1)
		buffer.Print("\n}\n")
	}
}

func generateCSharpObjectSetter(schema *ObjectSchema, buffer *BufferedFormatString) {

	generateCSharpNullCheck(buffer)
}

func generateCSharpArraySetter(schema *ArraySchema, buffer *BufferedFormatString) {

	generateCSharpNullCheck(buffer)

	if schema.MinItems != nil {
		generateCSharpRangeCheck(*schema.MinItems, "value.Length", "does not have enough items", "%d", false, "<", "", buffer)
	}

	if schema.MaxItems != nil {
		generateCSharpRangeCheck(*schema.MaxItems, "value.Length", "does not have enough items", "%d", false, ">", "", buffer)
	}
}

func generateCSharpNullCheck(buffer *BufferedFormatString) {

	buffer.Printf("\nif(value == null)\n{")
	buffer.AddIndentation(1)

	buffer.Print("\nthrow new NullReferenceException(\"Cannot set property to null value\");")

	buffer.AddIndentation(-1)
	buffer.Print("\n}\n")
}

func generateCSharpRangeCheck(value interface{}, reference, message, format string, exclusive bool, comparator, exclusiveComparator string, buffer *BufferedFormatString) {

	var compareString string

	if exclusive {
		compareString = exclusiveComparator
	} else {
		compareString = comparator
	}

	buffer.Printf("\nif(%s %s "+format+")\n{", reference, compareString, value)
	buffer.AddIndentation(1)

	buffer.Printf("\nthrow new Exception(\"Property '\"+value+\"' %s.\");", message)
	buffer.AddIndentation(-1)
	buffer.Print("\n}\n")
}

/*
	Generates code which throws an error if the given [parameter]'s value is not contained in the given [validValues].
*/
func generateCSharpEnumCheck(schema TypeSchema, buffer *BufferedFormatString, enumValues []interface{}, prefix string, postfix string) {

	var typeName string
	var length int

	length = len(enumValues)

	if length <= 0 {
		return
	}

	// write array of valid values
	typeName = generateCSharpTypeForSchema(schema)
	buffer.Printf("%s[] validValues = new %s[]{%s%v%s", typeName, typeName, prefix, enumValues[0], postfix)

	for _, enumValue := range enumValues[1:length] {
		buffer.Printf(",%s%v%s", prefix, enumValue, postfix)
	}

	buffer.Print("};\n")

	// compare
	buffer.Print("\nbool isValid = false;")
	buffer.Print("\nfor(int i = 0; i < validValues.Length; i++)\n{")
	buffer.AddIndentation(1)

	buffer.Print("\nif(validValues[i] == value)\n{")
	buffer.AddIndentation(1)
	buffer.Print("\nisValid = true;\nbreak;")

	buffer.AddIndentation(-1)
	buffer.Print("\n}")
	buffer.AddIndentation(-1)
	buffer.Print("\n}")

	buffer.Print("\nif(!isValid)\n{")
	buffer.AddIndentation(1)
	buffer.Print("\nthrow new Exception(\"Given value '\"+value+\"' was not found in list of acceptable values\");")

	buffer.AddIndentation(-1)
	buffer.Print("\n}\n")
}

func generateCSharpTypeForSchema(subschema TypeSchema) string {

	switch subschema.GetSchemaType() {
	case SCHEMATYPE_NUMBER:
		return "double"
	case SCHEMATYPE_INTEGER:
		return "int"
	case SCHEMATYPE_ARRAY:
		return ToCamelCase(subschema.(*ArraySchema).Items.GetTitle()) + "[]"
	case SCHEMATYPE_OBJECT:
		return ToCamelCase(subschema.GetTitle())
	case SCHEMATYPE_STRING:
		return "string"
	case SCHEMATYPE_BOOLEAN:
		return "bool"
	}

	return "Object"
}
<commit_msg>Implemented C# serialization annotations<commit_after>package presilo

import (
	"fmt"
	"strings"
)

/*
  Generates valid CSharp code for a given schema.

	C# code contains DataContractJsonSerializer annotations,
	which are required for proper serialization/deserialization of fields.
	Unfortunately this isn't available before .NET 4.5, so any generated code
	will need to be compiled with .NET 4.5+
*/
func GenerateCSharp(schema *ObjectSchema, module string, tabstyle string) string {

	var buffer *BufferedFormatString

	buffer = NewBufferedFormatString(tabstyle)

	generateCSharpImports(schema, buffer)
	buffer.Print("\n")
	generateCSharpNamespace(schema, buffer, module)
	buffer.Print("\n")
	generateCSharpTypeDeclaration(schema, buffer)
	buffer.Print("\n")
	generateCSharpConstructor(schema, buffer)
	buffer.Print("\n")
	generateCSharpFunctions(schema, buffer)
	buffer.AddIndentation(-1)
	buffer.Print("\n}")
	buffer.AddIndentation(-1)
	buffer.Print("\n}")

	return buffer.String()
}

func generateCSharpImports(schema *ObjectSchema, buffer *BufferedFormatString) {

	buffer.Print("using System;")
	buffer.Print("\n using System.Runtime.Serialization;")

	// import regex if we need it
	if containsRegexpMatch(schema) {
		buffer.Print("\nusing System.Text.RegularExpressions;")
	}

	buffer.Print("\n")
}

func generateCSharpNamespace(schema *ObjectSchema, buffer *BufferedFormatString, module string) {

	buffer.Printf("namespace %s\n{", module)
	buffer.AddIndentation(1)
}

func generateCSharpTypeDeclaration(schema *ObjectSchema, buffer *BufferedFormatString) {

	var subschema TypeSchema
	var propertyName string

	buffer.Print("[DataContract]")
	buffer.Printf("\npublic class %s\n{", ToCamelCase(schema.Title))
	buffer.AddIndentation(1)

	for propertyName, subschema = range schema.Properties {

		buffer.Print("\n[DataMember]")
		buffer.Printf("\nprotected %s %s;", generateCSharpTypeForSchema(subschema), ToJavaCase(propertyName))
	}
}

func generateCSharpConstructor(schema *ObjectSchema, buffer *BufferedFormatString) {

	var subschema TypeSchema
	var declarations, setters []string
	var propertyName string
	var toWrite string

	buffer.Printf("\npublic %s(", ToCamelCase(schema.Title))

	for _, propertyName = range schema.RequiredProperties {

		subschema = schema.Properties[propertyName]
		propertyName = ToJavaCase(propertyName)

		toWrite = fmt.Sprintf("%s %s", generateCSharpTypeForSchema(subschema), propertyName)
		declarations = append(declarations, toWrite)

		toWrite = fmt.Sprintf("\nset%s(%s);", ToCamelCase(propertyName), propertyName)
		setters = append(setters, toWrite)
	}

	buffer.Print(strings.Join(declarations, ","))
	buffer.Print(")\n{")
	buffer.AddIndentation(1)

	for _, setter := range setters {
		buffer.Print(setter)
	}

	buffer.AddIndentation(-1)
	buffer.Print("\n}\n")
}

func generateCSharpFunctions(schema *ObjectSchema, buffer *BufferedFormatString) {

	var subschema TypeSchema
	var propertyName, properName, camelName, typeName string

	for propertyName, subschema = range schema.Properties {

		properName = ToJavaCase(propertyName)
		camelName = ToCamelCase(propertyName)
		typeName = generateCSharpTypeForSchema(subschema)

		// getter
		buffer.Printf("\npublic %s get%s()\n{", typeName, camelName)
		buffer.AddIndentation(1)

		buffer.Printf("\nreturn this.%s;", properName)

		buffer.AddIndentation(-1)
		buffer.Print("\n}")

		// setter
		buffer.Printf("\npublic void set%s(%s value)\n{", camelName, typeName)
		buffer.AddIndentation(1)

		switch subschema.GetSchemaType() {
		case SCHEMATYPE_STRING:
			generateCSharpStringSetter(subschema.(*StringSchema), buffer)
		case SCHEMATYPE_INTEGER:
			fallthrough
		case SCHEMATYPE_NUMBER:
			generateCSharpNumericSetter(subschema.(NumericSchemaType), buffer)
		case SCHEMATYPE_OBJECT:
			generateCSharpObjectSetter(subschema.(*ObjectSchema), buffer)
		case SCHEMATYPE_ARRAY:
			generateCSharpArraySetter(subschema.(*ArraySchema), buffer)
		}

		buffer.Printf("\n%s = value;", properName)
		buffer.AddIndentation(-1)
		buffer.Print("\n}\n")
	}
}

func generateCSharpStringSetter(schema *StringSchema, buffer *BufferedFormatString) {

	generateCSharpNullCheck(buffer)

	if schema.MinLength != nil {
		generateCSharpRangeCheck(*schema.MinLength, "value.Length", "was shorter than allowable minimum", "%d", false, "<", "", buffer)
	}

	if schema.MaxLength != nil {
		generateCSharpRangeCheck(*schema.MaxLength, "value.Length", "was longer than allowable maximum", "%d", false, ">", "", buffer)
	}

	if schema.Pattern != nil {

		buffer.Printf("\nRegex regex = new Regex(\"%s\");", sanitizeQuotedString(*schema.Pattern))
		buffer.Printf("\nif(!regex.IsMatch(value))\n{")
		buffer.AddIndentation(1)

		buffer.Printf("\nthrow new Exception(\"Value '\"+value+\"' did not match pattern '%s'\");", *schema.Pattern)

		buffer.AddIndentation(-1)
		buffer.Print("\n}")
	}
}

func generateCSharpNumericSetter(schema NumericSchemaType, buffer *BufferedFormatString) {

	if schema.HasMinimum() {
		generateCSharpRangeCheck(schema.GetMinimum(), "value", "is under the allowable minimum", schema.GetConstraintFormat(), schema.IsExclusiveMinimum(), "<=", "<", buffer)
	}

	if schema.HasMaximum() {
		generateCSharpRangeCheck(schema.GetMaximum(), "value", "is over the allowable maximum", schema.GetConstraintFormat(), schema.IsExclusiveMaximum(), ">=", ">", buffer)
	}

	if schema.HasEnum() {
		generateCSharpEnumCheck(schema, buffer, schema.GetEnum(), "", "")
	}

	if schema.HasMultiple() {

		buffer.Printf("\nif(value %% %f != 0)\n{", schema.GetMultiple())
		buffer.AddIndentation(1)

		buffer.Printf("\nthrow new Exception(\"Property '\"+value+\"' was not a multiple of %s\");", schema.GetMultiple())

		buffer.AddIndentation(-1)
		buffer.Print("\n}\n")
	}
}

func generateCSharpObjectSetter(schema *ObjectSchema, buffer *BufferedFormatString) {

	generateCSharpNullCheck(buffer)
}

func generateCSharpArraySetter(schema *ArraySchema, buffer *BufferedFormatString) {

	generateCSharpNullCheck(buffer)

	if schema.MinItems != nil {
		generateCSharpRangeCheck(*schema.MinItems, "value.Length", "does not have enough items", "%d", false, "<", "", buffer)
	}

	if schema.MaxItems != nil {
		generateCSharpRangeCheck(*schema.MaxItems, "value.Length", "does not have enough items", "%d", false, ">", "", buffer)
	}
}

func generateCSharpNullCheck(buffer *BufferedFormatString) {

	buffer.Printf("\nif(value == null)\n{")
	buffer.AddIndentation(1)

	buffer.Print("\nthrow new NullReferenceException(\"Cannot set property to null value\");")

	buffer.AddIndentation(-1)
	buffer.Print("\n}\n")
}

func generateCSharpRangeCheck(value interface{}, reference, message, format string, exclusive bool, comparator, exclusiveComparator string, buffer *BufferedFormatString) {

	var compareString string

	if exclusive {
		compareString = exclusiveComparator
	} else {
		compareString = comparator
	}

	buffer.Printf("\nif(%s %s "+format+")\n{", reference, compareString, value)
	buffer.AddIndentation(1)

	buffer.Printf("\nthrow new Exception(\"Property '\"+value+\"' %s.\");", message)
	buffer.AddIndentation(-1)
	buffer.Print("\n}\n")
}

/*
	Generates code which throws an error if the given [parameter]'s value is not contained in the given [validValues].
*/
func generateCSharpEnumCheck(schema TypeSchema, buffer *BufferedFormatString, enumValues []interface{}, prefix string, postfix string) {

	var typeName string
	var length int

	length = len(enumValues)

	if length <= 0 {
		return
	}

	// write array of valid values
	typeName = generateCSharpTypeForSchema(schema)
	buffer.Printf("%s[] validValues = new %s[]{%s%v%s", typeName, typeName, prefix, enumValues[0], postfix)

	for _, enumValue := range enumValues[1:length] {
		buffer.Printf(",%s%v%s", prefix, enumValue, postfix)
	}

	buffer.Print("};\n")

	// compare
	buffer.Print("\nbool isValid = false;")
	buffer.Print("\nfor(int i = 0; i < validValues.Length; i++)\n{")
	buffer.AddIndentation(1)

	buffer.Print("\nif(validValues[i] == value)\n{")
	buffer.AddIndentation(1)
	buffer.Print("\nisValid = true;\nbreak;")

	buffer.AddIndentation(-1)
	buffer.Print("\n}")
	buffer.AddIndentation(-1)
	buffer.Print("\n}")

	buffer.Print("\nif(!isValid)\n{")
	buffer.AddIndentation(1)
	buffer.Print("\nthrow new Exception(\"Given value '\"+value+\"' was not found in list of acceptable values\");")

	buffer.AddIndentation(-1)
	buffer.Print("\n}\n")
}

func generateCSharpTypeForSchema(subschema TypeSchema) string {

	switch subschema.GetSchemaType() {
	case SCHEMATYPE_NUMBER:
		return "double"
	case SCHEMATYPE_INTEGER:
		return "int"
	case SCHEMATYPE_ARRAY:
		return ToCamelCase(subschema.(*ArraySchema).Items.GetTitle()) + "[]"
	case SCHEMATYPE_OBJECT:
		return ToCamelCase(subschema.GetTitle())
	case SCHEMATYPE_STRING:
		return "string"
	case SCHEMATYPE_BOOLEAN:
		return "bool"
	}

	return "Object"
}
<|endoftext|>


<commit_before>package telcatalog

import (
	"errors"
	"fmt"

	"github.com/cloudstax/firecamp/api/catalog"
	"github.com/cloudstax/firecamp/api/common"
	"github.com/cloudstax/firecamp/api/manage"
	"github.com/cloudstax/firecamp/pkg/dns"
)

const (
	defaultVersion = "1.5"
	// ContainerImage is the main running container.
	ContainerImage = common.ContainerNamePrefix + "telegraf:" + defaultVersion

	// DefaultCollectIntervalSecs defines the default metrics collect interval, unit: seconds
	DefaultCollectIntervalSecs = 60

	ENV_MONITOR_COLLECT_INTERVAL = "COLLECT_INTERVAL"
	ENV_MONITOR_SERVICE_NAME     = "MONITOR_SERVICE_NAME"
	ENV_MONITOR_SERVICE_TYPE     = "MONITOR_SERVICE_TYPE"
	ENV_MONITOR_SERVICE_MEMBERS  = "MONITOR_SERVICE_MEMBERS"
	ENV_MONITOR_METRICS          = "MONITOR_METRICS"

	// Limits the max custom metrics size to 16KB
	maxMetricsLength = 16 * 1024

	metricsConfFileName = "metrics.conf"
)

// The InfluxData Telegraf catalog service, https://github.com/influxdata/telegraf

// ValidateRequest checks if the request is valid
func ValidateRequest(req *catalog.CatalogCreateTelegrafRequest) error {
	if req.Options.CollectIntervalSecs <= 0 {
		return errors.New("Please specify the valid collect interval")
	}
	if len(req.Options.MonitorMetrics) > maxMetricsLength {
		return fmt.Errorf("Max custom metrics length should be within %d bytes", maxMetricsLength)
	}

	return nil
}

// GenDefaultCreateServiceRequest returns the default service creation request.
func GenDefaultCreateServiceRequest(platform string, region string, cluster string, service string,
	attr *common.ServiceAttr, monitorServiceMembers []*common.ServiceMember,
	opts *catalog.CatalogTelegrafOptions, res *common.Resources) *manage.CreateServiceRequest {

	members := ""
	for i, m := range monitorServiceMembers {
		dnsname := dns.GenDNSName(m.MemberName, attr.Spec.DomainName)
		if i == 0 {
			members = dnsname
		} else {
			members += fmt.Sprintf(",%s", dnsname)
		}
	}

	envkvs := []*common.EnvKeyValuePair{
		&common.EnvKeyValuePair{Name: common.ENV_CONTAINER_PLATFORM, Value: platform},
		&common.EnvKeyValuePair{Name: common.ENV_REGION, Value: region},
		&common.EnvKeyValuePair{Name: common.ENV_CLUSTER, Value: cluster},
		&common.EnvKeyValuePair{Name: common.ENV_SERVICE_NAME, Value: service},
		&common.EnvKeyValuePair{Name: ENV_MONITOR_COLLECT_INTERVAL, Value: fmt.Sprintf("%ds", opts.CollectIntervalSecs)},
		&common.EnvKeyValuePair{Name: ENV_MONITOR_SERVICE_NAME, Value: opts.MonitorServiceName},
		&common.EnvKeyValuePair{Name: ENV_MONITOR_SERVICE_TYPE, Value: attr.Spec.CatalogServiceType},
		&common.EnvKeyValuePair{Name: ENV_MONITOR_SERVICE_MEMBERS, Value: members},
		&common.EnvKeyValuePair{Name: ENV_MONITOR_METRICS, Value: opts.MonitorMetrics},
	}

	serviceCfgs := genServiceConfigs(opts)

	replicaCfgs := catalog.GenStatelessServiceReplicaConfigs(cluster, service, 1)

	req := &manage.CreateServiceRequest{
		Service: &manage.ServiceCommonRequest{
			Region:             region,
			Cluster:            cluster,
			ServiceName:        service,
			CatalogServiceType: common.CatalogService_Telegraf,
		},

		Resource: &common.Resources{
			MaxCPUUnits:     res.MaxCPUUnits,
			ReserveCPUUnits: res.ReserveCPUUnits,
			MaxMemMB:        res.MaxMemMB,
			ReserveMemMB:    res.ReserveMemMB,
		},

		ServiceType: common.ServiceTypeStateless,

		ContainerImage: ContainerImage,
		// Telegraf only needs 1 container.
		Replicas: 1,
		Envkvs:   envkvs,
		// telegraf dockerfile expose 8125/udp 8092/udp 8094.
		// 8125 is the port that the statsD input plugin listens on.
		// 8092 is use by the udp listener plugin, and is deprecated in favor of the socket listener plugin.
		// 8094 the port that the socket listener plugin listens on, to listens for messages from
		// streaming (tcp, unix) or datagram (udp, unixgram) protocols.
		// Currently firecamp telegraf is only used to monitor the stateful service. So no need to expose
		// these ports and no need to register DNS for the telegraf service itself.
		RegisterDNS: false,

		ServiceConfigs: serviceCfgs,

		ReplicaConfigs: replicaCfgs,
	}
	return req
}

func genServiceConfigs(opts *catalog.CatalogTelegrafOptions) []*manage.ConfigFileContent {
	// create service.conf file
	content := fmt.Sprintf(servicefileContent, opts.CollectIntervalSecs, opts.MonitorServiceName)
	serviceCfg := &manage.ConfigFileContent{
		FileName: catalog.SERVICE_FILE_NAME,
		FileMode: common.DefaultConfigFileMode,
		Content:  content,
	}

	configs := []*manage.ConfigFileContent{serviceCfg}

	if len(opts.MonitorMetrics) != 0 {
		// create metrics.conf file
		metricsCfg := &manage.ConfigFileContent{
			FileName: metricsConfFileName,
			FileMode: common.DefaultConfigFileMode,
			Content:  opts.MonitorMetrics,
		}
		configs = append(configs, metricsCfg)
	}

	return configs
}

const (
	// TODO create 2 service config files: service.conf and metrics.conf
	servicefileContent = `
CollectIntervalSecs=%d
MonitorServiceName=%s
`
)
<commit_msg>add monitor service type for telegraf<commit_after>package telcatalog

import (
	"errors"
	"fmt"

	"github.com/cloudstax/firecamp/api/catalog"
	"github.com/cloudstax/firecamp/api/common"
	"github.com/cloudstax/firecamp/api/manage"
	"github.com/cloudstax/firecamp/pkg/dns"
)

const (
	defaultVersion = "1.5"
	// ContainerImage is the main running container.
	ContainerImage = common.ContainerNamePrefix + "telegraf:" + defaultVersion

	// DefaultCollectIntervalSecs defines the default metrics collect interval, unit: seconds
	DefaultCollectIntervalSecs = 60

	ENV_MONITOR_COLLECT_INTERVAL = "COLLECT_INTERVAL"
	ENV_MONITOR_SERVICE_NAME     = "MONITOR_SERVICE_NAME"
	ENV_MONITOR_SERVICE_TYPE     = "MONITOR_SERVICE_TYPE"
	ENV_MONITOR_SERVICE_MEMBERS  = "MONITOR_SERVICE_MEMBERS"
	ENV_MONITOR_METRICS          = "MONITOR_METRICS"

	// Limits the max custom metrics size to 16KB
	maxMetricsLength = 16 * 1024

	metricsConfFileName = "metrics.conf"
)

// The InfluxData Telegraf catalog service, https://github.com/influxdata/telegraf

// ValidateRequest checks if the request is valid
func ValidateRequest(req *catalog.CatalogCreateTelegrafRequest) error {
	if req.Options.CollectIntervalSecs <= 0 {
		return errors.New("Please specify the valid collect interval")
	}
	if len(req.Options.MonitorMetrics) > maxMetricsLength {
		return fmt.Errorf("Max custom metrics length should be within %d bytes", maxMetricsLength)
	}

	return nil
}

// GenDefaultCreateServiceRequest returns the default service creation request.
func GenDefaultCreateServiceRequest(platform string, region string, cluster string, service string,
	attr *common.ServiceAttr, monitorServiceMembers []*common.ServiceMember,
	opts *catalog.CatalogTelegrafOptions, res *common.Resources) *manage.CreateServiceRequest {

	members := ""
	for i, m := range monitorServiceMembers {
		dnsname := dns.GenDNSName(m.MemberName, attr.Spec.DomainName)
		if i == 0 {
			members = dnsname
		} else {
			members += fmt.Sprintf(",%s", dnsname)
		}
	}

	envkvs := []*common.EnvKeyValuePair{
		&common.EnvKeyValuePair{Name: common.ENV_CONTAINER_PLATFORM, Value: platform},
		&common.EnvKeyValuePair{Name: common.ENV_REGION, Value: region},
		&common.EnvKeyValuePair{Name: common.ENV_CLUSTER, Value: cluster},
		&common.EnvKeyValuePair{Name: common.ENV_SERVICE_NAME, Value: service},
		&common.EnvKeyValuePair{Name: ENV_MONITOR_COLLECT_INTERVAL, Value: fmt.Sprintf("%ds", opts.CollectIntervalSecs)},
		&common.EnvKeyValuePair{Name: ENV_MONITOR_SERVICE_NAME, Value: opts.MonitorServiceName},
		&common.EnvKeyValuePair{Name: ENV_MONITOR_SERVICE_TYPE, Value: attr.Spec.CatalogServiceType},
		&common.EnvKeyValuePair{Name: ENV_MONITOR_SERVICE_MEMBERS, Value: members},
		&common.EnvKeyValuePair{Name: ENV_MONITOR_METRICS, Value: opts.MonitorMetrics},
	}

	serviceCfgs := genServiceConfigs(opts)

	replicaCfgs := catalog.GenStatelessServiceReplicaConfigs(cluster, service, 1)

	req := &manage.CreateServiceRequest{
		Service: &manage.ServiceCommonRequest{
			Region:             region,
			Cluster:            cluster,
			ServiceName:        service,
			CatalogServiceType: common.CatalogService_Telegraf,
		},

		Resource: &common.Resources{
			MaxCPUUnits:     res.MaxCPUUnits,
			ReserveCPUUnits: res.ReserveCPUUnits,
			MaxMemMB:        res.MaxMemMB,
			ReserveMemMB:    res.ReserveMemMB,
		},

		ServiceType: common.ServiceTypeStateless,

		ContainerImage: ContainerImage,
		// Telegraf only needs 1 container.
		Replicas: 1,
		Envkvs:   envkvs,
		// telegraf dockerfile expose 8125/udp 8092/udp 8094.
		// 8125 is the port that the statsD input plugin listens on.
		// 8092 is use by the udp listener plugin, and is deprecated in favor of the socket listener plugin.
		// 8094 the port that the socket listener plugin listens on, to listens for messages from
		// streaming (tcp, unix) or datagram (udp, unixgram) protocols.
		// Currently firecamp telegraf is only used to monitor the stateful service. So no need to expose
		// these ports and no need to register DNS for the telegraf service itself.
		RegisterDNS: false,

		ServiceConfigs: serviceCfgs,

		ReplicaConfigs: replicaCfgs,
	}
	return req
}

func genServiceConfigs(opts *catalog.CatalogTelegrafOptions) []*manage.ConfigFileContent {
	// create service.conf file
	content := fmt.Sprintf(servicefileContent, opts.CollectIntervalSecs, opts.MonitorServiceName, opts.MonitorServiceType)
	serviceCfg := &manage.ConfigFileContent{
		FileName: catalog.SERVICE_FILE_NAME,
		FileMode: common.DefaultConfigFileMode,
		Content:  content,
	}

	configs := []*manage.ConfigFileContent{serviceCfg}

	if len(opts.MonitorMetrics) != 0 {
		// create metrics.conf file
		metricsCfg := &manage.ConfigFileContent{
			FileName: metricsConfFileName,
			FileMode: common.DefaultConfigFileMode,
			Content:  opts.MonitorMetrics,
		}
		configs = append(configs, metricsCfg)
	}

	return configs
}

const (
	// TODO create 2 service config files: service.conf and metrics.conf
	servicefileContent = `
CollectIntervalSecs=%d
MonitorServiceName=%s
MonitorServiceType=%s
`
)
<|endoftext|>


<commit_before>package git

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"github.com/github/hub/cmd"
)

var GlobalFlags []string

func Version() (string, error) {
	output, err := gitOutput("version")
	if err != nil {
		return "", fmt.Errorf("Can't load git version")
	}

	return output[0], nil
}

func Dir() (string, error) {
	output, err := gitOutput("rev-parse", "-q", "--git-dir")
	if err != nil {
		return "", fmt.Errorf("Not a git repository (or any of the parent directories): .git")
	}

	gitDir := output[0]
	gitDir, err = filepath.Abs(gitDir)
	if err != nil {
		return "", err
	}

	return gitDir, nil
}

func HasFile(segments ...string) bool {
	dir, err := Dir()
	if err != nil {
		return false
	}

	s := []string{dir}
	s = append(s, segments...)
	path := filepath.Join(s...)
	if _, err := os.Stat(path); err == nil {
		return true
	}

	return false
}

func BranchAtRef(paths ...string) (name string, err error) {
	dir, err := Dir()
	if err != nil {
		return
	}

	segments := []string{dir}
	segments = append(segments, paths...)
	path := filepath.Join(segments...)
	b, err := ioutil.ReadFile(path)
	if err != nil {
		return
	}

	n := string(b)
	refPrefix := "ref: "
	if strings.HasPrefix(n, refPrefix) {
		name = strings.TrimPrefix(n, refPrefix)
		name = strings.TrimSpace(name)
	} else {
		err = fmt.Errorf("No branch info in %s: %s", path, n)
	}

	return
}

func Editor() (string, error) {
	output, err := gitOutput("var", "GIT_EDITOR")
	if err != nil {
		return "", fmt.Errorf("Can't load git var: GIT_EDITOR")
	}

	return output[0], nil
}

func Head() (string, error) {
	return BranchAtRef("HEAD")
}

func SymbolicFullName(name string) (string, error) {
	output, err := gitOutput("rev-parse", "--symbolic-full-name", name)
	if err != nil {
		return "", fmt.Errorf("Unknown revision or path not in the working tree: %s", name)
	}

	return output[0], nil
}

func Ref(ref string) (string, error) {
	output, err := gitOutput("rev-parse", "-q", ref)
	if err != nil {
		return "", fmt.Errorf("Unknown revision or path not in the working tree: %s", ref)
	}

	return output[0], nil
}

func RefList(a, b string) ([]string, error) {
	ref := fmt.Sprintf("%s...%s", a, b)
	output, err := gitOutput("rev-list", "--cherry-pick", "--right-only", "--no-merges", ref)
	if err != nil {
		return []string{}, fmt.Errorf("Can't load rev-list for %s", ref)
	}

	return output, nil
}

func CommentChar() string {
	char, err := Config("core.commentchar")
	if err != nil {
		char = "#"
	}

	return char
}

func Show(sha string) (string, error) {
	cmd := cmd.New("git")
	cmd.WithArg("show").WithArg("-s").WithArg("--format=%s%n%+b").WithArg(sha)

	output, err := cmd.CombinedOutput()
	output = strings.TrimSpace(output)

	return output, err
}

func Log(sha1, sha2 string) (string, error) {
	execCmd := cmd.New("git")
	execCmd.WithArg("log").WithArg("--no-color")
	execCmd.WithArg("--format=%h (%aN, %ar)%n%w(78,3,3)%s%n%+b")
	execCmd.WithArg("--cherry")
	shaRange := fmt.Sprintf("%s...%s", sha1, sha2)
	execCmd.WithArg(shaRange)

	outputs, err := execCmd.CombinedOutput()
	if err != nil {
		return "", fmt.Errorf("Can't load git log %s..%s", sha1, sha2)
	}

	return outputs, nil
}

func Remotes() ([]string, error) {
	return gitOutput("remote", "-v")
}

func Config(name string) (string, error) {
	return gitGetConfig(name)
}

func GlobalConfig(name string) (string, error) {
	return gitGetConfig("--global", name)
}

func SetGlobalConfig(name, value string) error {
	_, err := gitConfig("--global", name, value)
	return err
}

func gitGetConfig(args ...string) (string, error) {
	output, err := gitOutput(gitConfigCommand(args)...)
	if err != nil {
		return "", fmt.Errorf("Unknown config %s", args[len(args)-1])
	}

	if len(output) == 0 {
		return "", nil
	}

	return output[0], nil
}

func gitConfig(args ...string) ([]string, error) {
	return gitOutput(gitConfigCommand(args)...)
}

func gitConfigCommand(args []string) []string {
	cmd := []string{"config"}
	return append(cmd, args...)
}

func Alias(name string) (string, error) {
	return Config(fmt.Sprintf("alias.%s", name))
}

func Run(command string, args ...string) error {
	cmd := cmd.New("git")

	for _, v := range GlobalFlags {
		cmd.WithArg(v)
	}

	cmd.WithArg(command)

	for _, a := range args {
		cmd.WithArg(a)
	}

	return cmd.Run()
}

func gitOutput(input ...string) (outputs []string, err error) {
	cmd := cmd.New("git")

	for _, v := range GlobalFlags {
		cmd.WithArg(v)
	}

	for _, i := range input {
		cmd.WithArg(i)
	}

	out, err := cmd.CombinedOutput()
	for _, line := range strings.Split(out, "\n") {
		line = strings.TrimSpace(line)
		if line != "" {
			outputs = append(outputs, string(line))
		}
	}

	return outputs, err
}
<commit_msg>Handle git worktrees when computing the head repo<commit_after>package git

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"github.com/github/hub/cmd"
)

var GlobalFlags []string

func Version() (string, error) {
	output, err := gitOutput("version")
	if err != nil {
		return "", fmt.Errorf("Can't load git version")
	}

	return output[0], nil
}

func Dir() (string, error) {
	output, err := gitOutput("rev-parse", "-q", "--git-dir")
	if err != nil {
		return "", fmt.Errorf("Not a git repository (or any of the parent directories): .git")
	}

	gitDir := output[0]
	gitDir, err = filepath.Abs(gitDir)
	if err != nil {
		return "", err
	}

	return gitDir, nil
}

func HasFile(segments ...string) bool {
	// The blessed way to resolve paths within git dir since Git 2.5.0
	output, err := gitOutput("rev-parse", "-q", "--git-path", filepath.Join(segments...))
	if err == nil {
		if _, err := os.Stat(output[0]); err == nil {
			return true
		}
	}

	// Fallback for older git versions
	dir, err := Dir()
	if err != nil {
		return false
	}

	s := []string{dir}
	s = append(s, segments...)
	path := filepath.Join(s...)
	if _, err := os.Stat(path); err == nil {
		return true
	}

	return false
}

func BranchAtRef(paths ...string) (name string, err error) {
	dir, err := Dir()
	if err != nil {
		return
	}

	segments := []string{dir}
	segments = append(segments, paths...)
	path := filepath.Join(segments...)
	b, err := ioutil.ReadFile(path)
	if err != nil {
		return
	}

	n := string(b)
	refPrefix := "ref: "
	if strings.HasPrefix(n, refPrefix) {
		name = strings.TrimPrefix(n, refPrefix)
		name = strings.TrimSpace(name)
	} else {
		err = fmt.Errorf("No branch info in %s: %s", path, n)
	}

	return
}

func Editor() (string, error) {
	output, err := gitOutput("var", "GIT_EDITOR")
	if err != nil {
		return "", fmt.Errorf("Can't load git var: GIT_EDITOR")
	}

	return output[0], nil
}

func Head() (string, error) {
	return BranchAtRef("HEAD")
}

func SymbolicFullName(name string) (string, error) {
	output, err := gitOutput("rev-parse", "--symbolic-full-name", name)
	if err != nil {
		return "", fmt.Errorf("Unknown revision or path not in the working tree: %s", name)
	}

	return output[0], nil
}

func Ref(ref string) (string, error) {
	output, err := gitOutput("rev-parse", "-q", ref)
	if err != nil {
		return "", fmt.Errorf("Unknown revision or path not in the working tree: %s", ref)
	}

	return output[0], nil
}

func RefList(a, b string) ([]string, error) {
	ref := fmt.Sprintf("%s...%s", a, b)
	output, err := gitOutput("rev-list", "--cherry-pick", "--right-only", "--no-merges", ref)
	if err != nil {
		return []string{}, fmt.Errorf("Can't load rev-list for %s", ref)
	}

	return output, nil
}

func CommentChar() string {
	char, err := Config("core.commentchar")
	if err != nil {
		char = "#"
	}

	return char
}

func Show(sha string) (string, error) {
	cmd := cmd.New("git")
	cmd.WithArg("show").WithArg("-s").WithArg("--format=%s%n%+b").WithArg(sha)

	output, err := cmd.CombinedOutput()
	output = strings.TrimSpace(output)

	return output, err
}

func Log(sha1, sha2 string) (string, error) {
	execCmd := cmd.New("git")
	execCmd.WithArg("log").WithArg("--no-color")
	execCmd.WithArg("--format=%h (%aN, %ar)%n%w(78,3,3)%s%n%+b")
	execCmd.WithArg("--cherry")
	shaRange := fmt.Sprintf("%s...%s", sha1, sha2)
	execCmd.WithArg(shaRange)

	outputs, err := execCmd.CombinedOutput()
	if err != nil {
		return "", fmt.Errorf("Can't load git log %s..%s", sha1, sha2)
	}

	return outputs, nil
}

func Remotes() ([]string, error) {
	return gitOutput("remote", "-v")
}

func Config(name string) (string, error) {
	return gitGetConfig(name)
}

func GlobalConfig(name string) (string, error) {
	return gitGetConfig("--global", name)
}

func SetGlobalConfig(name, value string) error {
	_, err := gitConfig("--global", name, value)
	return err
}

func gitGetConfig(args ...string) (string, error) {
	output, err := gitOutput(gitConfigCommand(args)...)
	if err != nil {
		return "", fmt.Errorf("Unknown config %s", args[len(args)-1])
	}

	if len(output) == 0 {
		return "", nil
	}

	return output[0], nil
}

func gitConfig(args ...string) ([]string, error) {
	return gitOutput(gitConfigCommand(args)...)
}

func gitConfigCommand(args []string) []string {
	cmd := []string{"config"}
	return append(cmd, args...)
}

func Alias(name string) (string, error) {
	return Config(fmt.Sprintf("alias.%s", name))
}

func Run(command string, args ...string) error {
	cmd := cmd.New("git")

	for _, v := range GlobalFlags {
		cmd.WithArg(v)
	}

	cmd.WithArg(command)

	for _, a := range args {
		cmd.WithArg(a)
	}

	return cmd.Run()
}

func gitOutput(input ...string) (outputs []string, err error) {
	cmd := cmd.New("git")

	for _, v := range GlobalFlags {
		cmd.WithArg(v)
	}

	for _, i := range input {
		cmd.WithArg(i)
	}

	out, err := cmd.CombinedOutput()
	for _, line := range strings.Split(out, "\n") {
		line = strings.TrimSpace(line)
		if line != "" {
			outputs = append(outputs, string(line))
		}
	}

	return outputs, err
}
<|endoftext|>


<commit_before>/*
The models package provides a means of communicating with the database

In your main function Initialise:

getList := make(chan ListRetrieve)
addList := make(chan AddRequest)
removeList := make(chan string)
go BookmarksCollection(getList, addList, removeList)

This runs the bookmarks collection and provides channels for requests.

To make requests of the database, do the following:

1. Retrieve a list

key := keyToRetrieve
reply := make(chan Bookmarks)
getList <- ListRetrieve{key, reply}
newList := <- reply

2. Add a list

bookmarks := bookmarksToInsert
reply := make(chan string)
addList <- AddRequest{bookmarks, reply}
newKey := <- reply

3. Remove a list

key := keyToDelete
removeList <- key

*/
package models
<commit_msg>Added indentation in docs.go for models Indentation of code makes godoc recognise code and format it appropriately<commit_after>/*
The models package provides a means of communicating with the database

In your main function Initialise:

	getList := make(chan ListRetrieve)
	addList := make(chan AddRequest)
	removeList := make(chan string)
	go BookmarksCollection(getList, addList, removeList)

This runs the bookmarks collection and provides channels for requests.

To make requests of the database, do the following:

1. Retrieve a list

	key := keyToRetrieve
	reply := make(chan Bookmarks)
	getList <- ListRetrieve{key, reply}
	newList := <- reply

2. Add a list

	bookmarks := bookmarksToInsert
	reply := make(chan string)
	addList <- AddRequest{bookmarks, reply}
	newKey := <- reply

3. Remove a list

	key := keyToDelete
	removeList <- key

*/
package models
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net"
	"net/url"
	"os"
)

func crawl(xmlSitemapURL string, options CrawlOptions) error {

	urls, err := getURLs(xmlSitemapURL)
	if err != nil {
		return err
	}

	results := StartDispatcher(50)

	for index, url := range urls {

		// Now, we take the delay, and the person's name, and make a WorkRequest out of them.
		work := WorkRequest{Name: fmt.Sprintf("%000d %s", index+1, url.String()), Execute: createWorkFunction(index, url)}

		// Push the work onto the queue.
		go func() {
			WorkQueue <- work
		}()
	}

	resultCounter := 0
	for result := range results {
		resultCounter++

		if result.Error != nil {
			fmt.Fprintf(os.Stderr, "%s\n", result.Error)
		} else {
			fmt.Fprintf(os.Stdout, "%s\n", result.Message)
		}

		if resultCounter >= len(urls) {
			close(results)
		}
	}

	return nil
}

func createWorkFunction(index int, url url.URL) func() WorkResult {
	return func() WorkResult {

		response, err := readURL(url.String())
		if err != nil {
			return WorkResult{
				Error: err,
			}
		}

		return WorkResult{
			Message: fmt.Sprintf("%05d  %03d %9s %15s  %s", index+1, response.StatusCode(), fmt.Sprintf("%d", response.Size()), fmt.Sprintf("%s", response.Duration()), url.String()),
		}
	}
}

func getURLs(xmlSitemapURL string) ([]url.URL, error) {

	var urls []url.URL

	urlsFromIndex, indexError := getURLsFromSitemapIndex(xmlSitemapURL)
	if indexError == nil {
		urls = urlsFromIndex
	}

	urlsFromSitemap, sitemapError := getURLsFromSitemap(xmlSitemapURL)
	if sitemapError == nil {
		urls = append(urls, urlsFromSitemap...)
	}

	if isInvalidSitemapIndexContent(indexError) && isInvalidXMLSitemapContent(sitemapError) {
		return nil, fmt.Errorf("%q is neither a sitemap index nor a XML sitemap", xmlSitemapURL)
	}

	return urls, nil

}

func getURLsFromSitemap(xmlSitemapURL string) ([]url.URL, error) {

	var urls []url.URL

	sitemap, xmlSitemapError := getXMLSitemap(xmlSitemapURL)
	if xmlSitemapError != nil {
		return nil, xmlSitemapError
	}

	for _, urlEntry := range sitemap.URLs {

		parsedURL, parseError := url.Parse(urlEntry.Location)
		if parseError != nil {
			return nil, parseError
		}

		urls = append(urls, *parsedURL)
	}

	return urls, nil
}

func getURLsFromSitemapIndex(xmlSitemapURL string) ([]url.URL, error) {

	var urls []url.URL

	sitemapIndex, sitemapIndexError := getSitemapIndex(xmlSitemapURL)
	if sitemapIndexError != nil {
		return nil, sitemapIndexError
	}

	for _, sitemap := range sitemapIndex.Sitemaps {

		sitemapUrls, err := getURLsFromSitemap(sitemap.Location)
		if err != nil {
			return nil, err
		}

		urls = append(urls, sitemapUrls...)
	}

	return urls, nil

}

type CrawlOptions struct {
	Hosts []net.IP
}
<commit_msg>Get links for each site<commit_after>package main

import (
	"bytes"
	"fmt"
	"io"
	"net"
	"net/url"
	"os"
	"strings"

	"github.com/PuerkitoBio/goquery"
)

func crawl(xmlSitemapURL string, options CrawlOptions) error {

	urls, err := getURLs(xmlSitemapURL)
	if err != nil {
		return err
	}

	results := StartDispatcher(50)

	for index, url := range urls {

		// Now, we take the delay, and the person's name, and make a WorkRequest out of them.
		work := WorkRequest{Name: fmt.Sprintf("%000d %s", index+1, url.String()), Execute: createWorkFunction(index, url)}

		// Push the work onto the queue.
		go func() {
			WorkQueue <- work
		}()
	}

	resultCounter := 0
	for result := range results {
		resultCounter++

		if result.Error != nil {
			fmt.Fprintf(os.Stderr, "%s\n", result.Error)
		} else {
			fmt.Fprintf(os.Stdout, "%s\n", result.Message)
		}

		if resultCounter >= len(urls) {
			close(results)
		}
	}

	return nil
}

func createWorkFunction(index int, url url.URL) func() WorkResult {
	return func() WorkResult {

		response, err := readURL(url.String())
		if err != nil {
			return WorkResult{
				Error: err,
			}
		}

		links, err := getDependentRequests(url, bytes.NewReader(response.Body()))
		if err != nil {
			return WorkResult{
				Error: err,
			}
		}

		for _, link := range links {
			fmt.Println(link.String())
		}

		return WorkResult{
			Message: fmt.Sprintf("%05d  %03d %9s %15s  %s", index+1, response.StatusCode(), fmt.Sprintf("%d", response.Size()), fmt.Sprintf("%s", response.Duration()), url.String()),
		}
	}
}

func getDependentRequests(baseURL url.URL, input io.Reader) ([]url.URL, error) {

	doc, err := goquery.NewDocumentFromReader(input)
	if err != nil {
		return nil, err
	}

	var urls []url.URL

	// base url
	base, _ := doc.Find("base[href]").Attr("href")
	if base == "" {
		base = baseURL.Scheme + "://" + baseURL.Host
	} else if strings.HasPrefix(base, "/") {
		base = baseURL.Scheme + "://" + baseURL.Host + base
	}

	// get all links
	doc.Find("a[href]").Each(func(i int, s *goquery.Selection) {
		// For each item found, get the band and title
		href, _ := s.Attr("href")

		if strings.HasPrefix(href, "/") {
			href = baseURL.Scheme + "://" + baseURL.Host + href
		} else if !strings.HasPrefix(href, "http://") && !strings.HasPrefix(href, "https://") {
			href = strings.TrimSuffix(base, "/") + href
		}

		hrefURL, err := url.Parse(href)
		if err != nil {
			return
		}

		// ignore external links
		if hrefURL.Host != baseURL.Host {
			return
		}

		urls = append(urls, *hrefURL)
	})

	return urls, nil
}

func getURLs(xmlSitemapURL string) ([]url.URL, error) {

	var urls []url.URL

	urlsFromIndex, indexError := getURLsFromSitemapIndex(xmlSitemapURL)
	if indexError == nil {
		urls = urlsFromIndex
	}

	urlsFromSitemap, sitemapError := getURLsFromSitemap(xmlSitemapURL)
	if sitemapError == nil {
		urls = append(urls, urlsFromSitemap...)
	}

	if isInvalidSitemapIndexContent(indexError) && isInvalidXMLSitemapContent(sitemapError) {
		return nil, fmt.Errorf("%q is neither a sitemap index nor a XML sitemap", xmlSitemapURL)
	}

	return urls, nil

}

func getURLsFromSitemap(xmlSitemapURL string) ([]url.URL, error) {

	var urls []url.URL

	sitemap, xmlSitemapError := getXMLSitemap(xmlSitemapURL)
	if xmlSitemapError != nil {
		return nil, xmlSitemapError
	}

	for _, urlEntry := range sitemap.URLs {

		parsedURL, parseError := url.Parse(urlEntry.Location)
		if parseError != nil {
			return nil, parseError
		}

		urls = append(urls, *parsedURL)
	}

	return urls, nil
}

func getURLsFromSitemapIndex(xmlSitemapURL string) ([]url.URL, error) {

	var urls []url.URL

	sitemapIndex, sitemapIndexError := getSitemapIndex(xmlSitemapURL)
	if sitemapIndexError != nil {
		return nil, sitemapIndexError
	}

	for _, sitemap := range sitemapIndex.Sitemaps {

		sitemapUrls, err := getURLsFromSitemap(sitemap.Location)
		if err != nil {
			return nil, err
		}

		urls = append(urls, sitemapUrls...)
	}

	return urls, nil

}

type CrawlOptions struct {
	Hosts []net.IP
}
<|endoftext|>


<commit_before>package edit

import (
	"io/ioutil"
	"path"
	"strings"

	"github.com/elves/elvish/eval"
	"github.com/elves/elvish/parse"
)

// A completer takes the current node
type completer func(parse.Node, *Editor) []*candidate

var completers = []struct {
	name string
	completer
}{
	{"variable", complVariable},
	{"command name", complNewForm},
	{"command name", makeCompoundCompleter(complFormHead)},
	{"argument", complNewArg},
	{"argument", makeCompoundCompleter(complArg)},
}

func complVariable(n parse.Node, ed *Editor) []*candidate {
	primary, ok := n.(*parse.Primary)
	if !ok || primary.Type != parse.Variable {
		return nil
	}

	head := primary.Value[1:]
	cands := []*candidate{}
	for variable := range ed.evaler.Global() {
		if strings.HasPrefix(variable, head) {
			cands = append(cands, &candidate{
				source: styled{variable[len(head):], attrForType[Variable]},
				menu:   styled{"$" + variable, attrForType[Variable]}})
		}
	}
	return cands
}

func complNewForm(n parse.Node, ed *Editor) []*candidate {
	if _, ok := n.(*parse.Chunk); ok {
		return complFormHeadInner("", ed)
	}
	if _, ok := n.Parent().(*parse.Chunk); ok {
		return complFormHeadInner("", ed)
	}
	return nil
}

func makeCompoundCompleter(
	f func(*parse.Compound, string, *Editor) []*candidate) completer {
	return func(n parse.Node, ed *Editor) []*candidate {
		pn, ok := n.(*parse.Primary)
		if !ok {
			return nil
		}
		cn, head := simpleCompound(pn)
		if cn == nil {
			return nil
		}
		return f(cn, head, ed)
	}
}

func complFormHead(cn *parse.Compound, head string, ed *Editor) []*candidate {
	if isFormHead(cn) {
		return complFormHeadInner(head, ed)
	}
	return nil
}

func complFormHeadInner(head string, ed *Editor) []*candidate {
	cands := []*candidate{}
	foundCommand := func(s string) {
		if strings.HasPrefix(s, head) {
			cands = append(cands, &candidate{
				source: styled{s[len(head):], styleForGoodCommand},
				menu:   styled{s, ""},
			})
		}
	}
	for special := range isBuiltinSpecial {
		foundCommand(special)
	}
	for variable := range ed.evaler.Global() {
		if strings.HasPrefix(variable, eval.FnPrefix) {
			foundCommand(variable[3:])
		}
	}
	for command := range ed.isExternal {
		foundCommand(command)
	}
	return cands
}

func complNewArg(n parse.Node, ed *Editor) []*candidate {
	sn, ok := n.(*parse.Sep)
	if !ok {
		return nil
	}
	if _, ok := sn.Parent().(*parse.Form); !ok {
		return nil
	}
	return complArgInner("")
}

func complArg(cn *parse.Compound, head string, ed *Editor) []*candidate {
	return complArgInner(head)
}

func complArgInner(head string) []*candidate {
	// Assume that the argument is an incomplete filename
	dir, file := path.Split(head)
	var all []string
	if dir == "" {
		// XXX ignore error
		all, _ = fileNames(".")
	} else {
		all, _ = fileNames(dir)
	}

	cands := []*candidate{}
	// Make candidates out of elements that match the file component.
	for _, s := range all {
		if strings.HasPrefix(s, file) {
			cands = append(cands, &candidate{
				source: styled{s[len(file):], ""},
				menu:   styled{s, defaultLsColor.determineAttr(s)},
			})
		}
	}

	return cands
}

func fileNames(dir string) (names []string, err error) {
	infos, e := ioutil.ReadDir(dir)
	if e != nil {
		err = e
		return
	}
	for _, info := range infos {
		names = append(names, info.Name())
	}
	return
}
<commit_msg>edit: use channels in fileNames<commit_after>package edit

import (
	"fmt"
	"io/ioutil"
	"path"
	"strings"

	"github.com/elves/elvish/eval"
	"github.com/elves/elvish/parse"
)

// A completer takes the current node
type completer func(parse.Node, *Editor) []*candidate

var completers = []struct {
	name string
	completer
}{
	{"variable", complVariable},
	{"command name", complNewForm},
	{"command name", makeCompoundCompleter(complFormHead)},
	{"argument", complNewArg},
	{"argument", makeCompoundCompleter(complArg)},
}

func complVariable(n parse.Node, ed *Editor) []*candidate {
	primary, ok := n.(*parse.Primary)
	if !ok || primary.Type != parse.Variable {
		return nil
	}

	head := primary.Value[1:]
	cands := []*candidate{}
	for variable := range ed.evaler.Global() {
		if strings.HasPrefix(variable, head) {
			cands = append(cands, &candidate{
				source: styled{variable[len(head):], attrForType[Variable]},
				menu:   styled{"$" + variable, attrForType[Variable]}})
		}
	}
	return cands
}

func complNewForm(n parse.Node, ed *Editor) []*candidate {
	if _, ok := n.(*parse.Chunk); ok {
		return complFormHeadInner("", ed)
	}
	if _, ok := n.Parent().(*parse.Chunk); ok {
		return complFormHeadInner("", ed)
	}
	return nil
}

func makeCompoundCompleter(
	f func(*parse.Compound, string, *Editor) []*candidate) completer {
	return func(n parse.Node, ed *Editor) []*candidate {
		pn, ok := n.(*parse.Primary)
		if !ok {
			return nil
		}
		cn, head := simpleCompound(pn)
		if cn == nil {
			return nil
		}
		return f(cn, head, ed)
	}
}

func complFormHead(cn *parse.Compound, head string, ed *Editor) []*candidate {
	if isFormHead(cn) {
		return complFormHeadInner(head, ed)
	}
	return nil
}

func complFormHeadInner(head string, ed *Editor) []*candidate {
	cands := []*candidate{}
	foundCommand := func(s string) {
		if strings.HasPrefix(s, head) {
			cands = append(cands, &candidate{
				source: styled{s[len(head):], styleForGoodCommand},
				menu:   styled{s, ""},
			})
		}
	}
	for special := range isBuiltinSpecial {
		foundCommand(special)
	}
	for variable := range ed.evaler.Global() {
		if strings.HasPrefix(variable, eval.FnPrefix) {
			foundCommand(variable[3:])
		}
	}
	for command := range ed.isExternal {
		foundCommand(command)
	}
	return cands
}

func complNewArg(n parse.Node, ed *Editor) []*candidate {
	sn, ok := n.(*parse.Sep)
	if !ok {
		return nil
	}
	if _, ok := sn.Parent().(*parse.Form); !ok {
		return nil
	}
	return complArgInner("", ed)
}

func complArg(cn *parse.Compound, head string, ed *Editor) []*candidate {
	return complArgInner(head, ed)
}

func complArgInner(head string, ed *Editor) []*candidate {
	// Assume that the argument is an incomplete filename
	dir, file := path.Split(head)
	if dir == "" {
		dir = "."
	}
	names, err := fileNames(dir)
	cands := []*candidate{}

	if err != nil {
		ed.pushTip(fmt.Sprintf("cannot list directory %s: %v", dir, err))
		return cands
	}

	// Make candidates out of elements that match the file component.
	for s := range names {
		if strings.HasPrefix(s, file) {
			cands = append(cands, &candidate{
				source: styled{s[len(file):], ""},
				menu:   styled{s, defaultLsColor.determineAttr(s)},
			})
		}
	}

	return cands
}

func fileNames(dir string) (<-chan string, error) {
	infos, err := ioutil.ReadDir(dir)
	if err != nil {
		return nil, err
	}
	names := make(chan string, 32)
	go func() {
		for _, info := range infos {
			names <- info.Name()
		}
		close(names)
	}()
	return names, nil
}
<|endoftext|>


<commit_before>package grocessing

import (
	"errors"
	"fmt"
	"github.com/veandco/go-sdl2/sdl"
	"github.com/veandco/go-sdl2/sdl_image"
	"github.com/veandco/go-sdl2/sdl_ttf"
	"os"
	"runtime"
	"time"
)

var (
	window   *sdl.Window
	renderer *sdl.Renderer
	font     *ttf.Font

	fpsCap    uint = 30
	frames    uint
	lastStart int64

	sketch Sketch

	stop chan bool

	winTitle string = "Debug view"

	m     *Matrix
	stack []*Matrix
)

type Matrix struct {
	fillColor   Color
	strokeColor Color
	draw_stroke bool
	draw_fill   bool
	x, y        int
}

type Color *sdl.Color
type Font *ttf.Font

type Image struct {
	*sdl.Texture
	w, h int32
}

type Sketch interface {
	Setup()
	Draw()
}

func GrocessingStart(s Sketch) {

	sketch = s
	err := ttf.Init()
	if err != nil {
		panic(err)
	}

	m = default_matrix()
	stack = []*Matrix{m}

	window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED,
		0, 0, sdl.WINDOW_SHOWN)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", err)
		os.Exit(1)
	}
	defer window.Destroy()

	renderer, err = sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to create renderer: %s\n", err)
		os.Exit(2)
	}

	sketch.Setup()
	go func() {
		defer renderer.Destroy()
		runtime.LockOSThread()
		var diff int64
		for {
			lastStart := time.Now().UnixNano()
			renderer.Clear()
			sketch.Draw()
			renderer.Present()
			diff += time.Now().UnixNano() - lastStart
			if diff >= 1000 {
				frames = 0
			}
			frames++

			if frames < 1000/fpsCap {
				sdl.Delay(uint32(1000/fpsCap - frames))
			}
		}
	}()
	<-stop
	os.Exit(0)
}

func default_matrix() *Matrix {
	return &Matrix{
		fillColor:   Hc(0),
		strokeColor: Hc(0xffffff),
		draw_stroke: true,
		draw_fill:   true,
	}
}

func Rgb(r, g, b byte) Color {
	return &sdl.Color{r, g, b, 0}
}

func Hc(h int32) Color {
	return &sdl.Color{
		uint8((h >> 16) & 0xFF),
		uint8((h >> 8) & 0xFF),
		uint8((h >> 0) & 0xFF),
		0,
	}
}

func NoFill() {
	m.draw_fill = false
}

func CreateFont(name string, a int) (Font, error) {
	font, err := ttf.OpenFont(name, a)
	if err != nil {
		return nil, errors.New(fmt.Sprintf("Could not open font: %v", err))
	}
	return font, nil
}

func Size(w, h int) {
	window.SetSize(w, h)
}

func SetFont(f *ttf.Font) {
	font = f
}

func Max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func Min(a, b int) int {
	if a > b {
		return b
	}
	return a
}

func Fill(c Color) {
	m.draw_fill = true
	m.fillColor = c
}

func Stroke(c Color) {
	m.strokeColor = c
}

func Background(c Color) {
	Fill(c)
	m.draw_fill = true
	w, h := window.GetSize()
	Rect(0, 0, w, h)
}

func Rect(x, y, w, h int) {
	r := &sdl.Rect{
		int32(x + m.x),
		int32(y + m.y),
		int32(w),
		int32(h),
	}

	if m.draw_fill && m.fillColor != nil {
		renderer.SetDrawColor(
			m.fillColor.R, m.fillColor.G, m.fillColor.B, m.fillColor.A,
		)
		renderer.FillRect(r)
	}

	if m.draw_stroke && m.strokeColor != nil {
		renderer.SetDrawColor(
			m.strokeColor.R, m.strokeColor.G, m.strokeColor.B, m.strokeColor.A,
		)
		renderer.DrawRect(r)
	}

}

func Text(txt string, x, y, w, h int) {
	surface, err := font.RenderUTF8_Blended(txt, *m.fillColor)
	if err != nil {
		panic(err)
	}
	texture, err := renderer.CreateTextureFromSurface(surface)
	surface.Free()
	if err != nil {
		panic(err)
	}

	rw, rh, err := font.SizeUTF8(txt)
	r := &sdl.Rect{
		int32(m.x + (Max(rw, int(w))-Min(rw, int(w)))/2),
		int32(m.y + (Max(rh, int(h))-Min(rh, int(h)))/2),
		int32(rw),
		int32(rh),
	}

	renderer.Copy(texture, nil, r)
	texture.Destroy()
}

func LoadImage(path string) (*Image, error) {

	image, err := img.Load(path)
	if err != nil {
		return nil, errors.New(fmt.Sprintf("Could not load image: %v", err))
	}

	texture, err := renderer.CreateTextureFromSurface(image)
	image.Free()

	_, _, w, h, err := texture.Query()
	if err != nil {
		return nil, err
	}

	return &Image{texture, w, h}, nil
}

func (i *Image) Draw(x, y int) {
	i.DrawRect(int(x), int(y), int(i.w), int(i.h))
}

func (i *Image) DrawRect(x, y, w, h int) {
	renderer.Copy(i.Texture,
		&sdl.Rect{
			0, 0,
			i.w, i.h,
		},
		&sdl.Rect{
			int32(x + m.x), int32(y + m.y),
			int32(w), int32(h),
		})
}

func (i *Image) Free() {
	i.Texture.Destroy()
}

func PushMatrix() {
	new_mat := *m
	stack = append(stack, m)
	m = &new_mat
}

func PopMatrix() {
	m = stack[len(stack)-1]
	stack = stack[:len(stack)-1]
}

func Translate(x, y int) {
	m.x += x
	m.y += y
}
<commit_msg>exit handling<commit_after>package grocessing

import (
	"errors"
	"fmt"
	"github.com/veandco/go-sdl2/sdl"
	"github.com/veandco/go-sdl2/sdl_image"
	"github.com/veandco/go-sdl2/sdl_ttf"
	"os"
	"runtime"
	"time"
)

var (
	window   *sdl.Window
	renderer *sdl.Renderer
	font     *ttf.Font

	fpsCap    uint = 30
	frames    uint
	lastStart int64

	sketch Sketch

	stop chan bool = make(chan bool)

	winTitle string = "Debug view"

	m     *Matrix
	stack []*Matrix
)

type Matrix struct {
	fillColor   Color
	strokeColor Color
	draw_stroke bool
	draw_fill   bool
	x, y        int
}

type Color *sdl.Color
type Font *ttf.Font

type Image struct {
	*sdl.Texture
	w, h int32
}

type Sketch interface {
	Setup()
	Draw()
}

func GrocessingStart(s Sketch) {

	sketch = s
	err := ttf.Init()
	if err != nil {
		panic(err)
	}

	m = default_matrix()
	stack = []*Matrix{m}

	window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED,
		0, 0, sdl.WINDOW_SHOWN)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", err)
		os.Exit(1)
	}
	defer window.Destroy()

	renderer, err = sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to create renderer: %s\n", err)
		os.Exit(2)
	}

	sketch.Setup()

	//draw routine
	go func() {
		defer renderer.Destroy()
		runtime.LockOSThread()
		var diff int64
		for {
			lastStart := time.Now().UnixNano()
			renderer.Clear()
			sketch.Draw()
			renderer.Present()
			diff += time.Now().UnixNano() - lastStart
			if diff >= 1000 {
				frames = 0
			}
			frames++

			if frames < 1000/fpsCap {
				sdl.Delay(uint32(1000/fpsCap - frames))
			}
		}
	}()
	//event routine
	go func() {
		for {
			for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
				switch event.(type) {
				case *sdl.QuitEvent:
					fmt.Println("EXIT")
					stop <- true
				}
			}
		}
	}()

	<-stop
	os.Exit(0)
}

func default_matrix() *Matrix {
	return &Matrix{
		fillColor:   Hc(0),
		strokeColor: Hc(0xffffff),
		draw_stroke: true,
		draw_fill:   true,
	}
}

func Rgb(r, g, b byte) Color {
	return &sdl.Color{r, g, b, 0}
}

func Hc(h int32) Color {
	return &sdl.Color{
		uint8((h >> 16) & 0xFF),
		uint8((h >> 8) & 0xFF),
		uint8((h >> 0) & 0xFF),
		0,
	}
}

func NoFill() {
	m.draw_fill = false
}

func CreateFont(name string, a int) (Font, error) {
	font, err := ttf.OpenFont(name, a)
	if err != nil {
		return nil, errors.New(fmt.Sprintf("Could not open font: %v", err))
	}
	return font, nil
}

func Size(w, h int) {
	window.SetSize(w, h)
}

func SetFont(f *ttf.Font) {
	font = f
}

func Max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func Min(a, b int) int {
	if a > b {
		return b
	}
	return a
}

func Fill(c Color) {
	m.draw_fill = true
	m.fillColor = c
}

func Stroke(c Color) {
	m.strokeColor = c
}

func Background(c Color) {
	Fill(c)
	m.draw_fill = true
	w, h := window.GetSize()
	Rect(0, 0, w, h)
}

func Rect(x, y, w, h int) {
	r := &sdl.Rect{
		int32(x + m.x),
		int32(y + m.y),
		int32(w),
		int32(h),
	}

	if m.draw_fill && m.fillColor != nil {
		renderer.SetDrawColor(
			m.fillColor.R, m.fillColor.G, m.fillColor.B, m.fillColor.A,
		)
		renderer.FillRect(r)
	}

	if m.draw_stroke && m.strokeColor != nil {
		renderer.SetDrawColor(
			m.strokeColor.R, m.strokeColor.G, m.strokeColor.B, m.strokeColor.A,
		)
		renderer.DrawRect(r)
	}

}

func Text(txt string, x, y, w, h int) {
	surface, err := font.RenderUTF8_Blended(txt, *m.fillColor)
	if err != nil {
		panic(err)
	}
	texture, err := renderer.CreateTextureFromSurface(surface)
	surface.Free()
	if err != nil {
		panic(err)
	}

	rw, rh, err := font.SizeUTF8(txt)
	r := &sdl.Rect{
		int32(m.x + (Max(rw, int(w))-Min(rw, int(w)))/2),
		int32(m.y + (Max(rh, int(h))-Min(rh, int(h)))/2),
		int32(rw),
		int32(rh),
	}

	renderer.Copy(texture, nil, r)
	texture.Destroy()
}

func LoadImage(path string) (*Image, error) {

	image, err := img.Load(path)
	if err != nil {
		return nil, errors.New(fmt.Sprintf("Could not load image: %v", err))
	}

	texture, err := renderer.CreateTextureFromSurface(image)
	image.Free()

	_, _, w, h, err := texture.Query()
	if err != nil {
		return nil, err
	}

	return &Image{texture, w, h}, nil
}

func (i *Image) Draw(x, y int) {
	i.DrawRect(int(x), int(y), int(i.w), int(i.h))
}

func (i *Image) DrawRect(x, y, w, h int) {
	renderer.Copy(i.Texture,
		&sdl.Rect{
			0, 0,
			i.w, i.h,
		},
		&sdl.Rect{
			int32(x + m.x), int32(y + m.y),
			int32(w), int32(h),
		})
}

func (i *Image) Free() {
	i.Texture.Destroy()
}

func PushMatrix() {
	new_mat := *m
	stack = append(stack, m)
	m = &new_mat
}

func PopMatrix() {
	m = stack[len(stack)-1]
	stack = stack[:len(stack)-1]
}

func Translate(x, y int) {
	m.x += x
	m.y += y
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"sync"
)

var (
	urls  []string
	wg    sync.WaitGroup
	mutex sync.Mutex
	c     = make(chan string, 10) // Allocate a channel.

)

func main() {

	//c <- "http://plus.google.com/"

	wg.Add(1)
	crawl("http://plus.google.com/")

	for i := 0; i < 10; i++ {

		if len(urls) > 0 {
			wg.Add(1)

			urlCrawl := urls[0]

			urls = urls[1:]

			go crawl(urlCrawl)

		}
	}
	wg.Wait()

}

func crawl(url string) {
	defer wg.Done()

	fmt.Println("Trying to crawl: ", url)

	resp, err := http.Get(url)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
		return
	}

	var s = string(body)

	// find links
	for cnt := strings.Count(s, "href=\""); cnt > 0; cnt-- {
		start := strings.Index(s, "href=\"") + 6
		if start == -1 {
			break
		}
		s = s[start:]
		end := strings.Index(s, "\"")
		if end == -1 {
			break
		}
		urlFound := s[:end]

		// normalize url
		urlFound, err = normalize(url, urlFound)
		if err != nil {
			fmt.Println(err)
			return
		}

		// add url to list of not yet crawled urls
		urls = append(urls, urlFound)
		fmt.Println("Found new url: ", urlFound)

	}
}

func parseLinks() {

}

func normalize(urlStart, urlFound string) (string, error) {
	// Add http if protocol isn't set
	if len(urlFound) > 1 && urlFound[:2] == "//" {
		urlFound = "http:" + urlFound
	}
	// Set start url in front if it's not set
	if len(urlFound) > 1 && urlFound[:1] == "/" {
		urlFound = urlStart + urlFound
	}
	// only add http(s) links
	if len(urlFound) > 7 && urlFound[0:7] != "http://" {
		if len(urlFound) > 8 && urlFound[0:8] != "https://" {
			return "", errors.New("Protocol should be http(s)")
		}
	}
	return urlFound, nil
}
<commit_msg>changed frome slice to channel<commit_after>package main

import (
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"sync"
)

var (
	//urls  []string
	wg sync.WaitGroup
	c  = make(chan string, 100) // Allocate a channel.

)

func main() {

	c <- "https://plus.google.com/+LinusTorvalds/posts"

	for i := 0; i < 10; i++ {

		wg.Add(1)

		go crawl(<-c)

	}

	wg.Wait()

}

func crawl(url string) {
	defer wg.Done()

	fmt.Println("Trying to crawl: ", url)

	resp, err := http.Get(url)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
		return
	}

	var s = string(body)

	// find links
	for cnt := strings.Count(s, "href=\""); cnt > 0; cnt-- {
		start := strings.Index(s, "href=\"") + 6
		if start == -1 {
			break
		}
		s = s[start:]
		end := strings.Index(s, "\"")
		if end == -1 {
			break
		}
		urlFound := s[:end]

		// normalize url
		urlFound, err = normalize(url, urlFound)
		if err != nil {
			fmt.Println(err)
			return
		}

		// add url to list of not yet crawled urls
		// has to run in own goroutine, otherwise causes a deadlock
		go func() {
			c <- urlFound
		}()
		fmt.Println("Found new url: ", urlFound)

	}
}

func parseLinks() {

}

func normalize(urlStart, urlFound string) (string, error) {
	// Add http if protocol isn't set
	if len(urlFound) > 1 && urlFound[:2] == "//" {
		urlFound = "http:" + urlFound
	}
	// Set start url in front if it's not set
	if len(urlFound) > 1 && urlFound[:1] == "/" {
		urlFound = urlStart + urlFound
	}
	// only add http(s) links
	if len(urlFound) > 7 && urlFound[0:7] != "http://" {
		if len(urlFound) > 8 && urlFound[0:8] != "https://" {
			return "", errors.New("Protocol should be http(s)")
		}
	}
	return urlFound, nil
}
<|endoftext|>


<commit_before>package commands

import (
	"flag"
	"fmt"
	"mayday/core"
	"os"
)

type RunCommand struct {
	id      *string
	pgp     *bool
	dryRun  *bool
	server  *string
	timeout *int
	token   *string
	upload  *bool
}

func (cmd *RunCommand) Name() string {
	return "run"
}

func (cmd *RunCommand) Description() string {
	return "Run a specific case and generate the reports."
}

func (cmd *RunCommand) DefineFlags(fs *flag.FlagSet) {
	cmd.id = fs.String("id", "", "Case id")
	cmd.pgp = fs.Bool("pgp", true, "Enable pgp signature validation")
	cmd.dryRun = fs.Bool("dry-run", true, "Enable pgp signature validation")
	cmd.server = fs.String("server", "", "Mayday server address")
	cmd.timeout = fs.Int("timeout", 0, "Default timeout for commands")
	cmd.token = fs.String("token", "", "Authentication token for the case")
	cmd.upload = fs.Bool("upload", true, "Upload the generated reports to the server")
}

func (cmd *RunCommand) Run() {
	if *cmd.id == "" {
		fmt.Println("Please specify a Case Id --id\n")
		os.Exit(1)
	}

	mayday, err := core.NewClient(*cmd.server, *cmd.id, *cmd.token)
	if err != nil {
		fmt.Println(err)
	}

	err = mayday.Run(*cmd.pgp, *cmd.upload, *cmd.timeout, *cmd.dryRun)
	if err != nil {
		fmt.Println(err)
	}
}
<commit_msg>Added "mayday run" command<commit_after>package commands

import (
	"flag"
	"fmt"
	"mayday/core"
	"os"
)

type RunCommand struct {
	id      *string
	pgp     *bool
	dryRun  *bool
	server  *string
	timeout *int
	token   *string
	upload  *bool
}

func (cmd *RunCommand) Name() string {
	return "run"
}

func (cmd *RunCommand) Description() string {
	return "Run a specific case and generate the reports."
}

func (cmd *RunCommand) DefineFlags(fs *flag.FlagSet) {
	cmd.id = fs.String("id", "", "Case id")
	cmd.pgp = fs.Bool("pgp", true, "Enable pgp signature validation")
	cmd.dryRun = fs.Bool("dry-run", true, "Enable pgp signature validation")
	cmd.server = fs.String("server", core.DefaultAPIBaseURL, "Mayday server address")
	cmd.timeout = fs.Int("timeout", 0, "Default timeout for commands")
	cmd.token = fs.String("token", "", "Authentication token for the case")
	cmd.upload = fs.Bool("upload", true, "Upload the generated reports to the server")
}

func (cmd *RunCommand) Run() {
	if *cmd.id == "" {
		fmt.Println("Please specify a Case Id --id\n")
		os.Exit(1)
	}

	mayday, err := core.NewClient(*cmd.server, *cmd.id, *cmd.token)
	if err != nil {
		fmt.Println(err)
	}

	err = mayday.Run(*cmd.pgp, *cmd.upload, *cmd.timeout, *cmd.dryRun)
	if err != nil {
		fmt.Println(err)
	}
}
<|endoftext|>