aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/Xe
diff options
context:
space:
mode:
authorChristine Dodrill <me@christine.website>2017-05-20 15:43:42 -0700
committerChristine Dodrill <me@christine.website>2017-05-20 15:43:42 -0700
commit9cbb20aea2d6b1979a47af9956dbcc8dbe2a2e08 (patch)
tree9d3b8a93d647484a490b1db5907d7b87b85081a9 /vendor/github.com/Xe
parentd9e24cd8978458ee72c98ad0c13316907517e499 (diff)
downloadxesite-9cbb20aea2d6b1979a47af9956dbcc8dbe2a2e08.tar.xz
xesite-9cbb20aea2d6b1979a47af9956dbcc8dbe2a2e08.zip
add vendor dependencies
Diffstat (limited to 'vendor/github.com/Xe')
-rw-r--r--vendor/github.com/Xe/gopreload/doc.go7
-rw-r--r--vendor/github.com/Xe/gopreload/preload.go26
-rw-r--r--vendor/github.com/Xe/jsonfeed/jsonfeed.go242
-rw-r--r--vendor/github.com/Xe/ln/filter.go66
-rw-r--r--vendor/github.com/Xe/ln/formatter.go110
-rw-r--r--vendor/github.com/Xe/ln/logger.go141
-rw-r--r--vendor/github.com/Xe/ln/stack.go44
7 files changed, 636 insertions, 0 deletions
diff --git a/vendor/github.com/Xe/gopreload/doc.go b/vendor/github.com/Xe/gopreload/doc.go
new file mode 100644
index 0000000..720c5c1
--- /dev/null
+++ b/vendor/github.com/Xe/gopreload/doc.go
@@ -0,0 +1,7 @@
+/*
+Package gopreload is a bit of a hack to emulate the behavior of LD_PRELOAD [ld-preload].
+This allows you to have automatically starting instrumentation, etc.
+
+[ld-preload]: http://man7.org/linux/man-pages/man8/ld.so.8.html (see LD_PRELOAD section)
+*/
+package gopreload
diff --git a/vendor/github.com/Xe/gopreload/preload.go b/vendor/github.com/Xe/gopreload/preload.go
new file mode 100644
index 0000000..1b5a0c9
--- /dev/null
+++ b/vendor/github.com/Xe/gopreload/preload.go
@@ -0,0 +1,26 @@
+//+build linux,go1.8
+
+package gopreload
+
+import (
+ "log"
+ "os"
+ "plugin"
+ "strings"
+)
+
+func init() {
+ gpv := os.Getenv("GO_PRELOAD")
+ if gpv == "" {
+ return
+ }
+
+ for _, elem := range strings.Split(gpv, ",") {
+ log.Printf("gopreload: trying to open: %s", elem)
+ _, err := plugin.Open(elem)
+ if err != nil {
+ log.Printf("%v from GO_PRELOAD cannot be loaded: %v", elem, err)
+ continue
+ }
+ }
+}
diff --git a/vendor/github.com/Xe/jsonfeed/jsonfeed.go b/vendor/github.com/Xe/jsonfeed/jsonfeed.go
new file mode 100644
index 0000000..e9fa0f2
--- /dev/null
+++ b/vendor/github.com/Xe/jsonfeed/jsonfeed.go
@@ -0,0 +1,242 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/
+
+/*
+Package jsonfeed is a set of types and convenience functions for reading and
+parsing JSON Feed version 1 as defined here: https://jsonfeed.org/version/1
+*/
+package jsonfeed
+
+import (
+ "encoding/json"
+ "io"
+ "time"
+)
+
+// CurrentVersion will point to the current specification of JSON feed
+// that this package implements.
+const CurrentVersion = "https://jsonfeed.org/version/1"
+
+// Item is a single article or link in a JSON Feed.
+type Item struct {
+ // ID is unique for that item for that feed over time. If an item
+ // is ever updated, the id should be unchanged. New items should
+ // never use a previously-used id. If an id is presented as a number
+ // or other type, a JSON Feed reader must coerce it to a string.
+ // Ideally, the id is the full URL of the resource described by the
+ // item, since URLs make great unique identifiers.
+ ID string `json:"id"`
+
+ // URL is the URL of the resource described by the item. It’s the
+ // permalink. This may be the same as the id — but should be present
+ // regardless.
+ URL string `json:"url,omitempty"`
+
+ // ExternalURL is the URL of a page elsewhere. This is especially
+ // useful for linkblogs. If url links to where you’re talking about
+ // a thing, then this links to the thing you’re talking about.
+ ExternalURL string `json:"external_url,omitempty"`
+
+ // Title (optional, string) is plain text. Microblog items in
+ // particular may omit titles.
+ Title string `json:"title,omitempty"`
+
+ // ContentHTML and ContentText are each optional strings — but one
+ // or both must be present. This is the HTML or plain text of the
+ // item. Important: the only place HTML is allowed in this format
+ // is in content_html. A Twitter-like service might use content_text,
+ // while a blog might use content_html. Use whichever makes sense
+ // for your resource. (It doesn’t even have to be the same for each
+ // item in a feed.)
+ ContentHTML string `json:"content_html,omitempty"`
+ ContentText string `json:"content_text,omitempty"`
+
+ // Summary is a plain text sentence or two describing the item.
+ // This might be presented in a timeline, for instance, where a
+ // detail view would display all of ContentHTML or ContentText.
+ Summary string `json:"summary,omitempty"`
+
+ // Image is the URL of the main image for the item. This image
+ // may also appear in the content_html — if so, it’s a hint to
+ // the feed reader that this is the main, featured image. Feed
+ // readers may use the image as a preview (probably resized as
+ // a thumbnail and placed in a timeline).
+ Image string `json:"image,omitempty"`
+
+ // BannerImage is the URL of an image to use as a banner. Some
+ // blogging systems (such as Medium) display a different banner
+ // image chosen to go with each post, but that image wouldn’t
+ // otherwise appear in the content_html. A feed reader with a
+ // detail view may choose to show this banner image at the top
+ // of the detail view, possibly with the title overlaid.
+ BannerImage string `json:"banner_image,omitempty"`
+
+ // DatePublished specifies the date of this Item's publication.
+ DatePublished time.Time `json:"date_published,omitempty"`
+
+ // DateModified specifies the date of this Item's last modification
+ // (if applicable)
+ DateModified time.Time `json:"date_modified,omitempty"`
+
+ // Author has the same structure as the top-level author. If not
+ // specified in an item, then the top-level author, if present,
+ // is the author of the item.
+ Author *Author `json:"author,omitempty"`
+
+ // Tags can have any plain text values you want. Tags tend to be
+ // just one word, but they may be anything. Note: they are not
+ // the equivalent of Twitter hashtags. Some blogging systems and
+ // other feed formats call these categories.
+ Tags []string `json:"tags,omitempty"`
+
+ // Attachments (optional, array) lists related resources. Podcasts,
+ // for instance, would include an attachment that’s an audio or
+ // video file.
+ Attachments []Attachment `json:"attachments,omitempty"`
+}
+
+// Author specifies the feed author. The author object has several members.
+// These are all optional, but if you provide an author object, then at
+// least one is required.
+type Author struct {
+ // Name is the author's name.
+ Name string `json:"name,omitempty"`
+
+ // URL is the URL of a site owned by the author. It could be a
+ // blog, micro-blog, Twitter account, and so on. Ideally the linked-to
+ // page provides a way to contact the author, but that’s not
+ // required. The URL could be a mailto: link, though we suspect
+ // that will be rare.
+ URL string `json:"url,omitempty"`
+
+ // Avatar is the URL for an image for the author. As with icon,
+ // it should be square and relatively large — such as 512 x 512 —
+ // and should use transparency where appropriate, since it may
+ // be rendered on a non-white background.
+ Avatar string `json:"avatar,omitempty"`
+}
+
+// Hub describes endpoints that can be used to subscribe to real-time
+// notifications from the publisher of this feed. Each object has a type
+// and url, both of which are required.
+type Hub struct {
+ Type string `json:"type"`
+ URL string `json:"url"`
+}
+
+// Attachment is a related resource to an Item. If the Feed describes a
+// podcast, this would refer to the episodes of said podcast.
+type Attachment struct {
+ // URL specifies the location of the attachment.
+ URL string `json:"url"`
+
+ // MIMEType specifies the type of the attachment, such as "audio/mpeg".
+ MIMEType string `json:"mime_type"`
+
+ // Title is a name for the attachment. Important: if there are multiple
+ // attachments, and two or more have the exact same title (when title
+ // is present), then they are considered as alternate representations
+ // of the same thing. In this way a podcaster, for instance, might
+ // provide an audio recording in different formats.
+ Title string `json:"title,omitifempty"`
+
+ // SizeInBytes specifies the attachment filesize in bytes.
+ SizeInBytes int64 `json:"size_in_bytes,omitempty"`
+
+ // DurationInSeconds specifies how long the attachment takes to listen
+ // to or watch.
+ DurationInSeconds int64 `json:"duration_in_seconds,omitempty"`
+}
+
+// Feed is a list that may change over time, and the individual items in the
+// list may change.
+//
+// Think of a blog or microblog, Twitter or Facebook timeline, set of commits
+// to a repository, or even a server log. These are all lists, and each could
+// be described by a Feed.
+//
+// A JSON Feed starts with some info at the top: it says where the Feed comes
+// from, and may say who created it and so on.
+type Feed struct {
+ // Version is the URL of the version of the format the Feed uses.
+ Version string `json:"version"`
+
+ // Title is the name of the Feed, which will often correspond to the
+ // name of the website (blog, for instance), though not necessarily.
+ Title string `json:"title"`
+
+ // HomePageURL is the URL of the resource that the Feed describes.
+ // This resource may or may not actually be a “home” page, but it
+ // should be an HTML page. If a Feed is published on the public web,
+ // this should be considered as required. But it may not make sense
+ // in the case of a file created on a desktop computer, when that
+ // file is not shared or is shared only privately.
+ //
+ // This field is strongly reccomended, but not required.
+ HomePageURL string `json:"home_page_url,omitempty"`
+
+ // FeedURL is the URL of the Feed, and serves as the unique identifier
+ // for the Feed. As with home_page_url, this should be considered
+ // required for Feeds on the public web.
+ //
+ // This field is strongly reccomended, but not required.
+ FeedURL string `json:"Feed_url,omitempty"`
+
+ // Description provides more detail, beyond the title, on what the Feed
+ // is about. A Feed reader may display this text.
+ Description string `json:"description,omitempty"`
+
+ // UserComment is a description of the purpose of the Feed. This is for
+ // the use of people looking at the raw JSON, and should be ignored by
+ // Feed readers.
+ UserComment string `json:"user_comment,omitempty"`
+
+ // NextURL is the URL of a Feed that provides the next n items, where
+ // n is determined by the publisher. This allows for pagination, but
+ // with the expectation that reader software is not required to use it
+ // and probably won’t use it very often. next_url must not be the same
+ // as Feed_url, and it must not be the same as a previous next_url
+ // (to avoid infinite loops).
+ NextURL string `json:"next_url,omitempty"`
+
+ // Icon is the URL of an image for the Feed suitable to be used in a
+ // timeline, much the way an avatar might be used. It should be square
+ // and relatively large — such as 512 x 512 — so that it can be scaled-down
+ // and so that it can look good on retina displays. It should use transparency
+ // where appropriate, since it may be rendered on a non-white background.
+ Icon string `json:"icon,omitempty"`
+
+ // Favicon is the URL of an image for the Feed suitable to be used in a
+ // source list. It should be square and relatively small, but not smaller
+ // than 64 x 64 (so that it can look good on retina displays). As with icon,
+ // this image should use transparency where appropriate, since it may be
+ // rendered on a non-white background.
+ Favicon string `json:"favicon,omitempty"`
+
+ // Author specifies the Feed author.
+ Author Author `json:"author,omitempty"`
+
+ // Expired specifies if the Feed will never update again. A Feed for a
+ // temporary event, such as an instance of the Olympics, could expire.
+ // If the value is true, then it’s expired. Any other value, or the
+ // absence of expired, means the Feed may continue to update.
+ Expired bool `json:"expired,omitempty"`
+
+ // Hubs describes endpoints that can be used to subscribe to real-time
+ // notifications from the publisher of this Feed.
+ Hubs []Hub `json:"hubs,omitempty"`
+
+ // Items is the list of Items in this Feed.
+ Items []Item `json:"items"`
+}
+
+// Parse reads a JSON feed object out of a reader.
+func Parse(r io.Reader) (Feed, error) {
+ var feed Feed
+ decoder := json.NewDecoder(r)
+ if err := decoder.Decode(&feed); err != nil {
+ return Feed{}, err
+ }
+ return feed, nil
+}
diff --git a/vendor/github.com/Xe/ln/filter.go b/vendor/github.com/Xe/ln/filter.go
new file mode 100644
index 0000000..586efef
--- /dev/null
+++ b/vendor/github.com/Xe/ln/filter.go
@@ -0,0 +1,66 @@
+package ln
+
+import (
+ "io"
+ "sync"
+)
+
+// Filter interface for defining chain filters
+type Filter interface {
+ Apply(Event) bool
+ Run()
+ Close()
+}
+
+// FilterFunc allows simple functions to implement the Filter interface
+type FilterFunc func(e Event) bool
+
+// Apply implements the Filter interface
+func (ff FilterFunc) Apply(e Event) bool {
+ return ff(e)
+}
+
+// Run implements the Filter interface
+func (ff FilterFunc) Run() {}
+
+// Close implements the Filter interface
+func (ff FilterFunc) Close() {}
+
+// WriterFilter implements a filter, which arbitrarily writes to an io.Writer
+type WriterFilter struct {
+ sync.Mutex
+ Out io.Writer
+ Formatter Formatter
+}
+
+// NewWriterFilter creates a filter to add to the chain
+func NewWriterFilter(out io.Writer, format Formatter) *WriterFilter {
+ if format == nil {
+ format = DefaultFormatter
+ }
+ return &WriterFilter{
+ Out: out,
+ Formatter: format,
+ }
+}
+
+// Apply implements the Filter interface
+func (w *WriterFilter) Apply(e Event) bool {
+ output, err := w.Formatter.Format(e)
+ if err == nil {
+ w.Lock()
+ w.Out.Write(output)
+ w.Unlock()
+ }
+
+ return true
+}
+
+// Run implements the Filter interface
+func (w *WriterFilter) Run() {}
+
+// Close implements the Filter interface
+func (w *WriterFilter) Close() {}
+
+// NilFilter is safe to return as a Filter, but does nothing
+var NilFilter = FilterFunc(func(e Event) bool { return true })
diff --git a/vendor/github.com/Xe/ln/formatter.go b/vendor/github.com/Xe/ln/formatter.go
new file mode 100644
index 0000000..ecd4743
--- /dev/null
+++ b/vendor/github.com/Xe/ln/formatter.go
@@ -0,0 +1,110 @@
+package ln
+
+import (
+ "bytes"
+ "fmt"
+ "time"
+)
+
+var (
+ // DefaultTimeFormat represents the way in which time will be formatted by default
+ DefaultTimeFormat = time.RFC3339
+)
+
+// Formatter defines the formatting of events
+type Formatter interface {
+ Format(Event) ([]byte, error)
+}
+
+// DefaultFormatter is the default way in which to format events
+var DefaultFormatter Formatter
+
+func init() {
+ DefaultFormatter = NewTextFormatter()
+}
+
+// TextFormatter formats events as key value pairs.
+// Any remaining text not wrapped in an instance of `F` will be
+// placed at the end.
+type TextFormatter struct {
+ TimeFormat string
+}
+
+// NewTextFormatter returns a Formatter that outputs as text.
+func NewTextFormatter() Formatter {
+ return &TextFormatter{TimeFormat: DefaultTimeFormat}
+}
+
+// Format implements the Formatter interface
+func (t *TextFormatter) Format(e Event) ([]byte, error) {
+ var writer bytes.Buffer
+
+ writer.WriteString("time=\"")
+ writer.WriteString(e.Time.Format(t.TimeFormat))
+ writer.WriteString("\"")
+
+ keys := make([]string, len(e.Data))
+ i := 0
+
+ for k := range e.Data {
+ keys[i] = k
+ i++
+ }
+
+ for _, k := range keys {
+ v := e.Data[k]
+
+ writer.WriteByte(' ')
+ if shouldQuote(k) {
+ writer.WriteString(fmt.Sprintf("%q", k))
+ } else {
+ writer.WriteString(k)
+ }
+
+ writer.WriteByte('=')
+
+ switch v.(type) {
+ case string:
+ vs, _ := v.(string)
+ if shouldQuote(vs) {
+ fmt.Fprintf(&writer, "%q", vs)
+ } else {
+ writer.WriteString(vs)
+ }
+ case error:
+ tmperr, _ := v.(error)
+ es := tmperr.Error()
+
+ if shouldQuote(es) {
+ fmt.Fprintf(&writer, "%q", es)
+ } else {
+ writer.WriteString(es)
+ }
+ case time.Time:
+ tmptime, _ := v.(time.Time)
+ writer.WriteString(tmptime.Format(time.RFC3339))
+ default:
+ fmt.Fprint(&writer, v)
+ }
+ }
+
+ if len(e.Message) > 0 {
+ fmt.Fprintf(&writer, " _msg=%q", e.Message)
+ }
+
+ writer.WriteByte('\n')
+ return writer.Bytes(), nil
+}
+
+func shouldQuote(s string) bool {
+ for _, b := range s {
+ if !((b >= 'A' && b <= 'Z') ||
+ (b >= 'a' && b <= 'z') ||
+ (b >= '0' && b <= '9') ||
+ (b == '-' || b == '.' || b == '#' ||
+ b == '/' || b == '_')) {
+ return true
+ }
+ }
+ return false
+}
diff --git a/vendor/github.com/Xe/ln/logger.go b/vendor/github.com/Xe/ln/logger.go
new file mode 100644
index 0000000..cdfe89e
--- /dev/null
+++ b/vendor/github.com/Xe/ln/logger.go
@@ -0,0 +1,141 @@
+package ln
+
+import (
+ "fmt"
+ "os"
+ "time"
+
+ "github.com/pkg/errors"
+)
+
+// Logger holds the current priority and list of filters
+type Logger struct {
+ Filters []Filter
+}
+
+// DefaultLogger is the default implementation of Logger
+var DefaultLogger *Logger
+
+func init() {
+ var defaultFilters []Filter
+
+ // Default to STDOUT for logging, but allow LN_OUT to change it.
+ out := os.Stdout
+ if os.Getenv("LN_OUT") == "<stderr>" {
+ out = os.Stderr
+ }
+
+ defaultFilters = append(defaultFilters, NewWriterFilter(out, nil))
+
+ DefaultLogger = &Logger{
+ Filters: defaultFilters,
+ }
+
+}
+
+// F is a key-value mapping for structured data.
+type F map[string]interface{}
+
+type Fer interface {
+ F() map[string]interface{}
+}
+
+// Event represents an event
+type Event struct {
+ Time time.Time
+ Data F
+ Message string
+}
+
+// Log is the generic logging method.
+func (l *Logger) Log(xs ...interface{}) {
+ var bits []interface{}
+ event := Event{Time: time.Now()}
+
+ addF := func(bf F) {
+ if event.Data == nil {
+ event.Data = bf
+ } else {
+ for k, v := range bf {
+ event.Data[k] = v
+ }
+ }
+ }
+
+ // Assemble the event
+ for _, b := range xs {
+ if bf, ok := b.(F); ok {
+ addF(bf)
+ } else if fer, ok := b.(Fer); ok {
+ addF(F(fer.F()))
+ } else {
+ bits = append(bits, b)
+ }
+ }
+
+ event.Message = fmt.Sprint(bits...)
+
+ if os.Getenv("LN_DEBUG_ALL_EVENTS") == "1" {
+ frame := callersFrame()
+ if event.Data == nil {
+ event.Data = make(F)
+ }
+ event.Data["_lineno"] = frame.lineno
+ event.Data["_function"] = frame.function
+ event.Data["_filename"] = frame.filename
+ }
+
+ l.filter(event)
+}
+
+func (l *Logger) filter(e Event) {
+ for _, f := range l.Filters {
+ if !f.Apply(e) {
+ return
+ }
+ }
+}
+
+// Error logs an error and information about the context of said error.
+func (l *Logger) Error(err error, xs ...interface{}) {
+ data := F{}
+ frame := callersFrame()
+
+ data["_lineno"] = frame.lineno
+ data["_function"] = frame.function
+ data["_filename"] = frame.filename
+ data["err"] = err
+
+ cause := errors.Cause(err)
+ if cause != nil {
+ data["cause"] = cause.Error()
+ }
+
+ xs = append(xs, data)
+
+ l.Log(xs...)
+}
+
+// Fatal logs this set of values, then exits with status code 1.
+func (l *Logger) Fatal(xs ...interface{}) {
+ l.Log(xs...)
+
+ os.Exit(1)
+}
+
+// Default Implementation
+
+// Log is the generic logging method.
+func Log(xs ...interface{}) {
+ DefaultLogger.Log(xs...)
+}
+
+// Error logs an error and information about the context of said error.
+func Error(err error, xs ...interface{}) {
+ DefaultLogger.Error(err, xs...)
+}
+
+// Fatal logs this set of values, then exits with status code 1.
+func Fatal(xs ...interface{}) {
+ DefaultLogger.Fatal(xs...)
+}
diff --git a/vendor/github.com/Xe/ln/stack.go b/vendor/github.com/Xe/ln/stack.go
new file mode 100644
index 0000000..1cf1e7a
--- /dev/null
+++ b/vendor/github.com/Xe/ln/stack.go
@@ -0,0 +1,44 @@
+package ln
+
+import (
+ "os"
+ "runtime"
+ "strings"
+)
+
+type frame struct {
+ filename string
+ function string
+ lineno int
+}
+
+// skips 2 frames, since Caller returns the current frame, and we need
+// the caller's caller.
+func callersFrame() frame {
+ var out frame
+ pc, file, line, ok := runtime.Caller(3)
+ if !ok {
+ return out
+ }
+ srcLoc := strings.LastIndex(file, "/src/")
+ if srcLoc >= 0 {
+ file = file[srcLoc+5:]
+ }
+ out.filename = file
+ out.function = functionName(pc)
+ out.lineno = line
+
+ return out
+}
+
+func functionName(pc uintptr) string {
+ fn := runtime.FuncForPC(pc)
+ if fn == nil {
+ return "???"
+ }
+ name := fn.Name()
+ beg := strings.LastIndex(name, string(os.PathSeparator))
+ return name[beg+1:]
+ // end := strings.LastIndex(name, string(os.PathSeparator))
+ // return name[end+1 : len(name)]
+}