From 7ef3453170ea4ff1686425ec8a2ccc80624a2c72 Mon Sep 17 00:00:00 2001 From: James Rasell Date: Wed, 13 Nov 2019 14:29:14 +0100 Subject: [PATCH] cmd: update policy read to handle nomad and external check entries --- cmd/policy/read/command.go | 77 ++- go.mod | 1 + go.sum | 2 + vendor/github.com/liamg/tml/.gitignore | 2 + vendor/github.com/liamg/tml/.travis.yml | 19 + vendor/github.com/liamg/tml/LICENSE | 674 ++++++++++++++++++++++++ vendor/github.com/liamg/tml/Makefile | 19 + vendor/github.com/liamg/tml/README.md | 97 ++++ vendor/github.com/liamg/tml/disable.go | 18 + vendor/github.com/liamg/tml/example.png | Bin 0 -> 16821 bytes vendor/github.com/liamg/tml/go.mod | 8 + vendor/github.com/liamg/tml/go.sum | 9 + vendor/github.com/liamg/tml/parse.go | 15 + vendor/github.com/liamg/tml/parser.go | 192 +++++++ vendor/github.com/liamg/tml/printf.go | 17 + vendor/github.com/liamg/tml/println.go | 7 + vendor/github.com/liamg/tml/sprintf.go | 11 + vendor/github.com/liamg/tml/tags.go | 48 ++ vendor/modules.txt | 2 + 19 files changed, 1211 insertions(+), 7 deletions(-) create mode 100644 vendor/github.com/liamg/tml/.gitignore create mode 100644 vendor/github.com/liamg/tml/.travis.yml create mode 100644 vendor/github.com/liamg/tml/LICENSE create mode 100644 vendor/github.com/liamg/tml/Makefile create mode 100644 vendor/github.com/liamg/tml/README.md create mode 100644 vendor/github.com/liamg/tml/disable.go create mode 100644 vendor/github.com/liamg/tml/example.png create mode 100644 vendor/github.com/liamg/tml/go.mod create mode 100644 vendor/github.com/liamg/tml/go.sum create mode 100644 vendor/github.com/liamg/tml/parse.go create mode 100644 vendor/github.com/liamg/tml/parser.go create mode 100644 vendor/github.com/liamg/tml/printf.go create mode 100644 vendor/github.com/liamg/tml/println.go create mode 100644 vendor/github.com/liamg/tml/sprintf.go create mode 100644 vendor/github.com/liamg/tml/tags.go diff --git a/cmd/policy/read/command.go b/cmd/policy/read/command.go index bbe543e..bb14eea 100644 --- a/cmd/policy/read/command.go +++ b/cmd/policy/read/command.go @@ -3,23 +3,26 @@ package read import ( "fmt" "os" + "sort" "strings" "github.com/jrasell/sherpa/cmd/helper" "github.com/jrasell/sherpa/pkg/api" clientCfg "github.com/jrasell/sherpa/pkg/config/client" + "github.com/liamg/tml" "github.com/sean-/sysexits" "github.com/spf13/cobra" ) const ( - outputHeader = "Group|Enabled|MinCount|MaxCount|Cooldown|ScaleInCount|ScaleOutCount" + nomadCheckHeader = "CPU In|CPU Out|Memory In|Memory Out" + externalCheckHeader = "Name|Enabled|Provider|Operator|Value|Action|Query" ) func RegisterCommand(rootCmd *cobra.Command) error { cmd := &cobra.Command{ Use: "read", - Short: "Details the scaling policy", + Short: "Details scaling policies associated to a job", Run: func(cmd *cobra.Command, args []string) { runRead(cmd, args) }, @@ -61,11 +64,71 @@ func runRead(_ *cobra.Command, args []string) { os.Exit(sysexits.OK) } - out := []string{outputHeader} + // Sort the keys so the output is ordered alphabetically by group name. + keys := []string{} + for k := range *resp { + keys = append(keys, k) + } + sort.Strings(keys) + + for _, k := range keys { + formatGroupOutput(k, (*resp)[k]) + } +} + +// formatGroupOutput format all the details of a group scaling policy and outputs this to the user +// in a readable, easy to follow fashion. +func formatGroupOutput(group string, policy *api.JobGroupPolicy) { + header := []string{ + fmt.Sprintf("Group|%s", group), + fmt.Sprintf("MinCount|%v", policy.MinCount), + fmt.Sprintf("MaxCount|%v", policy.MaxCount), + fmt.Sprintf("Cooldown|%v", policy.Cooldown), + fmt.Sprintf("ScaleInCount|%v", policy.ScaleInCount), + fmt.Sprintf("ScaleOutCount|%v", policy.ScaleOutCount), + } + + var nomadChecks []string + var externalChecks []string + + // Check we have Nomad checks configured. + if policy.ScaleInMemoryPercentageThreshold != nil || policy.ScaleOutMemoryPercentageThreshold != nil || + policy.ScaleInCPUPercentageThreshold != nil || policy.ScaleOutCPUPercentageThreshold != nil { + + // Create the Nomad check output. + nomadChecks = append(nomadChecks, nomadCheckHeader) + nomadChecks = append(nomadChecks, fmt.Sprintf("%v%%|%v%%|%v%%|%v%%", + *policy.ScaleInCPUPercentageThreshold, *policy.ScaleOutCPUPercentageThreshold, + *policy.ScaleInMemoryPercentageThreshold, *policy.ScaleOutMemoryPercentageThreshold)) + } + + // Check is there are external checks configured. + if policy.ExternalChecks != nil { + + // Set the header. + externalChecks = append(externalChecks, externalCheckHeader) + + // Iterate the checks and format the output. + for name, check := range policy.ExternalChecks { + externalChecks = append(externalChecks, fmt.Sprintf("%s|%v|%s|%s|%v|%s|%s", + name, check.Enabled, check.Provider, check.ComparisonOperator, check.ComparisonValue, check.Action, check.Query)) + } + } + + // Print our top header and include the core required parameters of a group scaling policy. + tml.Println("Scaling Policy:") + fmt.Println(helper.FormatKV(header)) + fmt.Println("") + + if len(nomadChecks) > 0 { + fmt.Println("Nomad Checks:") + fmt.Println(helper.FormatList(nomadChecks)) + fmt.Println("") + } - for group, pol := range *resp { - out = append(out, fmt.Sprintf("%s|%v|%v|%v|%v|%v|%v", - group, pol.Enabled, pol.MinCount, pol.MaxCount, pol.Cooldown, pol.ScaleInCount, pol.ScaleOutCount)) + if len(externalChecks) > 0 { + fmt.Println("External Checks:") + fmt.Println(helper.FormatList(externalChecks)) + fmt.Println("") } - fmt.Println(helper.FormatList(out)) } diff --git a/go.mod b/go.mod index df76c2e..9ab5077 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/hashicorp/golang-lru v0.5.3 // indirect github.com/hashicorp/nomad/api v0.0.0-20190508234936-7ba2378a159e github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/liamg/tml v0.2.0 github.com/mattn/go-isatty v0.0.7 github.com/oklog/run v1.0.0 github.com/panjf2000/ants/v2 v2.1.1 diff --git a/go.sum b/go.sum index c55c533..f3f708e 100644 --- a/go.sum +++ b/go.sum @@ -85,6 +85,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/liamg/tml v0.2.0 h1:Ab4Qs+gWfy5TJ0OPk7OSVwgdPZmRD978LIHgsdqg56A= +github.com/liamg/tml v0.2.0/go.mod h1:0h4EAV/zBOsqI91EWONedjRpO8O0itjGJVd+wG5eC+E= github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= diff --git a/vendor/github.com/liamg/tml/.gitignore b/vendor/github.com/liamg/tml/.gitignore new file mode 100644 index 0000000..acf56c4 --- /dev/null +++ b/vendor/github.com/liamg/tml/.gitignore @@ -0,0 +1,2 @@ +bin +.vscode diff --git a/vendor/github.com/liamg/tml/.travis.yml b/vendor/github.com/liamg/tml/.travis.yml new file mode 100644 index 0000000..6d170b2 --- /dev/null +++ b/vendor/github.com/liamg/tml/.travis.yml @@ -0,0 +1,19 @@ +language: go +go: +- master +env: + - GO111MODULE=on +script: +- make build-travis +deploy: + - provider: releases + skip_cleanup: true + api_key: + secure: "T/uvbRV2dguNO8pEq8xINN1U1GUOkoXVf6Yc7gN0DH7OiNfraj88V5jH5M/tIE/WpFw0zNQXA5oF0V1czs7YG5TytG3/ioUdEyWqcpkeMcFJmhk/MAmSIwbfA0jP5EKuQ7fvaRRRclcLD3rHrxYKnDrKUedaQXraz31pJTydK5IaC8vPVfYAZ4NBGenlxVLXAXZM5uwpdqxLV25BAxdlEQkn5AEeGbii59QNblF5xaoYhQ7i5NL7nn4kKYqWwEJ0+osZ0dIEHVCNaF6hmiTsv7Wv+Yt0cT9FVwsbnV/wsd4XLszbIXXCXwe/cwrs/hxSkPN1FA9Tom9Qho5DPlI4+qf9qvLI+iUZ2XgqLdAvB1zEx0Sv/VdOPHCJuejvdxLCJfHAkjBWkz6U7F1llREtQS0L9tURBbt48LrrAgMKyNoXjknIk3LRQ0Sdd2ncMZ4OMK1OjcLOlfaJnhVsXYhkIVF4n/pS0WC5qn8JqSlxUxgopH13+cELY56d0sOhbIHVSmpZml7NOfgF4K2sLqkT+2uQjWwWBic0kuQ3h5pzcJAZvjUSN6+phxUg3i/EOWeeiiYUv3LS1hX5ZEZ+4ORM++1J3lk/Btk7iH1mYJVJoSg0rWojL3nGGDMrqb+AsdkXOo5LdtjMVzkUWqfvvdzAGoITcc4+FQZ+nt9uPWrUEbA=" + name: "tml $TRAVIS_TAG" + file: + - bin/darwin-amd64/tml + - bin/linux-amd64/tml + on: + repo: liamg/tml + tags: true diff --git a/vendor/github.com/liamg/tml/LICENSE b/vendor/github.com/liamg/tml/LICENSE new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/vendor/github.com/liamg/tml/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/vendor/github.com/liamg/tml/Makefile b/vendor/github.com/liamg/tml/Makefile new file mode 100644 index 0000000..1b3b1e0 --- /dev/null +++ b/vendor/github.com/liamg/tml/Makefile @@ -0,0 +1,19 @@ + +default: build + +build: test + mkdir -p bin + go build ./tml/ -o bin/tml + +build-travis: test + mkdir -p bin/linux-amd64/tml + mkdir -p bin/darwin-amd64/tml + GOOS=linux GOARCH=amd64 go build -o bin/linux-amd64/tml -ldflags "-X github.com/liamg/tml/version.Version=${TRAVIS_TAG}" ./tml + GOOS=darwin GOARCH=amd64 go build -o bin/darwin-amd64/tml -ldflags "-X github.com/liamg/tml/version.Version=${TRAVIS_TAG}" ./tml + +test: + go vet ./... + go test -v ./... + +.PHONY: build test + \ No newline at end of file diff --git a/vendor/github.com/liamg/tml/README.md b/vendor/github.com/liamg/tml/README.md new file mode 100644 index 0000000..135b6aa --- /dev/null +++ b/vendor/github.com/liamg/tml/README.md @@ -0,0 +1,97 @@ +# tml - Terminal Markup Language + +[![Build Status](https://travis-ci.org/liamg/tml.svg "Travis CI status")](https://travis-ci.org/liamg/tml) +[![GoDoc](https://godoc.org/github.com/liamg/tml?status.svg)](https://godoc.org/github.com/liamg/tml) + +A Go module (and standalone binary) to make the output of coloured/formatted text in the terminal easier and more readable. + +You can use it in your Go programs, and bash etc. too. + +![Example screenshot](example.png) + +## Usage in Go + +The output of coloured/formatted text is easy using the following syntax: + +```go +package main + +import "github.com/liamg/tml" + +func main() { + tml.Printf("this text is red and the following is %s\n", "not red") +} +``` + +## Usage in Bash + +First, install tml: + +``` +go get -u github.com/liamg/tml/tml +``` + +Then you can simply pipe text containing tags to tml: + +```bash +#!/bin/bash + +echo "this text is red and the following is not red" | tml +``` + +## Format + +Each tag is enclosed in angle brackets, much like HTML. + +You can nest tags as deeply as you like. + +It's not required to close tags you've opened, though it can make for easier reading. + +### Available Tags + +#### Foreground Colours + +- `` +- `` +- `` +- `` +- `` +- `` +- `` +- `` +- `` +- `` +- `` +- `` +- `` +- `` +- `` +- `` + +#### Background Colours + +- `` +- `` +- `` +- `` +- `` +- `` +- `` +- `` +- `` +- `` +- `` +- `` +- `` +- `` +- `` +- `` + +#### Attributes + +- `` +- `` +- `` +- `` +- `` +- `` diff --git a/vendor/github.com/liamg/tml/disable.go b/vendor/github.com/liamg/tml/disable.go new file mode 100644 index 0000000..de074e1 --- /dev/null +++ b/vendor/github.com/liamg/tml/disable.go @@ -0,0 +1,18 @@ +package tml + +import "sync" + +var disableFormatting bool +var formattingLock sync.RWMutex + +func DisableFormatting() { + formattingLock.Lock() + defer formattingLock.Unlock() + disableFormatting = true +} + +func EnableFormatting() { + formattingLock.Lock() + defer formattingLock.Unlock() + disableFormatting = false +} diff --git a/vendor/github.com/liamg/tml/example.png b/vendor/github.com/liamg/tml/example.png new file mode 100644 index 0000000000000000000000000000000000000000..16469bfad5efdca92c637dc8145f5ef9abcdbb45 GIT binary patch literal 16821 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 literal 0 HcmV?d00001 diff --git a/vendor/github.com/liamg/tml/go.mod b/vendor/github.com/liamg/tml/go.mod new file mode 100644 index 0000000..666bd58 --- /dev/null +++ b/vendor/github.com/liamg/tml/go.mod @@ -0,0 +1,8 @@ +module github.com/liamg/tml + +go 1.12 + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/stretchr/testify v1.3.0 +) diff --git a/vendor/github.com/liamg/tml/go.sum b/vendor/github.com/liamg/tml/go.sum new file mode 100644 index 0000000..4f76e62 --- /dev/null +++ b/vendor/github.com/liamg/tml/go.sum @@ -0,0 +1,9 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= diff --git a/vendor/github.com/liamg/tml/parse.go b/vendor/github.com/liamg/tml/parse.go new file mode 100644 index 0000000..2297dad --- /dev/null +++ b/vendor/github.com/liamg/tml/parse.go @@ -0,0 +1,15 @@ +package tml + +import ( + "strings" + "bytes" +) + +// Parse converts the input string (containing TML tags) into a string containing ANSI escape code sequences for output to the terminal. +func Parse(input string) (string, error) { + output := bytes.NewBufferString("") + if err := NewParser(output).Parse(strings.NewReader(input)); err != nil { + return "", err + } + return output.String(), nil +} diff --git a/vendor/github.com/liamg/tml/parser.go b/vendor/github.com/liamg/tml/parser.go new file mode 100644 index 0000000..684e104 --- /dev/null +++ b/vendor/github.com/liamg/tml/parser.go @@ -0,0 +1,192 @@ +package tml + +import ( + "fmt" + "io" + "strings" +) + +// Parser is used to parse a TML string into an output string containing ANSI escape codes +type Parser struct { + writer io.Writer + IncludeLeadingResets bool + IncludeTrailingResets bool + state parserState +} + +type parserState struct { + fg string + bg string + attrs attrs +} + +type attrs uint8 + +const ( + bold uint8 = 1 + dim = 2 + underline = 4 + blink = 8 + reverse = 16 + hidden = 32 +) + +var resetAll = "\x1b[0m" +var resetFg = "\x1b[39m" +var resetBg = "\x1b[49m" + +var attrMap = map[uint8]string{ + bold: "\x1b[1m", + dim: "\x1b[2m", + underline: "\x1b[4m", + blink: "\x1b[5m", + reverse: "\x1b[7m", + hidden: "\x1b[8m", +} + +func (s *parserState) setFg(esc string) string { + if s.fg == esc { + return "" + } + s.fg = esc + return esc +} + +func (s *parserState) setBg(esc string) string { + if s.bg == esc { + return "" + } + s.bg = esc + return esc +} + +func (s *parserState) setAttr(attr int8) string { + + output := "" + + if attr < 0 { + output = resetAll + s.fg + s.bg + } + + s.attrs = attrs(uint8(s.attrs) + uint8(attr)) + + for attr, esc := range attrMap { + if uint8(s.attrs)&attr > 0 { + output += esc + } + } + + return output +} + +// NewParser creates a new parser that writes to w +func NewParser(w io.Writer) *Parser { + return &Parser{ + writer: w, + IncludeLeadingResets: true, + IncludeTrailingResets: true, + } +} + +func (p *Parser) handleTag(name string) bool { + + if strings.HasPrefix(name, "/") { + name = name[1:] + if _, isFg := fgTags[name]; isFg { + if !disableFormatting { + p.writer.Write([]byte(p.state.setFg(resetFg))) + } + return true + } else if _, isBg := bgTags[name]; isBg { + if !disableFormatting { + p.writer.Write([]byte(p.state.setBg(resetBg))) + } + return true + } else if attr, isAttr := attrTags[name]; isAttr { + if !disableFormatting { + p.writer.Write([]byte(p.state.setAttr(-int8(attr)))) + } + return true + } + return false + } + + if esc, ok := fgTags[name]; ok { + if !disableFormatting { + p.writer.Write([]byte(p.state.setFg(esc))) + } + return true + } + + if esc, ok := bgTags[name]; ok { + if !disableFormatting { + p.writer.Write([]byte(p.state.setBg(esc))) + } + return true + } + + if attr, ok := attrTags[name]; ok { + if !disableFormatting { + p.writer.Write([]byte(p.state.setAttr(int8(attr)))) + } + return true + } + + return false +} + +// Parse takes input from the reader and converts any provided tags to the relevant ANSI escape codes for output to parser's writer. +func (p *Parser) Parse(reader io.Reader) error { + + formattingLock.RLock() + defer formattingLock.RUnlock() + + buffer := make([]byte, 1024) + + if p.IncludeLeadingResets && !disableFormatting { + if _, err := p.writer.Write([]byte(resetAll)); err != nil { + return err + } + } + + var inTag bool + var tagName string + + for { + n, err := reader.Read(buffer) + if err != nil { + if err == io.EOF { + break + } + return err + } + for _, r := range []rune(string(buffer[:n])) { + + if inTag { + if r == '>' { + if !p.handleTag(tagName) { + p.writer.Write([]byte(fmt.Sprintf("<%s>", tagName))) + } + tagName = "" + inTag = false + continue + } + tagName = fmt.Sprintf("%s%c", tagName, r) + continue + } + + if r == '<' { + inTag = true + continue + } + + p.writer.Write([]byte(string([]rune{r}))) + } + } + + if p.IncludeTrailingResets && !disableFormatting { + p.writer.Write([]byte(resetAll)) + } + + return nil +} diff --git a/vendor/github.com/liamg/tml/printf.go b/vendor/github.com/liamg/tml/printf.go new file mode 100644 index 0000000..e259435 --- /dev/null +++ b/vendor/github.com/liamg/tml/printf.go @@ -0,0 +1,17 @@ +package tml + +import ( + "fmt" +) + +// Printf works like fmt.Printf, but adds the option of using tags to apply colour or text formatting to the written text. For example "some red text". +// A full list of tags is available here: https://github.com/liamg/tml +func Printf(input string, a ...interface{}) error { + format, err := Parse(input) + if err != nil { + return err + } + _, err = fmt.Printf(format, a...) + return err +} + diff --git a/vendor/github.com/liamg/tml/println.go b/vendor/github.com/liamg/tml/println.go new file mode 100644 index 0000000..e91de1d --- /dev/null +++ b/vendor/github.com/liamg/tml/println.go @@ -0,0 +1,7 @@ +package tml + +// Println works like fmt.Println, but adds the option of using tags to apply colour or text formatting to the written text. For example "some red text". +// A full list of tags is available here: https://github.com/liamg/tml +func Println(input string) { + Printf(input + "\n") +} diff --git a/vendor/github.com/liamg/tml/sprintf.go b/vendor/github.com/liamg/tml/sprintf.go new file mode 100644 index 0000000..36e7d05 --- /dev/null +++ b/vendor/github.com/liamg/tml/sprintf.go @@ -0,0 +1,11 @@ +package tml + +import "fmt" + +// Sprintf works like fmt.Sprintf, but adds the option of using tags to apply colour or text formatting to the written text. For example "some red text". +// A full list of tags is available here: https://github.com/liamg/tml +func Sprintf(input string, a ...interface{}) string { + // parsing cannot fail as the reader/writer are simply for local strings + format, _ := Parse(input) + return fmt.Sprintf(format, a...) +} diff --git a/vendor/github.com/liamg/tml/tags.go b/vendor/github.com/liamg/tml/tags.go new file mode 100644 index 0000000..81722d1 --- /dev/null +++ b/vendor/github.com/liamg/tml/tags.go @@ -0,0 +1,48 @@ +package tml + +var fgTags = map[string]string{ + "red": "\x1b[31m", + "green": "\x1b[32m", + "yellow": "\x1b[33m", + "blue": "\x1b[34m", + "magenta": "\x1b[35m", + "cyan": "\x1b[36m", + "lightgrey": "\x1b[37m", + "darkgrey": "\x1b[90m", + "black": "\x1b[30m", + "lightred": "\x1b[91m", + "lightgreen": "\x1b[92m", + "lightyellow": "\x1b[93m", + "lightblue": "\x1b[94m", + "lightmagenta": "\x1b[95m", + "lightcyan": "\x1b[96m", + "white": "\x1b[97m", +} + +var bgTags = map[string]string{ + "bg-red": "\x1b[41m", + "bg-green": "\x1b[42m", + "bg-yellow": "\x1b[43m", + "bg-blue": "\x1b[44m", + "bg-magenta": "\x1b[45m", + "bg-cyan": "\x1b[46m", + "bg-lightgrey": "\x1b[47m", + "bg-darkgrey": "\x1b[40m", + "bg-black": "\x1b[40m", + "bg-lightred": "\x1b[101m", + "bg-lightgreen": "\x1b[102m", + "bg-lightyellow": "\x1b[103m", + "bg-lightblue": "\x1b[104m", + "bg-lightmagenta": "\x1b[105m", + "bg-lightcyan": "\x1b[106m", + "bg-white": "\x1b[107m", +} + +var attrTags = map[string]uint8{ + "bold": bold, + "dim": dim, + "underline": underline, + "blink": blink, + "reverse": reverse, + "hidden": hidden, +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 7b4f9cf..62dcd68 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -43,6 +43,8 @@ github.com/hashicorp/nomad/api/contexts github.com/hashicorp/serf/coordinate # github.com/inconshreveable/mousetrap v1.0.0 github.com/inconshreveable/mousetrap +# github.com/liamg/tml v0.2.0 +github.com/liamg/tml # github.com/magiconair/properties v1.8.0 github.com/magiconair/properties # github.com/mattn/go-isatty v0.0.7