")
+ if !f.preventSurroundingPre {
+ fmt.Fprint(w, "
")
+ }
if wrapInTable {
fmt.Fprint(w, "
\n")
diff --git a/vendor/github.com/alecthomas/chroma/lexers/b/bash.go b/vendor/github.com/alecthomas/chroma/lexers/b/bash.go
index ff4e4a80..131e432f 100644
--- a/vendor/github.com/alecthomas/chroma/lexers/b/bash.go
+++ b/vendor/github.com/alecthomas/chroma/lexers/b/bash.go
@@ -36,7 +36,7 @@ var Bash = internal.Register(MustNewLexer(
{`\b(if|fi|else|while|do|done|for|then|return|function|case|select|continue|until|esac|elif)(\s*)\b`, ByGroups(Keyword, Text), nil},
{"\\b(alias|bg|bind|break|builtin|caller|cd|command|compgen|complete|declare|dirs|disown|echo|enable|eval|exec|exit|export|false|fc|fg|getopts|hash|help|history|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|set|shift|shopt|source|suspend|test|time|times|trap|true|type|typeset|ulimit|umask|unalias|unset|wait)(?=[\\s)`])", NameBuiltin, nil},
{`\A#!.+\n`, CommentPreproc, nil},
- {`#.*\n`, CommentSingle, nil},
+ {`#.*\S`, CommentSingle, nil},
{`\\[\w\W]`, LiteralStringEscape, nil},
{`(\b\w+)(\s*)(\+?=)`, ByGroups(NameVariable, Text, Operator), nil},
{`[\[\]{}()=]`, Operator, nil},
diff --git a/vendor/github.com/alecthomas/chroma/lexers/e/elixir.go b/vendor/github.com/alecthomas/chroma/lexers/e/elixir.go
index 23fa8af6..40730290 100644
--- a/vendor/github.com/alecthomas/chroma/lexers/e/elixir.go
+++ b/vendor/github.com/alecthomas/chroma/lexers/e/elixir.go
@@ -36,9 +36,9 @@ var Elixir = internal.Register(MustNewLexer(
{`\\\\|\<\<|\>\>|\=\>|\(|\)|\:|\;|\,|\[|\]`, Punctuation, nil},
{`&\d`, NameEntity, nil},
{`\<|\>|\+|\-|\*|\/|\!|\^|\&`, Operator, nil},
- {`0b[01]+`, LiteralNumberBin, nil},
- {`0o[0-7]+`, LiteralNumberOct, nil},
- {`0x[\da-fA-F]+`, LiteralNumberHex, nil},
+ {`0b[01](_?[01])*`, LiteralNumberBin, nil},
+ {`0o[0-7](_?[0-7])*`, LiteralNumberOct, nil},
+ {`0x[\da-fA-F](_?[\dA-Fa-f])*`, LiteralNumberHex, nil},
{`\d(_?\d)*\.\d(_?\d)*([eE][-+]?\d(_?\d)*)?`, LiteralNumberFloat, nil},
{`\d(_?\d)*`, LiteralNumberInteger, nil},
{`"""\s*`, LiteralStringHeredoc, Push("heredoc_double")},
diff --git a/vendor/github.com/alecthomas/chroma/lexers/g/go.go b/vendor/github.com/alecthomas/chroma/lexers/g/go.go
index 54c23c3c..a93fa8bb 100644
--- a/vendor/github.com/alecthomas/chroma/lexers/g/go.go
+++ b/vendor/github.com/alecthomas/chroma/lexers/g/go.go
@@ -42,6 +42,7 @@ var Go = internal.Register(MustNewLexer(
{"(`)([^`]*)(`)", ByGroups(LiteralString, Using(TypeRemappingLexer(GoTextTemplate, TypeMapping{{Other, LiteralString, nil}})), LiteralString), nil},
{`"(\\\\|\\"|[^"])*"`, LiteralString, nil},
{`(<<=|>>=|<<|>>|<=|>=|&\^=|&\^|\+=|-=|\*=|/=|%=|&=|\|=|&&|\|\||<-|\+\+|--|==|!=|:=|\.\.\.|[+\-*/%&])`, Operator, nil},
+ {`([a-zA-Z_]\w*)(\s*)(\()`, ByGroups(NameFunction, UsingSelf("root"), Punctuation), nil},
{`[|^<>=!()\[\]{}.,;:]`, Punctuation, nil},
{`[^\W\d]\w*`, NameOther, nil},
},
diff --git a/vendor/github.com/alecthomas/chroma/lexers/h/http.go b/vendor/github.com/alecthomas/chroma/lexers/h/http.go
index 67bc71a4..b8c29729 100644
--- a/vendor/github.com/alecthomas/chroma/lexers/h/http.go
+++ b/vendor/github.com/alecthomas/chroma/lexers/h/http.go
@@ -85,6 +85,7 @@ func (d *httpBodyContentTyper) Tokenise(options *TokeniseOptions, text string) (
}
case token.Type == Literal && isContentType:
{
+ isContentType = false
contentType = strings.TrimSpace(token.Value)
pos := strings.Index(contentType, ";")
if pos > 0 {
diff --git a/vendor/github.com/alecthomas/chroma/lexers/s/systemd.go b/vendor/github.com/alecthomas/chroma/lexers/s/systemd.go
new file mode 100644
index 00000000..e2f7e9b7
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/lexers/s/systemd.go
@@ -0,0 +1,29 @@
+package s
+
+import (
+ . "github.com/alecthomas/chroma" // nolint
+ "github.com/alecthomas/chroma/lexers/internal"
+)
+
+var SYSTEMD = internal.Register(MustNewLexer(
+ &Config{
+ Name: "SYSTEMD",
+ Aliases: []string{"systemd"},
+ Filenames: []string{"*.service"},
+ MimeTypes: []string{"text/plain"},
+ },
+ Rules {
+ "root": {
+ {`\s+`, Text, nil},
+ {`[;#].*`, Comment, nil},
+ {`\[.*?\]$`, Keyword, nil},
+ {`(.*?)(=)(.*)(\\\n)`, ByGroups(NameAttribute, Operator, LiteralString, Text), Push("continuation")},
+ {`(.*?)(=)(.*)`, ByGroups(NameAttribute, Operator, LiteralString), nil},
+ },
+ "continuation": {
+ {`(.*?)(\\\n)`, ByGroups(LiteralString, Text), nil},
+ {`(.*)`, LiteralString, Pop(1)},
+ },
+ },
+))
+
diff --git a/vendor/github.com/alecthomas/chroma/lexers/t/tradingview.go b/vendor/github.com/alecthomas/chroma/lexers/t/tradingview.go
new file mode 100644
index 00000000..e411411e
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/lexers/t/tradingview.go
@@ -0,0 +1,36 @@
+package t
+
+import (
+ . "github.com/alecthomas/chroma" // nolint
+ "github.com/alecthomas/chroma/lexers/internal"
+)
+
+// TradingView lexer.
+var TradingView = internal.Register(MustNewLexer(
+ &Config{
+ Name: "TradingView",
+ Aliases: []string{"tradingview", "tv"},
+ Filenames: []string{"*.tv"},
+ MimeTypes: []string{"text/x-tradingview"},
+ DotAll: true,
+ },
+ Rules{
+ "root": {
+ {`[^\S\n]+|\n|[()]`, Text, nil},
+ {`(//.*?)(\n)`, ByGroups(CommentSingle, Text), nil},
+ {`>=|<=|==|!=|>|<|\?|-|\+|\*|\/|%|\[|\]`, Operator, nil},
+ {`[:,.]`, Punctuation, nil},
+ {`=`, KeywordPseudo, nil},
+ {`"(\\\\|\\"|[^"\n])*["\n]`, LiteralString, nil},
+ {`'\\.'|'[^\\]'`, LiteralString, nil},
+ {`[0-9](\.[0-9]*)?([eE][+-][0-9]+)?`, LiteralNumber, nil},
+ {`(abs|acos|alertcondition|alma|asin|atan|atr|avg|barcolor|barssince|bgcolor|cci|ceil|change|cog|correlation|cos|crossover|crossunder|cum|dev|ema|exp|falling|fill|fixnan|floor|heikinashi|highest|highestbars|hline|iff|input|kagi|linebreak|linreg|log|log10|lowest|lowestbars|macd|max|min|mom|nz|percentile_linear_interpolation|percentile_nearest_rank|percentrank|pivothigh|pivotlow|plot|plotarrow|plotbar|plotcandle|plotchar|plotshape|pointfigure|pow|renko|rising|rma|roc|round|rsi|sar|security|sign|sin|sma|sqrt|stdev|stoch|study|sum|swma|tan|tostring|tsi|valuewhen|variance|vwma|wma|strategy\.(cancel|cancel_all|close|close_all|entry|exit|order)|strategy\.risk\.(allow_entry_in|max_cons_loss_days|max_drawdown|max_intraday_filled_orders|max_intraday_loss|max_position_size))\b`, NameFunction, nil},
+ {`\b(cross|dayofmonth|dayofweek|hour|minute|month|na|offset|second|tickerid|time|tr|vwap|weekofyear|year)(\()`, ByGroups(NameFunction, Text), nil}, // functions that can also be variable
+ {`(accdist|aqua|area|areabr|black|blue|bool|circles|close|columns|currency\.(AUD|CAD|CHF|EUR|GBP|HKD|JPY|NOK|NONE|NZD|SEK|SGD|TRY|USD|ZAR)|dashed|dotted|float|friday|fuchsia|gray|green|high|histogram|hl2|hlc3|integer|interval|isdaily|isdwm|isintraday|ismonthly|isweekly|lime|line|linebr|location\.(abovebar|belowbar|bottom|top)|low|maroon|monday|n|navy|ohlc4|olive|open|orange|period|purple|red|resolution|saturday|scale\.(left|none|right)|session|session\.(extended|regular)|silver|size\.(auto|huge|large|normal|small|tiny)|solid|source|string|sunday|symbol|syminfo\.(mintick|pointvalue|prefix|root|session)|teal|thursday|ticker|tuesday|volume|wednesday|white|yellow|strategy\.(cash|position_size|closedtrades|direction\.(all|long|short)|equity|eventrades|fixed|grossloss|grossprofit|initial_capital|long|losstrades|max_contracts_held_all|max_contracts_held_long|max_contracts_held_short|max_drawdown|netprofit|oca\.(cancel|none|reduce)|openprofit|opentrades|percent_of_equity|position_avg_price|position_entry_name|short|wintrades)|shape\.(arrowdown|arrowup|circle|cross|diamond|flag|labeldown|labelup|square|triangledown|triangleup|xcross)|barstate\.is(first|history|last|new|realtime)|barmerge\.(gaps_on|gaps_off|lookahead_on|lookahead_off)|strategy\.commission\.(cash_per_contract|cash_per_order|percent))\b`, NameVariable, nil},
+ {`(cross|dayofmonth|dayofweek|hour|minute|month|na|second|tickerid|time|tr|vwap|weekofyear|year)(\b[^\(])`, ByGroups(NameVariable, Text), nil}, // variables that can also be function
+ {`(true|false)\b`, KeywordConstant, nil},
+ {`(and|or|not|if|else|for|to)\b`, OperatorWord, nil},
+ {`@?[_a-zA-Z]\w*`, Text, nil},
+ },
+ },
+))
diff --git a/vendor/github.com/andygrunwald/go-gerrit/projects_commit.go b/vendor/github.com/andygrunwald/go-gerrit/projects_commit.go
index a166341b..d4bb9425 100644
--- a/vendor/github.com/andygrunwald/go-gerrit/projects_commit.go
+++ b/vendor/github.com/andygrunwald/go-gerrit/projects_commit.go
@@ -26,11 +26,11 @@ func (s *ProjectsService) GetCommit(projectName, commitID string) (*CommitInfo,
return v, resp, err
}
-// GetCommitContent gets the content of a file from the HEAD revision of a certain branch.
+// GetCommitContent gets the content of a file from a certain commit.
// The content is returned as base64 encoded string.
//
-// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#get-content
-func (s *ProjectsService) GetCommitContent(projectName, branchID, fileID string) (string, *Response, error) {
- u := fmt.Sprintf("projects/%s/branches/%s/files/%s/content", url.QueryEscape(projectName), branchID, fileID)
+// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html##get-content-from-commit
+func (s *ProjectsService) GetCommitContent(projectName, commitID, fileID string) (string, *Response, error) {
+ u := fmt.Sprintf("projects/%s/commits/%s/files/%s/content", url.QueryEscape(projectName), commitID, fileID)
return getStringResponseWithoutOptions(s.client, u)
}
diff --git a/vendor/github.com/gdamore/tcell/README.adoc b/vendor/github.com/gdamore/tcell/README.adoc
new file mode 100644
index 00000000..3b600577
--- /dev/null
+++ b/vendor/github.com/gdamore/tcell/README.adoc
@@ -0,0 +1,270 @@
+= tcell
+
+
+image:https://img.shields.io/travis/gdamore/tcell.svg?label=linux[Linux Status,link="https://travis-ci.org/gdamore/tcell"]
+image:https://img.shields.io/appveyor/ci/gdamore/tcell.svg?label=windows[Windows Status,link="https://ci.appveyor.com/project/gdamore/tcell"]
+image:https://img.shields.io/badge/license-APACHE2-blue.svg[Apache License,link="https://github.com/gdamore/tcell/blob/master/LICENSE"]
+image:https://img.shields.io/badge/gitter-join-brightgreen.svg[Gitter,link="https://gitter.im/gdamore/tcell"]
+image:https://img.shields.io/badge/godoc-reference-blue.svg[GoDoc,link="https://godoc.org/github.com/gdamore/tcell"]
+image:http://goreportcard.com/badge/gdamore/tcell[Go Report Card,link="http://goreportcard.com/report/gdamore/tcell"]
+image:https://codecov.io/gh/gdamore/tcell/branch/master/graph/badge.svg[codecov,link="https://codecov.io/gh/gdamore/tcell"]
+image:https://tidelift.com/badges/github/gdamore/tcell?style=flat[Dependencies]
+
+[cols="2",grid="none"]
+|===
+|_Tcell_ is a _Go_ package that provides a cell based view for text terminals, like _xterm_.
+It was inspired by _termbox_, but includes many additional improvements.
+a|[.right]
+image::logos/tcell.png[float="right"]
+|===
+
+## Examples
+
+* https://github.com/gdamore/proxima5[proxima5] - space shooter (https://youtu.be/jNxKTCmY_bQ[video])
+* https://github.com/gdamore/govisor[govisor] - service management UI (http://2.bp.blogspot.com/--OsvnfzSNow/Vf7aqMw3zXI/AAAAAAAAARo/uOMtOvw4Sbg/s1600/Screen%2BShot%2B2015-09-20%2Bat%2B9.08.41%2BAM.png[screenshot])
+* mouse demo - included mouse test (http://2.bp.blogspot.com/-fWvW5opT0es/VhIdItdKqJI/AAAAAAAAATE/7Ojc0L1SpB0/s1600/Screen%2BShot%2B2015-10-04%2Bat%2B11.47.13%2BPM.png[screenshot])
+* https://github.com/gdamore/gomatrix[gomatrix] - converted from Termbox
+* https://github.com/zyedidia/micro/[micro] - lightweight text editor with syntax-highlighting and themes
+* https://github.com/viktomas/godu[godu] - simple golang utility helping to discover large files/folders.
+* https://github.com/rivo/tview[tview] - rich interactive widgets for terminal UIs
+* https://github.com/marcusolsson/tui-go[tui-go] - UI library for terminal apps
+* https://github.com/rgm3/gomandelbrot[gomandelbrot] - Mandelbrot!
+* https://github.com/senorprogrammer/wtf[WTF]- Personal information dashboard for your terminal
+* https://github.com/browsh-org/browsh[browsh] - A fully-modern text-based browser, rendering to TTY and browsers (https://www.youtube.com/watch?v=HZq86XfBoRo[video])
+* https://github.com/sachaos/go-life[go-life] - Conway's Game of Life.
+
+## Pure Go Terminfo Database
+
+_Tcell_ includes a full parser and expander for terminfo capability strings,
+so that it can avoid hard coding escape strings for formatting. It also favors
+portability, and includes support for all POSIX systems.
+
+The database is also flexible & extensible, and can modified by either running
+a program to build the entire database, or an entry for just a single terminal.
+
+## More Portable
+
+_Tcell_ is portable to a wide variety of systems.
+_Tcell_ is believed
+to work with all of the systems officially supported by golang with
+the exception of nacl (which lacks any kind of a terminal interface).
+(Plan9 is not supported by _Tcell_, but it is experimental status only
+in golang.) For all of these systems *except Solaris/illumos*, _Tcell_
+is pure Go, with no need for CGO.
+
+## No Async IO
+
+_Tcell_ is able to operate without requiring `SIGIO` signals (unlike _termbox_),
+or asynchronous I/O, and can instead use standard Go file
+objects and Go routines.
+This means it should be safe, especially for
+use with programs that use exec, or otherwise need to manipulate the
+tty streams.
+This model is also much closer to idiomatic Go, leading
+to fewer surprises.
+
+## Rich Unicode & non-Unicode support
+
+_Tcell_ includes enhanced support for Unicode, including wide characters and
+combining characters, provided your terminal can support them.
+Note that
+Windows terminals generally don't support the full Unicode repertoire.
+
+It will also convert to and from Unicode locales, so that the program
+can work with UTF-8 internally, and get reasonable output in other locales.
+_Tcell_ tries hard to convert to native characters on both input and output, and
+on output _Tcell_ even makes use of the alternate character set to facilitate
+drawing certain characters.
+
+## More Function Keys
+
+_Tcell_ also has richer support for a larger number of special keys that some terminals can send.
+
+## Better Color Handling
+
+_Tcell_ will respect your terminal's color space as specified within your terminfo
+entries, so that for example attempts to emit color sequences on VT100 terminals
+won't result in unintended consequences.
+
+In Windows mode, _Tcell_ supports 16 colors, bold, dim, and reverse,
+instead of just termbox's 8 colors with reverse. (Note that there is some
+conflation with bold/dim and colors.)
+
+_Tcell_ maps 16 colors down to 8, for terminals that need it.
+(The upper 8 colors are just brighter versions of the lower 8.)
+
+## Better Mouse Support
+
+_Tcell_ supports enhanced mouse tracking mode, so your application can receive
+regular mouse motion events, and wheel events, if your terminal supports it.
+
+## _Termbox_ Compatibility
+
+A compatibility layer for _termbox_ is provided in the `compat` directory.
+To use it, try importing `github.com/gdamore/tcell/termbox`
+instead. Most _termbox-go_ programs will probably work without further
+modification.
+
+## Working With Unicode
+
+Internally Tcell uses UTF-8, just like Go.
+However, Tcell understands how to
+convert to and from other character sets, using the capabilities of
+the `golang.org/x/text/encoding packages`.
+Your application must supply
+them, as the full set of the most common ones bloats the program by about 2MB.
+If you're lazy, and want them all anyway, see the `encoding` sub-directory.
+
+## Wide & Combining Characters
+
+The `SetContent()` API takes a primary rune, and an optional list of combining runes.
+If any of the runes is a wide (East Asian) rune occupying two cells,
+then the library will skip output from the following cell, but care must be
+taken in the application to avoid explicitly attempting to set content in the
+next cell, otherwise the results are undefined. (Normally wide character
+is displayed, and the other character is not; do not depend on that behavior.)
+
+Experience has shown that the vanilla Windows 8 console application does not
+support any of these characters properly, but at least some options like
+_ConEmu_ do support Wide characters.
+
+## Colors
+
+_Tcell_ assumes the ANSI/XTerm color model, including the 256 color map that
+XTerm uses when it supports 256 colors. The terminfo guidance will be
+honored, with respect to the number of colors supported. Also, only
+terminals which expose ANSI style `setaf` and `setab` will support color;
+if you have a color terminal that only has `setf` and `setb`, please let me
+know; it wouldn't be hard to add that if there is need.
+
+## 24-bit Color
+
+_Tcell_ _supports true color_! (That is, if your terminal can support it,
+_Tcell_ can accurately display 24-bit color.)
+
+To use 24-bit color, you need to use a terminal that supports it. Modern
+xterm and similar teminal emulators can support this. As terminfo lacks any
+way to describe this capability, we fabricate the capability for
+terminals with names ending in `*-truecolor`. The stock distribution ships
+with a database that defines `xterm-truecolor`.
+To try it out, set your
+`TERM` variable to `xterm-truecolor`.
+
+When using TrueColor, programs will display the colors that the programmer
+intended, overriding any "`themes`" you may have set in your terminal
+emulator. (For some cases, accurate color fidelity is more important
+than respecting themes. For other cases, such as typical text apps that
+only use a few colors, its more desirable to respect the themes that
+the user has established.)
+
+If you find this undesirable, you can either use a `TERM` variable
+that lacks the `TRUECOLOR` setting, or set `TCELL_TRUECOLOR=disable` in your
+environment.
+
+## Performance
+
+Reasonable attempts have been made to minimize sending data to terminals,
+avoiding repeated sequences or drawing the same cell on refresh updates.
+
+## Terminfo
+
+(Not relevent for Windows users.)
+
+The Terminfo implementation operates with two forms of database. The first
+is the built-in go database, which contains a number of real database entries
+that are compiled into the program directly. This should minimize calling
+out to database file searches.
+
+The second is in the form of JSON files, that contain the same information,
+which can be located either by the `$TCELLDB` environment file, `$HOME/.tcelldb`,
+or is located in the Go source directory as `database.json`.
+
+These files (both the Go and the JSON files) can be generated using the
+mkinfo.go program. If you need to regnerate the entire set for some reason,
+run the mkdatabase.sh file. The generation uses the infocmp(1) program on
+the system to collect the necessary information.
+
+The `mkinfo.go` program can also be used to generate specific database entries
+for named terminals, in case your favorite terminal is missing. (If you
+find that this is the case, please let me know and I'll try to add it!)
+
+_Tcell_ requires that the terminal support the `cup` mode of cursor addressing.
+Terminals without absolute cursor addressability are not supported.
+This is unlikely to be a problem; such terminals have not been mass produced
+since the early 1970s.
+
+## Mouse Support
+
+Mouse support is detected via the `kmous` terminfo variable, however,
+enablement/disablement and decoding mouse events is done using hard coded
+sequences based on the XTerm X11 model. As of this writing all popular
+terminals with mouse tracking support this model. (Full terminfo support
+is not possible as terminfo sequences are not defined.)
+
+On Windows, the mouse works normally.
+
+Mouse wheel buttons on various terminals are known to work, but the support
+in terminal emulators, as well as support for various buttons and
+live mouse tracking, varies widely. Modern _xterm_, macOS _Terminal_, and _iTerm_ all work well.
+
+## Testablity
+
+There is a `SimulationScreen`, that can be used to simulate a real screen
+for automated testing. The supplied tests do this. The simulation contains
+event delivery, screen resizing support, and capabilities to inject events
+and examine "`physical`" screen contents.
+
+## Platforms
+
+### POSIX (Linux, FreeBSD, macOS, Solaris, etc.)
+
+For mainstream systems with a suitably well defined system call interface
+to tty settings, everything works using pure Go.
+
+For the remainder (right now means only Solaris/illumos) we use POSIX function
+calls to manage termios, which implies that CGO is required on those platforms.
+
+### Windows
+
+Windows console mode applications are supported. Unfortunately _mintty_
+and other _cygwin_ style applications are not supported.
+
+Modern console applications like ConEmu, as well as the Windows 10
+console itself, support all the good features (resize, mouse tracking, etc.)
+
+I haven't figured out how to cleanly resolve the dichotomy between cygwin
+style termios and the Windows Console API; it seems that perhaps nobody else
+has either. If anyone has suggestions, let me know! Really, if you're
+using a Windows application, you should use the native Windows console or a
+fully compatible console implementation.
+
+### Plan9 and Native Client (Nacl)
+
+The nacl and plan9 platforms won't work, but compilation stubs are supplied
+for folks that want to include parts of this in software targetting those
+platforms. The Simulation screen works, but as Tcell doesn't know how to
+allocate a real screen object on those platforms, `NewScreen()` will fail.
+
+If anyone has wisdom about how to improve support for either of these,
+please let me know. PRs are especially welcome.
+
+### Commercial Support
+
+_Tcell_ is absolutely free, but if you want to obtain commercial, professional support, there are options.
+
+[cols="2",align="center",frame="none", grid="none"]
+|===
+^.^|
+image:logos/tidelift.png[100,100]
+a|
+https://tidelift.com/[Tidelift] subscriptions include support for _Tcell_, as well as many other open source packages.
+
+^.^|
+image:logos/staysail.png[100,100]
+a|
+mailto:info@staysail.tech[Staysail Systems, Inc.] offers direct support, and custom development around _Tcell_ on an hourly basis.
+
+^.^|
+image:logos/patreon.png[100,100]
+a|I also welcome donations at https://www.patron.com/gedamore/[Patreon], if you just want to make a contribution.
+|===
diff --git a/vendor/github.com/gdamore/tcell/README.md b/vendor/github.com/gdamore/tcell/README.md
deleted file mode 100644
index ed7297b5..00000000
--- a/vendor/github.com/gdamore/tcell/README.md
+++ /dev/null
@@ -1,255 +0,0 @@
-## tcell
-
-[](https://travis-ci.org/gdamore/tcell)
-[](https://ci.appveyor.com/project/gdamore/tcell)
-[](https://github.com/gdamore/tcell/blob/master/LICENSE)
-[](https://gitter.im/gdamore/tcell)
-[](https://godoc.org/github.com/gdamore/tcell)
-[](http://goreportcard.com/report/gdamore/tcell)
-[](https://codecov.io/gh/gdamore/tcell)
-
-
-Package tcell provides a cell based view for text terminals, like xterm.
-It was inspired by termbox, but differs from termbox in some important
-ways. It also adds substantial functionality beyond termbox.
-
-## Examples
-
-* [proxima5](https://github.com/gdamore/proxima5) - space shooter ([video](https://youtu.be/jNxKTCmY_bQ))
-* [govisor](https://github.com/gdamore/govisor) - service management UI ([screenshot](http://2.bp.blogspot.com/--OsvnfzSNow/Vf7aqMw3zXI/AAAAAAAAARo/uOMtOvw4Sbg/s1600/Screen%2BShot%2B2015-09-20%2Bat%2B9.08.41%2BAM.png))
-* mouse demo - [screenshot](http://2.bp.blogspot.com/-fWvW5opT0es/VhIdItdKqJI/AAAAAAAAATE/7Ojc0L1SpB0/s1600/Screen%2BShot%2B2015-10-04%2Bat%2B11.47.13%2BPM.png) - included mouse test
-* [gomatrix](https://github.com/gdamore/gomatrix) - converted from Termbox
-* [micro](https://github.com/zyedidia/micro/) - lightweight text editor with syntax-highlighting and themes
-* [godu](https://github.com/viktomas/godu) - simple golang utility helping to discover large files/folders.
-* [tview](https://github.com/rivo/tview) - rich interactive widgets for terminal UIs
-* [tui-go](https://github.com/marcusolsson/tui-go) - UI library for terminal apps
-* [gomandelbrot](https://github.com/rgm3/gomandelbrot) - Mandelbrot!
-* [WTF](https://github.com/senorprogrammer/wtf)- Personal information dashboard for your terminal
-* [browsh](https://github.com/browsh-org/browsh) - A fully-modern text-based browser, rendering to TTY and browsers ([video](https://www.youtube.com/watch?v=HZq86XfBoRo))
-
-## Pure Go Terminfo Database
-
-First, it includes a full parser and expander for terminfo capability strings,
-so that it can avoid hard coding escape strings for formatting. It also favors
-portability, and includes support for all POSIX systems.
-
-The database is also flexible & extensible, and can modified by either running
-a program to build the entire database, or an entry for just a single terminal.
-
-## More Portable
-
-Tcell is portable to a wider variety of systems. Tcell is believed
-to work with all of the systems officially supported by golang with
-the exception of nacl (which lacks any kind of a terminal interface).
-(Plan9 is not supported by Tcell, but it is experimental status only
-in golang.) For all of these systems *except Solaris/illumos*, Tcell
-is pure Go, with no need for CGO.
-
-## No Async IO
-
-Tcell is able to operate without requiring SIGIO signals (unlike Termbox),
-or asynchronous I/O, and can instead use standard Go file
-objects and Go routines. This means it should be safe, especially for
-use with programs that use exec, or otherwise need to manipulate the
-tty streams. This model is also much closer to idiomatic Go, leading
-to fewer surprises.
-
-## Richer Unicode & non-Unicode support
-
-Tcell includes enhanced support for Unicode, including wide characters and
-combining characters, provided your terminal can support them. Note that
-Windows terminals generally don't support the full Unicode repertoire.
-
-It will also convert to and from Unicode locales, so that the program
-can work with UTF-8 internally, and get reasonable output in other locales.
-We try hard to convert to native characters on both input and output, and
-on output Tcell even makes use of the alternate character set to facilitate
-drawing certain characters.
-
-## More Function Keys
-
-It also has richer support for a larger number of special keys that some
-terminals can send.
-
-## Better Color Handling
-
-Tcell will respect your terminal's color space as specified within your terminfo
-entries, so that for example attempts to emit color sequences on VT100 terminals
-won't result in unintended consequences.
-
-In Windows mode, Tcell supports 16 colors, bold, dim, and reverse,
-instead of just termbox's 8 colors with reverse. (Note that there is some
-conflation with bold/dim and colors.)
-
-Tcell maps 16 colors down to 8, for terminals that need it. (The upper
-8 colors are just brighter versions of the lower 8.)
-
-## Better Mouse Support
-
-Tcell supports enhanced mouse tracking mode, so your application can receive
-regular mouse motion events, and wheel events, if your terminal supports it.
-
-## Termbox Compatibility
-
-A compatibility layer for termbox is provided in the compat
-directory. To use it, try importing "github.com/gdamore/tcell/termbox"
-instead. Most termbox-go programs will probably work without further
-modification.
-
-## Working With Unicode
-
-Internally Tcell uses UTF-8, just like Go. However, Tcell understands how to
-convert to and from other character sets, using the capabilities of
-the golang.org/x/text/encoding packages. Your application must supply
-them, as the full set of the most common ones bloats the program by about
-2MB. If you're lazy, and want them all anyway, see the encoding
-sub-directory.
-
-## Wide & Combining Characters
-
-The SetContent() API takes a primary rune, and an optional list of combining
-runes. If any of the runes is a wide (East Asian) rune occupying two cells,
-then the library will skip output from the following cell, but care must be
-taken in the application to avoid explicitly attempting to set content in the
-next cell, otherwise the results are undefined. (Normally wide character
-is displayed, and the other character is not; do not depend on that behavior.)
-
-Experience has shown that the vanilla Windows 8 console application does not
-support any of these characters properly, but at least some options like
-ConEmu do support Wide characters at least.
-
-## Colors
-
-Tcell assumes the ANSI/XTerm color model, including the 256 color map that
-XTerm uses when it supports 256 colors. The terminfo guidance will be
-honored, with respect to the number of colors supported. Also, only
-terminals which expose ANSI style setaf and setab will support color;
-if you have a color terminal that only has setf and setb, please let me
-know; it wouldn't be hard to add that if there is need.
-
-## 24-bit Color
-
-Tcell _supports true color_! (That is, if your terminal can support it,
-Tcell can accurately display 24-bit color.)
-
-To use 24-bit color, you need to use a terminal that supports it. Modern
-xterm and similar teminal emulators can support this. As terminfo lacks any
-way to describe this capability, we fabricate the capability for
-terminals with names ending in *-truecolor. The stock distribution ships
-with a database that defines xterm-truecolor. To try it out, set your
-TERM variable to xterm-truecolor.
-
-When using TrueColor, programs will display the colors that the programmer
-intended, overriding any "themes" you may have set in your terminal
-emulator. (For some cases, accurate color fidelity is more important
-than respecting themes. For other cases, such as typical text apps that
-only use a few colors, its more desirable to respect the themes that
-the user has established.)
-
-If you find this undesirable, you can either use a TERM variable
-that lacks the TRUECOLOR setting, or set TCELL_TRUECOLOR=disable in your
-environment.
-
-## Performance
-
-Reasonable attempts have been made to minimize sending data to terminals,
-avoiding repeated sequences or drawing the same cell on refresh updates.
-
-## Terminfo
-
-(Not relevent for Windows users.)
-
-The Terminfo implementation operates with two forms of database. The first
-is the built-in go database, which contains a number of real database entries
-that are compiled into the program directly. This should minimize calling
-out to database file searches.
-
-The second is in the form of JSON files, that contain the same information,
-which can be located either by the $TCELLDB environment file, $HOME/.tcelldb,
-or is located in the Go source directory as database.json.
-
-These files (both the Go and the JSON files) can be generated using the
-mkinfo.go program. If you need to regnerate the entire set for some reason,
-run the mkdatabase.sh file. The generation uses the infocmp(1) program on
-the system to collect the necessary information.
-
-The mkinfo.go program can also be used to generate specific database entries
-for named terminals, in case your favorite terminal is missing. (If you
-find that this is the case, please let me know and I'll try to add it!)
-
-Tcell requires that the terminal support the 'cup' mode of cursor addressing.
-Terminals without absolute cursor addressability are not supported.
-This is unlikely to be a problem; such terminals have not been mass produced
-since the early 1970s.
-
-## Mouse Support
-
-Mouse support is detected via the "kmous" terminfo variable, however,
-enablement/disablement and decoding mouse events is done using hard coded
-sequences based on the XTerm X11 model. As of this writing all popular
-terminals with mouse tracking support this model. (Full terminfo support
-is not possible as terminfo sequences are not defined.)
-
-On Windows, the mouse works normally.
-
-Mouse wheel buttons on various terminals are known to work, but the support
-in terminal emulators, as well as support for various buttons and
-live mouse tracking, varies widely. As a particular datum, MacOS X Terminal
-does not support Mouse events at all (as of MacOS 10.10, aka Yosemite.) The
-excellent iTerm application is fully supported, as is vanilla XTerm.
-
-Mouse tracking with live tracking also varies widely. Current XTerm
-implementations, as well as current Screen and iTerm2, and Windows
-consoles, all support this quite nicely. On other platforms you might
-find that only mouse click and release events are reported, with
-no intervening motion events. It really depends on your terminal.
-
-## Testablity
-
-There is a SimulationScreen, that can be used to simulate a real screen
-for automated testing. The supplied tests do this. The simulation contains
-event delivery, screen resizing support, and capabilities to inject events
-and examine "physical" screen contents.
-
-## Platforms
-
-### POSIX (Linux, FreeBSD, MacOS, Solaris, etc.)
-
-For mainstream systems with a suitably well defined system call interface
-to tty settings, everything works using pure Go.
-
-For the remainder (right now means only Solaris/illumos) we use POSIX function
-calls to manage termios, which implies that CGO is required on those platforms.
-
-### Windows
-
-Windows console mode applications are supported. Unfortunately mintty
-and other cygwin style applications are not supported.
-
-Modern console applications like ConEmu, as well as the Windows 10
-console itself, support all the good features (resize, mouse tracking, etc.)
-
-I haven't figured out how to cleanly resolve the dichotomy between cygwin
-style termios and the Windows Console API; it seems that perhaps nobody else
-has either. If anyone has suggestions, let me know! Really, if you're
-using a Windows application, you should use the native Windows console or a
-fully compatible console implementation.
-
-### Plan9 and Native Client (Nacl)
-
-The nacl and plan9 platforms won't work, but compilation stubs are supplied
-for folks that want to include parts of this in software targetting those
-platforms. The Simulation screen works, but as Tcell doesn't know how to
-allocate a real screen object on those platforms, NewScreen() will fail.
-
-If anyone has wisdom about how to improve support for either of these,
-please let me know. PRs are especially welcome.
-
-### Commercial Support
-
-This software is absolutely free, but if you want to obtain commercial
-support (giving prioritized access to the developer, etc. on an hourly
-rate), please drop a line to info@staysail.tech
-
-I also welcome donations at Patreon, if you just want to feel good about
-defraying development costs: https://www.patreon.com/gedamore
diff --git a/vendor/github.com/gdamore/tcell/tcell.png b/vendor/github.com/gdamore/tcell/tcell.png
deleted file mode 100644
index 24333c4a..00000000
Binary files a/vendor/github.com/gdamore/tcell/tcell.png and /dev/null differ
diff --git a/vendor/github.com/gdamore/tcell/tcell.svg b/vendor/github.com/gdamore/tcell/tcell.svg
deleted file mode 100644
index d8695d55..00000000
--- a/vendor/github.com/gdamore/tcell/tcell.svg
+++ /dev/null
@@ -1,93 +0,0 @@
-
-
diff --git a/vendor/github.com/godbus/dbus/.travis.yml b/vendor/github.com/godbus/dbus/.travis.yml
index 2e1bbb78..9cd57f43 100644
--- a/vendor/github.com/godbus/dbus/.travis.yml
+++ b/vendor/github.com/godbus/dbus/.travis.yml
@@ -4,8 +4,10 @@ go_import_path: github.com/godbus/dbus
sudo: true
go:
- - 1.6.3
- 1.7.3
+ - 1.8.7
+ - 1.9.5
+ - 1.10.1
- tip
env:
@@ -38,3 +40,7 @@ addons:
- dbus-x11
before_install:
+
+script:
+ - go test -v -race ./... # Run all the tests with the race detector enabled
+ - go vet ./... # go vet is the official Go static analyzer
diff --git a/vendor/github.com/godbus/dbus/README.markdown b/vendor/github.com/godbus/dbus/README.markdown
index d37f4e2e..fd296487 100644
--- a/vendor/github.com/godbus/dbus/README.markdown
+++ b/vendor/github.com/godbus/dbus/README.markdown
@@ -14,7 +14,7 @@ D-Bus message bus system.
### Installation
-This packages requires Go 1.1. If you installed it and set up your GOPATH, just run:
+This packages requires Go 1.7. If you installed it and set up your GOPATH, just run:
```
go get github.com/godbus/dbus
diff --git a/vendor/github.com/godbus/dbus/auth.go b/vendor/github.com/godbus/dbus/auth.go
index 98017b69..b0dcb54e 100644
--- a/vendor/github.com/godbus/dbus/auth.go
+++ b/vendor/github.com/godbus/dbus/auth.go
@@ -116,7 +116,6 @@ func (conn *Conn) Auth(methods []Auth) error {
return err
}
go conn.inWorker()
- go conn.outWorker()
return nil
}
}
diff --git a/vendor/github.com/godbus/dbus/auth_anonymous.go b/vendor/github.com/godbus/dbus/auth_anonymous.go
new file mode 100644
index 00000000..75f3ad34
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/auth_anonymous.go
@@ -0,0 +1,16 @@
+package dbus
+
+// AuthAnonymous returns an Auth that uses the ANONYMOUS mechanism.
+func AuthAnonymous() Auth {
+ return &authAnonymous{}
+}
+
+type authAnonymous struct{}
+
+func (a *authAnonymous) FirstData() (name, resp []byte, status AuthStatus) {
+ return []byte("ANONYMOUS"), nil, AuthOk
+}
+
+func (a *authAnonymous) HandleData(data []byte) (resp []byte, status AuthStatus) {
+ return nil, AuthError
+}
diff --git a/vendor/github.com/godbus/dbus/call.go b/vendor/github.com/godbus/dbus/call.go
index ba6e73f6..2cb18901 100644
--- a/vendor/github.com/godbus/dbus/call.go
+++ b/vendor/github.com/godbus/dbus/call.go
@@ -1,9 +1,12 @@
package dbus
import (
+ "context"
"errors"
)
+var errSignature = errors.New("dbus: mismatched signature")
+
// Call represents a pending or completed method call.
type Call struct {
Destination string
@@ -20,9 +23,25 @@ type Call struct {
// Holds the response once the call is done.
Body []interface{}
+
+ // tracks context and canceler
+ ctx context.Context
+ ctxCanceler context.CancelFunc
}
-var errSignature = errors.New("dbus: mismatched signature")
+func (c *Call) Context() context.Context {
+ if c.ctx == nil {
+ return context.Background()
+ }
+
+ return c.ctx
+}
+
+func (c *Call) ContextCancel() {
+ if c.ctxCanceler != nil {
+ c.ctxCanceler()
+ }
+}
// Store stores the body of the reply into the provided pointers. It returns
// an error if the signatures of the body and retvalues don't match, or if
@@ -34,3 +53,8 @@ func (c *Call) Store(retvalues ...interface{}) error {
return Store(c.Body, retvalues...)
}
+
+func (c *Call) done() {
+ c.Done <- c
+ c.ContextCancel()
+}
diff --git a/vendor/github.com/godbus/dbus/conn.go b/vendor/github.com/godbus/dbus/conn.go
index 5720e2eb..b38920ba 100644
--- a/vendor/github.com/godbus/dbus/conn.go
+++ b/vendor/github.com/godbus/dbus/conn.go
@@ -1,6 +1,7 @@
package dbus
import (
+ "context"
"errors"
"io"
"os"
@@ -14,7 +15,6 @@ var (
systemBusLck sync.Mutex
sessionBus *Conn
sessionBusLck sync.Mutex
- sessionEnvLck sync.Mutex
)
// ErrClosed is the error returned by calls on a closed connection.
@@ -35,23 +35,13 @@ type Conn struct {
unixFD bool
uuid string
- names []string
- namesLck sync.RWMutex
-
- serialLck sync.Mutex
- nextSerial uint32
- serialUsed map[uint32]bool
-
- calls map[uint32]*Call
- callsLck sync.RWMutex
-
- handler Handler
-
- out chan *Message
- closed bool
- outLck sync.RWMutex
-
+ handler Handler
signalHandler SignalHandler
+ serialGen SerialGenerator
+
+ names *nameTracker
+ calls *callTracker
+ outHandler *outputHandler
eavesdropped chan<- *Message
eavesdroppedLck sync.Mutex
@@ -87,32 +77,31 @@ func SessionBus() (conn *Conn, err error) {
}
func getSessionBusAddress() (string, error) {
- sessionEnvLck.Lock()
- defer sessionEnvLck.Unlock()
- address := os.Getenv("DBUS_SESSION_BUS_ADDRESS")
- if address != "" && address != "autolaunch:" {
+ if address := os.Getenv("DBUS_SESSION_BUS_ADDRESS"); address != "" && address != "autolaunch:" {
+ return address, nil
+
+ } else if address := tryDiscoverDbusSessionBusAddress(); address != "" {
+ os.Setenv("DBUS_SESSION_BUS_ADDRESS", address)
return address, nil
}
return getSessionBusPlatformAddress()
}
// SessionBusPrivate returns a new private connection to the session bus.
-func SessionBusPrivate() (*Conn, error) {
+func SessionBusPrivate(opts ...ConnOption) (*Conn, error) {
address, err := getSessionBusAddress()
if err != nil {
return nil, err
}
- return Dial(address)
+ return Dial(address, opts...)
}
// SessionBusPrivate returns a new private connection to the session bus.
+//
+// Deprecated: use SessionBusPrivate with options instead.
func SessionBusPrivateHandler(handler Handler, signalHandler SignalHandler) (*Conn, error) {
- address, err := getSessionBusAddress()
- if err != nil {
- return nil, err
- }
- return DialHandler(address, handler, signalHandler)
+ return SessionBusPrivate(WithHandler(handler), WithSignalHandler(signalHandler))
}
// SystemBus returns a shared connection to the system bus, connecting to it if
@@ -145,53 +134,93 @@ func SystemBus() (conn *Conn, err error) {
}
// SystemBusPrivate returns a new private connection to the system bus.
-func SystemBusPrivate() (*Conn, error) {
- return Dial(getSystemBusPlatformAddress())
+func SystemBusPrivate(opts ...ConnOption) (*Conn, error) {
+ return Dial(getSystemBusPlatformAddress(), opts...)
}
// SystemBusPrivateHandler returns a new private connection to the system bus, using the provided handlers.
+//
+// Deprecated: use SystemBusPrivate with options instead.
func SystemBusPrivateHandler(handler Handler, signalHandler SignalHandler) (*Conn, error) {
- return DialHandler(getSystemBusPlatformAddress(), handler, signalHandler)
+ return SystemBusPrivate(WithHandler(handler), WithSignalHandler(signalHandler))
}
// Dial establishes a new private connection to the message bus specified by address.
-func Dial(address string) (*Conn, error) {
+func Dial(address string, opts ...ConnOption) (*Conn, error) {
tr, err := getTransport(address)
if err != nil {
return nil, err
}
- return newConn(tr, NewDefaultHandler(), NewDefaultSignalHandler())
+ return newConn(tr, opts...)
}
// DialHandler establishes a new private connection to the message bus specified by address, using the supplied handlers.
+//
+// Deprecated: use Dial with options instead.
func DialHandler(address string, handler Handler, signalHandler SignalHandler) (*Conn, error) {
- tr, err := getTransport(address)
- if err != nil {
- return nil, err
+ return Dial(address, WithSignalHandler(signalHandler))
+}
+
+// ConnOption is a connection option.
+type ConnOption func(conn *Conn) error
+
+// WithHandler overrides the default handler.
+func WithHandler(handler Handler) ConnOption {
+ return func(conn *Conn) error {
+ conn.handler = handler
+ return nil
+ }
+}
+
+// WithSignalHandler overrides the default signal handler.
+func WithSignalHandler(handler SignalHandler) ConnOption {
+ return func(conn *Conn) error {
+ conn.signalHandler = handler
+ return nil
+ }
+}
+
+// WithSerialGenerator overrides the default signals generator.
+func WithSerialGenerator(gen SerialGenerator) ConnOption {
+ return func(conn *Conn) error {
+ conn.serialGen = gen
+ return nil
}
- return newConn(tr, handler, signalHandler)
}
// NewConn creates a new private *Conn from an already established connection.
-func NewConn(conn io.ReadWriteCloser) (*Conn, error) {
- return NewConnHandler(conn, NewDefaultHandler(), NewDefaultSignalHandler())
+func NewConn(conn io.ReadWriteCloser, opts ...ConnOption) (*Conn, error) {
+ return newConn(genericTransport{conn}, opts...)
}
// NewConnHandler creates a new private *Conn from an already established connection, using the supplied handlers.
+//
+// Deprecated: use NewConn with options instead.
func NewConnHandler(conn io.ReadWriteCloser, handler Handler, signalHandler SignalHandler) (*Conn, error) {
- return newConn(genericTransport{conn}, handler, signalHandler)
+ return NewConn(genericTransport{conn}, WithHandler(handler), WithSignalHandler(signalHandler))
}
// newConn creates a new *Conn from a transport.
-func newConn(tr transport, handler Handler, signalHandler SignalHandler) (*Conn, error) {
+func newConn(tr transport, opts ...ConnOption) (*Conn, error) {
conn := new(Conn)
conn.transport = tr
- conn.calls = make(map[uint32]*Call)
- conn.out = make(chan *Message, 10)
- conn.handler = handler
- conn.signalHandler = signalHandler
- conn.nextSerial = 1
- conn.serialUsed = map[uint32]bool{0: true}
+ for _, opt := range opts {
+ if err := opt(conn); err != nil {
+ return nil, err
+ }
+ }
+ conn.calls = newCallTracker()
+ if conn.handler == nil {
+ conn.handler = NewDefaultHandler()
+ }
+ if conn.signalHandler == nil {
+ conn.signalHandler = NewDefaultSignalHandler()
+ }
+ if conn.serialGen == nil {
+ conn.serialGen = newSerialGenerator()
+ }
+ conn.outHandler = &outputHandler{conn: conn}
+ conn.names = newNameTracker()
conn.busObj = conn.Object("org.freedesktop.DBus", "/org/freedesktop/DBus")
return conn, nil
}
@@ -206,18 +235,7 @@ func (conn *Conn) BusObject() BusObject {
// and the channels passed to Eavesdrop and Signal are closed. This method must
// not be called on shared connections.
func (conn *Conn) Close() error {
- conn.outLck.Lock()
- if conn.closed {
- // inWorker calls Close on read error, the read error may
- // be caused by another caller calling Close to shutdown the
- // dbus connection, a double-close scenario we prevent here.
- conn.outLck.Unlock()
- return nil
- }
- close(conn.out)
- conn.closed = true
- conn.outLck.Unlock()
-
+ conn.outHandler.close()
if term, ok := conn.signalHandler.(Terminator); ok {
term.Terminate()
}
@@ -249,17 +267,9 @@ func (conn *Conn) Eavesdrop(ch chan<- *Message) {
conn.eavesdroppedLck.Unlock()
}
-// getSerial returns an unused serial.
+// GetSerial returns an unused serial.
func (conn *Conn) getSerial() uint32 {
- conn.serialLck.Lock()
- defer conn.serialLck.Unlock()
- n := conn.nextSerial
- for conn.serialUsed[n] {
- n++
- }
- conn.serialUsed[n] = true
- conn.nextSerial = n + 1
- return n
+ return conn.serialGen.GetSerial()
}
// Hello sends the initial org.freedesktop.DBus.Hello call. This method must be
@@ -271,10 +281,7 @@ func (conn *Conn) Hello() error {
if err != nil {
return err
}
- conn.namesLck.Lock()
- conn.names = make([]string, 1)
- conn.names[0] = s
- conn.namesLck.Unlock()
+ conn.names.acquireUniqueConnectionName(s)
return nil
}
@@ -283,109 +290,48 @@ func (conn *Conn) Hello() error {
func (conn *Conn) inWorker() {
for {
msg, err := conn.ReadMessage()
- if err == nil {
- conn.eavesdroppedLck.Lock()
- if conn.eavesdropped != nil {
- select {
- case conn.eavesdropped <- msg:
- default:
- }
- conn.eavesdroppedLck.Unlock()
- continue
+ if err != nil {
+ if _, ok := err.(InvalidMessageError); !ok {
+ // Some read error occured (usually EOF); we can't really do
+ // anything but to shut down all stuff and returns errors to all
+ // pending replies.
+ conn.Close()
+ conn.calls.finalizeAllWithError(err)
+ return
+ }
+ // invalid messages are ignored
+ continue
+ }
+ conn.eavesdroppedLck.Lock()
+ if conn.eavesdropped != nil {
+ select {
+ case conn.eavesdropped <- msg:
+ default:
}
conn.eavesdroppedLck.Unlock()
- dest, _ := msg.Headers[FieldDestination].value.(string)
- found := false
- if dest == "" {
- found = true
- } else {
- conn.namesLck.RLock()
- if len(conn.names) == 0 {
- found = true
- }
- for _, v := range conn.names {
- if dest == v {
- found = true
- break
- }
- }
- conn.namesLck.RUnlock()
- }
- if !found {
- // Eavesdropped a message, but no channel for it is registered.
- // Ignore it.
- continue
- }
- switch msg.Type {
- case TypeMethodReply, TypeError:
- serial := msg.Headers[FieldReplySerial].value.(uint32)
- conn.callsLck.Lock()
- if c, ok := conn.calls[serial]; ok {
- if msg.Type == TypeError {
- name, _ := msg.Headers[FieldErrorName].value.(string)
- c.Err = Error{name, msg.Body}
- } else {
- c.Body = msg.Body
- }
- c.Done <- c
- conn.serialLck.Lock()
- delete(conn.serialUsed, serial)
- conn.serialLck.Unlock()
- delete(conn.calls, serial)
- }
- conn.callsLck.Unlock()
- case TypeSignal:
- iface := msg.Headers[FieldInterface].value.(string)
- member := msg.Headers[FieldMember].value.(string)
- // as per http://dbus.freedesktop.org/doc/dbus-specification.html ,
- // sender is optional for signals.
- sender, _ := msg.Headers[FieldSender].value.(string)
- if iface == "org.freedesktop.DBus" && sender == "org.freedesktop.DBus" {
- if member == "NameLost" {
- // If we lost the name on the bus, remove it from our
- // tracking list.
- name, ok := msg.Body[0].(string)
- if !ok {
- panic("Unable to read the lost name")
- }
- conn.namesLck.Lock()
- for i, v := range conn.names {
- if v == name {
- conn.names = append(conn.names[:i],
- conn.names[i+1:]...)
- }
- }
- conn.namesLck.Unlock()
- } else if member == "NameAcquired" {
- // If we acquired the name on the bus, add it to our
- // tracking list.
- name, ok := msg.Body[0].(string)
- if !ok {
- panic("Unable to read the acquired name")
- }
- conn.namesLck.Lock()
- conn.names = append(conn.names, name)
- conn.namesLck.Unlock()
- }
- }
- conn.handleSignal(msg)
- case TypeMethodCall:
- go conn.handleCall(msg)
- }
- } else if _, ok := err.(InvalidMessageError); !ok {
- // Some read error occured (usually EOF); we can't really do
- // anything but to shut down all stuff and returns errors to all
- // pending replies.
- conn.Close()
- conn.callsLck.RLock()
- for _, v := range conn.calls {
- v.Err = err
- v.Done <- v
- }
- conn.callsLck.RUnlock()
- return
+ continue
}
- // invalid messages are ignored
+ conn.eavesdroppedLck.Unlock()
+ dest, _ := msg.Headers[FieldDestination].value.(string)
+ found := dest == "" ||
+ !conn.names.uniqueNameIsKnown() ||
+ conn.names.isKnownName(dest)
+ if !found {
+ // Eavesdropped a message, but no channel for it is registered.
+ // Ignore it.
+ continue
+ }
+ switch msg.Type {
+ case TypeError:
+ conn.serialGen.RetireSerial(conn.calls.handleDBusError(msg))
+ case TypeMethodReply:
+ conn.serialGen.RetireSerial(conn.calls.handleReply(msg))
+ case TypeSignal:
+ conn.handleSignal(msg)
+ case TypeMethodCall:
+ go conn.handleCall(msg)
+ }
+
}
}
@@ -395,6 +341,25 @@ func (conn *Conn) handleSignal(msg *Message) {
// as per http://dbus.freedesktop.org/doc/dbus-specification.html ,
// sender is optional for signals.
sender, _ := msg.Headers[FieldSender].value.(string)
+ if iface == "org.freedesktop.DBus" && sender == "org.freedesktop.DBus" {
+ if member == "NameLost" {
+ // If we lost the name on the bus, remove it from our
+ // tracking list.
+ name, ok := msg.Body[0].(string)
+ if !ok {
+ panic("Unable to read the lost name")
+ }
+ conn.names.loseName(name)
+ } else if member == "NameAcquired" {
+ // If we acquired the name on the bus, add it to our
+ // tracking list.
+ name, ok := msg.Body[0].(string)
+ if !ok {
+ panic("Unable to read the acquired name")
+ }
+ conn.names.acquireName(name)
+ }
+ }
signal := &Signal{
Sender: sender,
Path: msg.Headers[FieldPath].value.(ObjectPath),
@@ -408,12 +373,7 @@ func (conn *Conn) handleSignal(msg *Message) {
// connection. The slice is always at least one element long, the first element
// being the unique name of the connection.
func (conn *Conn) Names() []string {
- conn.namesLck.RLock()
- // copy the slice so it can't be modified
- s := make([]string, len(conn.names))
- copy(s, conn.names)
- conn.namesLck.RUnlock()
- return s
+ return conn.names.listKnownNames()
}
// Object returns the object identified by the given destination name and path.
@@ -423,24 +383,17 @@ func (conn *Conn) Object(dest string, path ObjectPath) BusObject {
// outWorker runs in an own goroutine, encoding and sending messages that are
// sent to conn.out.
-func (conn *Conn) outWorker() {
- for msg := range conn.out {
- err := conn.SendMessage(msg)
- conn.callsLck.RLock()
- if err != nil {
- if c := conn.calls[msg.serial]; c != nil {
- c.Err = err
- c.Done <- c
- }
- conn.serialLck.Lock()
- delete(conn.serialUsed, msg.serial)
- conn.serialLck.Unlock()
- } else if msg.Type != TypeMethodCall {
- conn.serialLck.Lock()
- delete(conn.serialUsed, msg.serial)
- conn.serialLck.Unlock()
- }
- conn.callsLck.RUnlock()
+func (conn *Conn) sendMessage(msg *Message) {
+ conn.sendMessageAndIfClosed(msg, func() {})
+}
+
+func (conn *Conn) sendMessageAndIfClosed(msg *Message, ifClosed func()) {
+ err := conn.outHandler.sendAndIfClosed(msg, ifClosed)
+ conn.calls.handleSendError(msg, err)
+ if err != nil {
+ conn.serialGen.RetireSerial(msg.serial)
+ } else if msg.Type != TypeMethodCall {
+ conn.serialGen.RetireSerial(msg.serial)
}
}
@@ -451,8 +404,21 @@ func (conn *Conn) outWorker() {
// once the call is complete. Otherwise, ch is ignored and a Call structure is
// returned of which only the Err member is valid.
func (conn *Conn) Send(msg *Message, ch chan *Call) *Call {
- var call *Call
+ return conn.send(context.Background(), msg, ch)
+}
+// SendWithContext acts like Send but takes a context
+func (conn *Conn) SendWithContext(ctx context.Context, msg *Message, ch chan *Call) *Call {
+ return conn.send(ctx, msg, ch)
+}
+
+func (conn *Conn) send(ctx context.Context, msg *Message, ch chan *Call) *Call {
+ if ctx == nil {
+ panic("nil context")
+ }
+
+ var call *Call
+ ctx, canceler := context.WithCancel(ctx)
msg.serial = conn.getSerial()
if msg.Type == TypeMethodCall && msg.Flags&FlagNoReplyExpected == 0 {
if ch == nil {
@@ -468,26 +434,23 @@ func (conn *Conn) Send(msg *Message, ch chan *Call) *Call {
call.Method = iface + "." + member
call.Args = msg.Body
call.Done = ch
- conn.callsLck.Lock()
- conn.calls[msg.serial] = call
- conn.callsLck.Unlock()
- conn.outLck.RLock()
- if conn.closed {
- call.Err = ErrClosed
- call.Done <- call
- } else {
- conn.out <- msg
- }
- conn.outLck.RUnlock()
+ call.ctx = ctx
+ call.ctxCanceler = canceler
+ conn.calls.track(msg.serial, call)
+ go func() {
+ <-ctx.Done()
+ conn.calls.handleSendError(msg, ctx.Err())
+ }()
+ conn.sendMessageAndIfClosed(msg, func() {
+ conn.calls.handleSendError(msg, ErrClosed)
+ canceler()
+ })
} else {
- conn.outLck.RLock()
- if conn.closed {
+ canceler()
+ call = &Call{Err: nil}
+ conn.sendMessageAndIfClosed(msg, func() {
call = &Call{Err: ErrClosed}
- } else {
- conn.out <- msg
- call = &Call{Err: nil}
- }
- conn.outLck.RUnlock()
+ })
}
return call
}
@@ -520,11 +483,7 @@ func (conn *Conn) sendError(err error, dest string, serial uint32) {
if len(e.Body) > 0 {
msg.Headers[FieldSignature] = MakeVariant(SignatureOf(e.Body...))
}
- conn.outLck.RLock()
- if !conn.closed {
- conn.out <- msg
- }
- conn.outLck.RUnlock()
+ conn.sendMessage(msg)
}
// sendReply creates a method reply message corresponding to the parameters and
@@ -542,11 +501,7 @@ func (conn *Conn) sendReply(dest string, serial uint32, values ...interface{}) {
if len(values) > 0 {
msg.Headers[FieldSignature] = MakeVariant(SignatureOf(values...))
}
- conn.outLck.RLock()
- if !conn.closed {
- conn.out <- msg
- }
- conn.outLck.RUnlock()
+ conn.sendMessage(msg)
}
func (conn *Conn) defaultSignalAction(fn func(h *defaultSignalHandler, ch chan<- *Signal), ch chan<- *Signal) {
@@ -681,3 +636,212 @@ func getKey(s, key string) string {
}
return ""
}
+
+type outputHandler struct {
+ conn *Conn
+ sendLck sync.Mutex
+ closed struct {
+ isClosed bool
+ lck sync.RWMutex
+ }
+}
+
+func (h *outputHandler) sendAndIfClosed(msg *Message, ifClosed func()) error {
+ h.closed.lck.RLock()
+ defer h.closed.lck.RUnlock()
+ if h.closed.isClosed {
+ ifClosed()
+ return nil
+ }
+ h.sendLck.Lock()
+ defer h.sendLck.Unlock()
+ return h.conn.SendMessage(msg)
+}
+
+func (h *outputHandler) close() {
+ h.closed.lck.Lock()
+ defer h.closed.lck.Unlock()
+ h.closed.isClosed = true
+}
+
+type serialGenerator struct {
+ lck sync.Mutex
+ nextSerial uint32
+ serialUsed map[uint32]bool
+}
+
+func newSerialGenerator() *serialGenerator {
+ return &serialGenerator{
+ serialUsed: map[uint32]bool{0: true},
+ nextSerial: 1,
+ }
+}
+
+func (gen *serialGenerator) GetSerial() uint32 {
+ gen.lck.Lock()
+ defer gen.lck.Unlock()
+ n := gen.nextSerial
+ for gen.serialUsed[n] {
+ n++
+ }
+ gen.serialUsed[n] = true
+ gen.nextSerial = n + 1
+ return n
+}
+
+func (gen *serialGenerator) RetireSerial(serial uint32) {
+ gen.lck.Lock()
+ defer gen.lck.Unlock()
+ delete(gen.serialUsed, serial)
+}
+
+type nameTracker struct {
+ lck sync.RWMutex
+ unique string
+ names map[string]struct{}
+}
+
+func newNameTracker() *nameTracker {
+ return &nameTracker{names: map[string]struct{}{}}
+}
+func (tracker *nameTracker) acquireUniqueConnectionName(name string) {
+ tracker.lck.Lock()
+ defer tracker.lck.Unlock()
+ tracker.unique = name
+}
+func (tracker *nameTracker) acquireName(name string) {
+ tracker.lck.Lock()
+ defer tracker.lck.Unlock()
+ tracker.names[name] = struct{}{}
+}
+func (tracker *nameTracker) loseName(name string) {
+ tracker.lck.Lock()
+ defer tracker.lck.Unlock()
+ delete(tracker.names, name)
+}
+
+func (tracker *nameTracker) uniqueNameIsKnown() bool {
+ tracker.lck.RLock()
+ defer tracker.lck.RUnlock()
+ return tracker.unique != ""
+}
+func (tracker *nameTracker) isKnownName(name string) bool {
+ tracker.lck.RLock()
+ defer tracker.lck.RUnlock()
+ _, ok := tracker.names[name]
+ return ok || name == tracker.unique
+}
+func (tracker *nameTracker) listKnownNames() []string {
+ tracker.lck.RLock()
+ defer tracker.lck.RUnlock()
+ out := make([]string, 0, len(tracker.names)+1)
+ out = append(out, tracker.unique)
+ for k := range tracker.names {
+ out = append(out, k)
+ }
+ return out
+}
+
+type callTracker struct {
+ calls map[uint32]*Call
+ lck sync.RWMutex
+}
+
+func newCallTracker() *callTracker {
+ return &callTracker{calls: map[uint32]*Call{}}
+}
+
+func (tracker *callTracker) track(sn uint32, call *Call) {
+ tracker.lck.Lock()
+ tracker.calls[sn] = call
+ tracker.lck.Unlock()
+}
+
+func (tracker *callTracker) handleReply(msg *Message) uint32 {
+ serial := msg.Headers[FieldReplySerial].value.(uint32)
+ tracker.lck.RLock()
+ _, ok := tracker.calls[serial]
+ tracker.lck.RUnlock()
+ if ok {
+ tracker.finalizeWithBody(serial, msg.Body)
+ }
+ return serial
+}
+
+func (tracker *callTracker) handleDBusError(msg *Message) uint32 {
+ serial := msg.Headers[FieldReplySerial].value.(uint32)
+ tracker.lck.RLock()
+ _, ok := tracker.calls[serial]
+ tracker.lck.RUnlock()
+ if ok {
+ name, _ := msg.Headers[FieldErrorName].value.(string)
+ tracker.finalizeWithError(serial, Error{name, msg.Body})
+ }
+ return serial
+}
+
+func (tracker *callTracker) handleSendError(msg *Message, err error) {
+ if err == nil {
+ return
+ }
+ tracker.lck.RLock()
+ _, ok := tracker.calls[msg.serial]
+ tracker.lck.RUnlock()
+ if ok {
+ tracker.finalizeWithError(msg.serial, err)
+ }
+}
+
+// finalize was the only func that did not strobe Done
+func (tracker *callTracker) finalize(sn uint32) {
+ tracker.lck.Lock()
+ defer tracker.lck.Unlock()
+ c, ok := tracker.calls[sn]
+ if ok {
+ delete(tracker.calls, sn)
+ c.ContextCancel()
+ }
+ return
+}
+
+func (tracker *callTracker) finalizeWithBody(sn uint32, body []interface{}) {
+ tracker.lck.Lock()
+ c, ok := tracker.calls[sn]
+ if ok {
+ delete(tracker.calls, sn)
+ }
+ tracker.lck.Unlock()
+ if ok {
+ c.Body = body
+ c.done()
+ }
+ return
+}
+
+func (tracker *callTracker) finalizeWithError(sn uint32, err error) {
+ tracker.lck.Lock()
+ c, ok := tracker.calls[sn]
+ if ok {
+ delete(tracker.calls, sn)
+ }
+ tracker.lck.Unlock()
+ if ok {
+ c.Err = err
+ c.done()
+ }
+ return
+}
+
+func (tracker *callTracker) finalizeAllWithError(err error) {
+ tracker.lck.Lock()
+ closedCalls := make([]*Call, 0, len(tracker.calls))
+ for sn := range tracker.calls {
+ closedCalls = append(closedCalls, tracker.calls[sn])
+ }
+ tracker.calls = map[uint32]*Call{}
+ tracker.lck.Unlock()
+ for _, call := range closedCalls {
+ call.Err = err
+ call.done()
+ }
+}
diff --git a/vendor/github.com/godbus/dbus/conn_other.go b/vendor/github.com/godbus/dbus/conn_other.go
index 254c9f2e..289044a4 100644
--- a/vendor/github.com/godbus/dbus/conn_other.go
+++ b/vendor/github.com/godbus/dbus/conn_other.go
@@ -6,12 +6,14 @@ import (
"bytes"
"errors"
"fmt"
+ "io/ioutil"
"os"
"os/exec"
+ "os/user"
+ "path"
+ "strings"
)
-const defaultSystemBusAddress = "unix:path=/var/run/dbus/system_bus_socket"
-
func getSessionBusPlatformAddress() (string, error) {
cmd := exec.Command("dbus-launch")
b, err := cmd.CombinedOutput()
@@ -33,10 +35,57 @@ func getSessionBusPlatformAddress() (string, error) {
return addr, nil
}
-func getSystemBusPlatformAddress() string {
- address := os.Getenv("DBUS_SYSTEM_BUS_ADDRESS")
- if address != "" {
- return fmt.Sprintf("unix:path=%s", address)
+// tryDiscoverDbusSessionBusAddress tries to discover an existing dbus session
+// and return the value of its DBUS_SESSION_BUS_ADDRESS.
+// It tries different techniques employed by different operating systems,
+// returning the first valid address it finds, or an empty string.
+//
+// * /run/user//bus if this exists, it *is* the bus socket. present on
+// Ubuntu 18.04
+// * /run/user//dbus-session: if this exists, it can be parsed for the bus
+// address. present on Ubuntu 16.04
+//
+// See https://dbus.freedesktop.org/doc/dbus-launch.1.html
+func tryDiscoverDbusSessionBusAddress() string {
+ if runtimeDirectory, err := getRuntimeDirectory(); err == nil {
+
+ if runUserBusFile := path.Join(runtimeDirectory, "bus"); fileExists(runUserBusFile) {
+ // if /run/user//bus exists, that file itself
+ // *is* the unix socket, so return its path
+ return fmt.Sprintf("unix:path=%s", runUserBusFile)
+ }
+ if runUserSessionDbusFile := path.Join(runtimeDirectory, "dbus-session"); fileExists(runUserSessionDbusFile) {
+ // if /run/user//dbus-session exists, it's a
+ // text file // containing the address of the socket, e.g.:
+ // DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-E1c73yNqrG
+
+ if f, err := ioutil.ReadFile(runUserSessionDbusFile); err == nil {
+ fileContent := string(f)
+
+ prefix := "DBUS_SESSION_BUS_ADDRESS="
+
+ if strings.HasPrefix(fileContent, prefix) {
+ address := strings.TrimRight(strings.TrimPrefix(fileContent, prefix), "\n\r")
+ return address
+ }
+ }
+ }
+ }
+ return ""
+}
+
+func getRuntimeDirectory() (string, error) {
+ if currentUser, err := user.Current(); err != nil {
+ return "", err
+ } else {
+ return fmt.Sprintf("/run/user/%s", currentUser.Uid), nil
+ }
+}
+
+func fileExists(filename string) bool {
+ if _, err := os.Stat(filename); !os.IsNotExist(err) {
+ return true
+ } else {
+ return false
}
- return defaultSystemBusAddress
}
diff --git a/vendor/github.com/godbus/dbus/conn_unix.go b/vendor/github.com/godbus/dbus/conn_unix.go
new file mode 100644
index 00000000..4cba8ae8
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/conn_unix.go
@@ -0,0 +1,18 @@
+//+build !windows,!solaris,!darwin
+
+package dbus
+
+import (
+ "os"
+ "fmt"
+)
+
+const defaultSystemBusAddress = "unix:path=/var/run/dbus/system_bus_socket"
+
+func getSystemBusPlatformAddress() string {
+ address := os.Getenv("DBUS_SYSTEM_BUS_ADDRESS")
+ if address != "" {
+ return fmt.Sprintf("unix:path=%s", address)
+ }
+ return defaultSystemBusAddress
+}
\ No newline at end of file
diff --git a/vendor/github.com/godbus/dbus/conn_windows.go b/vendor/github.com/godbus/dbus/conn_windows.go
new file mode 100644
index 00000000..4291e451
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/conn_windows.go
@@ -0,0 +1,15 @@
+//+build windows
+
+package dbus
+
+import "os"
+
+const defaultSystemBusAddress = "tcp:host=127.0.0.1,port=12434"
+
+func getSystemBusPlatformAddress() string {
+ address := os.Getenv("DBUS_SYSTEM_BUS_ADDRESS")
+ if address != "" {
+ return address
+ }
+ return defaultSystemBusAddress
+}
diff --git a/vendor/github.com/godbus/dbus/decoder.go b/vendor/github.com/godbus/dbus/decoder.go
index ef50dcab..5c27d3b5 100644
--- a/vendor/github.com/godbus/dbus/decoder.go
+++ b/vendor/github.com/godbus/dbus/decoder.go
@@ -191,7 +191,14 @@ func (dec *decoder) decode(s string, depth int) interface{} {
length := dec.decode("u", depth).(uint32)
v := reflect.MakeSlice(reflect.SliceOf(typeFor(s[1:])), 0, int(length))
// Even for empty arrays, the correct padding must be included
- dec.align(alignment(typeFor(s[1:])))
+ align := alignment(typeFor(s[1:]))
+ if len(s) > 1 && s[1] == '(' {
+ //Special case for arrays of structs
+ //structs decode as a slice of interface{} values
+ //but the dbus alignment does not match this
+ align = 8
+ }
+ dec.align(align)
spos := dec.pos
for dec.pos < spos+int(length) {
ev := dec.decode(s[1:], depth+1)
diff --git a/vendor/github.com/godbus/dbus/default_handler.go b/vendor/github.com/godbus/dbus/default_handler.go
index e81f73ac..81dbcc7e 100644
--- a/vendor/github.com/godbus/dbus/default_handler.go
+++ b/vendor/github.com/godbus/dbus/default_handler.go
@@ -21,6 +21,8 @@ func newIntrospectIntf(h *defaultHandler) *exportedIntf {
//NewDefaultHandler returns an instance of the default
//call handler. This is useful if you want to implement only
//one of the two handlers but not both.
+//
+// Deprecated: this is the default value, don't use it, it will be unexported.
func NewDefaultHandler() *defaultHandler {
h := &defaultHandler{
objects: make(map[ObjectPath]*exportedObj),
@@ -161,6 +163,7 @@ func newExportedObject() *exportedObj {
}
type exportedObj struct {
+ mu sync.RWMutex
interfaces map[string]*exportedIntf
}
@@ -168,19 +171,27 @@ func (obj *exportedObj) LookupInterface(name string) (Interface, bool) {
if name == "" {
return obj, true
}
+ obj.mu.RLock()
+ defer obj.mu.RUnlock()
intf, exists := obj.interfaces[name]
return intf, exists
}
func (obj *exportedObj) AddInterface(name string, iface *exportedIntf) {
+ obj.mu.Lock()
+ defer obj.mu.Unlock()
obj.interfaces[name] = iface
}
func (obj *exportedObj) DeleteInterface(name string) {
+ obj.mu.Lock()
+ defer obj.mu.Unlock()
delete(obj.interfaces, name)
}
func (obj *exportedObj) LookupMethod(name string) (Method, bool) {
+ obj.mu.RLock()
+ defer obj.mu.RUnlock()
for _, intf := range obj.interfaces {
method, exists := intf.LookupMethod(name)
if exists {
@@ -220,8 +231,12 @@ func (obj *exportedIntf) isFallbackInterface() bool {
//NewDefaultSignalHandler returns an instance of the default
//signal handler. This is useful if you want to implement only
//one of the two handlers but not both.
+//
+// Deprecated: this is the default value, don't use it, it will be unexported.
func NewDefaultSignalHandler() *defaultSignalHandler {
- return &defaultSignalHandler{}
+ return &defaultSignalHandler{
+ closeChan: make(chan struct{}),
+ }
}
func isDefaultSignalHandler(handler SignalHandler) bool {
@@ -231,32 +246,47 @@ func isDefaultSignalHandler(handler SignalHandler) bool {
type defaultSignalHandler struct {
sync.RWMutex
- closed bool
- signals []chan<- *Signal
+ closed bool
+ signals []chan<- *Signal
+ closeChan chan struct{}
}
func (sh *defaultSignalHandler) DeliverSignal(intf, name string, signal *Signal) {
- go func() {
- sh.RLock()
- defer sh.RUnlock()
- if sh.closed {
+ sh.RLock()
+ defer sh.RUnlock()
+ if sh.closed {
+ return
+ }
+ for _, ch := range sh.signals {
+ select {
+ case ch <- signal:
+ case <-sh.closeChan:
return
+ default:
+ go func() {
+ select {
+ case ch <- signal:
+ case <-sh.closeChan:
+ return
+ }
+ }()
}
- for _, ch := range sh.signals {
- ch <- signal
- }
- }()
+ }
}
func (sh *defaultSignalHandler) Init() error {
sh.Lock()
sh.signals = make([]chan<- *Signal, 0)
+ sh.closeChan = make(chan struct{})
sh.Unlock()
return nil
}
func (sh *defaultSignalHandler) Terminate() {
sh.Lock()
+ if !sh.closed {
+ close(sh.closeChan)
+ }
sh.closed = true
for _, ch := range sh.signals {
close(ch)
diff --git a/vendor/github.com/godbus/dbus/export.go b/vendor/github.com/godbus/dbus/export.go
index aae97088..95d0e295 100644
--- a/vendor/github.com/godbus/dbus/export.go
+++ b/vendor/github.com/godbus/dbus/export.go
@@ -170,11 +170,8 @@ func (conn *Conn) handleCall(msg *Message) {
reply.Body[i] = ret[i]
}
reply.Headers[FieldSignature] = MakeVariant(SignatureOf(reply.Body...))
- conn.outLck.RLock()
- if !conn.closed {
- conn.out <- reply
- }
- conn.outLck.RUnlock()
+
+ conn.sendMessage(reply)
}
}
@@ -207,12 +204,14 @@ func (conn *Conn) Emit(path ObjectPath, name string, values ...interface{}) erro
if len(values) > 0 {
msg.Headers[FieldSignature] = MakeVariant(SignatureOf(values...))
}
- conn.outLck.RLock()
- defer conn.outLck.RUnlock()
- if conn.closed {
+
+ var closed bool
+ conn.sendMessageAndIfClosed(msg, func() {
+ closed = true
+ })
+ if closed {
return ErrClosed
}
- conn.out <- msg
return nil
}
diff --git a/vendor/github.com/godbus/dbus/go.mod b/vendor/github.com/godbus/dbus/go.mod
new file mode 100644
index 00000000..bdcd1259
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/go.mod
@@ -0,0 +1 @@
+module github.com/godbus/dbus
diff --git a/vendor/github.com/godbus/dbus/object.go b/vendor/github.com/godbus/dbus/object.go
index 6d95583d..f27ffe14 100644
--- a/vendor/github.com/godbus/dbus/object.go
+++ b/vendor/github.com/godbus/dbus/object.go
@@ -1,6 +1,7 @@
package dbus
import (
+ "context"
"errors"
"strings"
)
@@ -9,7 +10,11 @@ import (
// invoked.
type BusObject interface {
Call(method string, flags Flags, args ...interface{}) *Call
+ CallWithContext(ctx context.Context, method string, flags Flags, args ...interface{}) *Call
Go(method string, flags Flags, ch chan *Call, args ...interface{}) *Call
+ GoWithContext(ctx context.Context, method string, flags Flags, ch chan *Call, args ...interface{}) *Call
+ AddMatchSignal(iface, member string, options ...MatchOption) *Call
+ RemoveMatchSignal(iface, member string, options ...MatchOption) *Call
GetProperty(p string) (Variant, error)
Destination() string
Path() ObjectPath
@@ -24,16 +29,73 @@ type Object struct {
// Call calls a method with (*Object).Go and waits for its reply.
func (o *Object) Call(method string, flags Flags, args ...interface{}) *Call {
- return <-o.Go(method, flags, make(chan *Call, 1), args...).Done
+ return <-o.createCall(context.Background(), method, flags, make(chan *Call, 1), args...).Done
}
-// AddMatchSignal subscribes BusObject to signals from specified interface and
-// method (member).
-func (o *Object) AddMatchSignal(iface, member string) *Call {
- return o.Call(
+// CallWithContext acts like Call but takes a context
+func (o *Object) CallWithContext(ctx context.Context, method string, flags Flags, args ...interface{}) *Call {
+ return <-o.createCall(ctx, method, flags, make(chan *Call, 1), args...).Done
+}
+
+// MatchOption specifies option for dbus routing match rule. Options can be constructed with WithMatch* helpers.
+// For full list of available options consult
+// https://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-routing-match-rules
+type MatchOption struct {
+ key string
+ value string
+}
+
+// WithMatchOption creates match option with given key and value
+func WithMatchOption(key, value string) MatchOption {
+ return MatchOption{key, value}
+}
+
+// WithMatchObjectPath creates match option that filters events based on given path
+func WithMatchObjectPath(path ObjectPath) MatchOption {
+ return MatchOption{"path", string(path)}
+}
+
+func formatMatchOptions(options []MatchOption) string {
+ items := make([]string, 0, len(options))
+ for _, option := range options {
+ items = append(items, option.key+"='"+option.value+"'")
+ }
+
+ return strings.Join(items, ",")
+}
+
+// AddMatchSignal subscribes BusObject to signals from specified interface,
+// method (member). Additional filter rules can be added via WithMatch* option constructors.
+// Note: To filter events by object path you have to specify this path via an option.
+func (o *Object) AddMatchSignal(iface, member string, options ...MatchOption) *Call {
+ base := []MatchOption{
+ {"type", "signal"},
+ {"interface", iface},
+ {"member", member},
+ }
+
+ options = append(base, options...)
+ return o.conn.BusObject().Call(
"org.freedesktop.DBus.AddMatch",
0,
- "type='signal',interface='"+iface+"',member='"+member+"'",
+ formatMatchOptions(options),
+ )
+}
+
+// RemoveMatchSignal unsubscribes BusObject from signals from specified interface,
+// method (member). Additional filter rules can be added via WithMatch* option constructors
+func (o *Object) RemoveMatchSignal(iface, member string, options ...MatchOption) *Call {
+ base := []MatchOption{
+ {"type", "signal"},
+ {"interface", iface},
+ {"member", member},
+ }
+
+ options = append(base, options...)
+ return o.conn.BusObject().Call(
+ "org.freedesktop.DBus.RemoveMatch",
+ 0,
+ formatMatchOptions(options),
)
}
@@ -49,6 +111,18 @@ func (o *Object) AddMatchSignal(iface, member string) *Call {
// If the method parameter contains a dot ('.'), the part before the last dot
// specifies the interface on which the method is called.
func (o *Object) Go(method string, flags Flags, ch chan *Call, args ...interface{}) *Call {
+ return o.createCall(context.Background(), method, flags, ch, args...)
+}
+
+// GoWithContext acts like Go but takes a context
+func (o *Object) GoWithContext(ctx context.Context, method string, flags Flags, ch chan *Call, args ...interface{}) *Call {
+ return o.createCall(ctx, method, flags, ch, args...)
+}
+
+func (o *Object) createCall(ctx context.Context, method string, flags Flags, ch chan *Call, args ...interface{}) *Call {
+ if ctx == nil {
+ panic("nil context")
+ }
iface := ""
i := strings.LastIndex(method, ".")
if i != -1 {
@@ -76,28 +150,28 @@ func (o *Object) Go(method string, flags Flags, ch chan *Call, args ...interface
} else if cap(ch) == 0 {
panic("dbus: unbuffered channel passed to (*Object).Go")
}
+ ctx, cancel := context.WithCancel(ctx)
call := &Call{
Destination: o.dest,
Path: o.path,
Method: method,
Args: args,
Done: ch,
+ ctxCanceler: cancel,
+ ctx: ctx,
}
- o.conn.callsLck.Lock()
- o.conn.calls[msg.serial] = call
- o.conn.callsLck.Unlock()
- o.conn.outLck.RLock()
- if o.conn.closed {
- call.Err = ErrClosed
- call.Done <- call
- } else {
- o.conn.out <- msg
- }
- o.conn.outLck.RUnlock()
+ o.conn.calls.track(msg.serial, call)
+ o.conn.sendMessageAndIfClosed(msg, func() {
+ o.conn.calls.handleSendError(msg, ErrClosed)
+ cancel()
+ })
+ go func() {
+ <-ctx.Done()
+ o.conn.calls.handleSendError(msg, ctx.Err())
+ }()
+
return call
}
- o.conn.outLck.RLock()
- defer o.conn.outLck.RUnlock()
done := make(chan *Call, 1)
call := &Call{
Err: nil,
@@ -107,11 +181,9 @@ func (o *Object) Go(method string, flags Flags, ch chan *Call, args ...interface
call.Done <- call
close(done)
}()
- if o.conn.closed {
+ o.conn.sendMessageAndIfClosed(msg, func() {
call.Err = ErrClosed
- return call
- }
- o.conn.out <- msg
+ })
return call
}
diff --git a/vendor/github.com/godbus/dbus/server_interfaces.go b/vendor/github.com/godbus/dbus/server_interfaces.go
index 091948ae..01166f0b 100644
--- a/vendor/github.com/godbus/dbus/server_interfaces.go
+++ b/vendor/github.com/godbus/dbus/server_interfaces.go
@@ -87,3 +87,13 @@ type SignalHandler interface {
type DBusError interface {
DBusError() (string, []interface{})
}
+
+// SerialGenerator is responsible for serials generation.
+//
+// Different approaches for the serial generation can be used,
+// maintaining a map guarded with a mutex (the standard way) or
+// simply increment an atomic counter.
+type SerialGenerator interface {
+ GetSerial() uint32
+ RetireSerial(serial uint32)
+}
diff --git a/vendor/github.com/godbus/dbus/transport_generic.go b/vendor/github.com/godbus/dbus/transport_generic.go
index 3fad859a..718a1ff0 100644
--- a/vendor/github.com/godbus/dbus/transport_generic.go
+++ b/vendor/github.com/godbus/dbus/transport_generic.go
@@ -11,7 +11,7 @@ var nativeEndian binary.ByteOrder
func detectEndianness() binary.ByteOrder {
var x uint32 = 0x01020304
- if *(*byte)(unsafe.Pointer(&x)) == 0x01 {
+ if *(*byte)(unsafe.Pointer(&x)) == 0x01 {
return binary.BigEndian
}
return binary.LittleEndian
diff --git a/vendor/github.com/godbus/dbus/transport_nonce_tcp.go b/vendor/github.com/godbus/dbus/transport_nonce_tcp.go
new file mode 100644
index 00000000..697739ef
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/transport_nonce_tcp.go
@@ -0,0 +1,39 @@
+//+build !windows
+
+package dbus
+
+import (
+ "errors"
+ "io/ioutil"
+ "net"
+)
+
+func init() {
+ transports["nonce-tcp"] = newNonceTcpTransport
+}
+
+func newNonceTcpTransport(keys string) (transport, error) {
+ host := getKey(keys, "host")
+ port := getKey(keys, "port")
+ noncefile := getKey(keys, "noncefile")
+ if host == "" || port == "" || noncefile == "" {
+ return nil, errors.New("dbus: unsupported address (must set host, port and noncefile)")
+ }
+ protocol, err := tcpFamily(keys)
+ if err != nil {
+ return nil, err
+ }
+ socket, err := net.Dial(protocol, net.JoinHostPort(host, port))
+ if err != nil {
+ return nil, err
+ }
+ b, err := ioutil.ReadFile(noncefile)
+ if err != nil {
+ return nil, err
+ }
+ _, err = socket.Write(b)
+ if err != nil {
+ return nil, err
+ }
+ return NewConn(socket)
+}
diff --git a/vendor/github.com/godbus/dbus/transport_unix.go b/vendor/github.com/godbus/dbus/transport_unix.go
index e56d5ca9..f000c6b5 100644
--- a/vendor/github.com/godbus/dbus/transport_unix.go
+++ b/vendor/github.com/godbus/dbus/transport_unix.go
@@ -31,6 +31,7 @@ func (o *oobReader) Read(b []byte) (n int, err error) {
type unixTransport struct {
*net.UnixConn
+ rdr *oobReader
hasUnixFDs bool
}
@@ -79,10 +80,15 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
// To be sure that all bytes of out-of-band data are read, we use a special
// reader that uses ReadUnix on the underlying connection instead of Read
// and gathers the out-of-band data in a buffer.
- rd := &oobReader{conn: t.UnixConn}
+ if t.rdr == nil {
+ t.rdr = &oobReader{conn: t.UnixConn}
+ } else {
+ t.rdr.oob = nil
+ }
+
// read the first 16 bytes (the part of the header that has a constant size),
// from which we can figure out the length of the rest of the message
- if _, err := io.ReadFull(rd, csheader[:]); err != nil {
+ if _, err := io.ReadFull(t.rdr, csheader[:]); err != nil {
return nil, err
}
switch csheader[0] {
@@ -104,7 +110,7 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
// decode headers and look for unix fds
headerdata := make([]byte, hlen+4)
copy(headerdata, csheader[12:])
- if _, err := io.ReadFull(t, headerdata[4:]); err != nil {
+ if _, err := io.ReadFull(t.rdr, headerdata[4:]); err != nil {
return nil, err
}
dec := newDecoder(bytes.NewBuffer(headerdata), order)
@@ -122,7 +128,7 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
all := make([]byte, 16+hlen+blen)
copy(all, csheader[:])
copy(all[16:], headerdata[4:])
- if _, err := io.ReadFull(rd, all[16+hlen:]); err != nil {
+ if _, err := io.ReadFull(t.rdr, all[16+hlen:]); err != nil {
return nil, err
}
if unixfds != 0 {
@@ -130,7 +136,7 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
return nil, errors.New("dbus: got unix fds on unsupported transport")
}
// read the fds from the OOB data
- scms, err := syscall.ParseSocketControlMessage(rd.oob)
+ scms, err := syscall.ParseSocketControlMessage(t.rdr.oob)
if err != nil {
return nil, err
}
@@ -148,11 +154,23 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
// substitute the values in the message body (which are indices for the
// array receiver via OOB) with the actual values
for i, v := range msg.Body {
- if j, ok := v.(UnixFDIndex); ok {
+ switch v.(type) {
+ case UnixFDIndex:
+ j := v.(UnixFDIndex)
if uint32(j) >= unixfds {
return nil, InvalidMessageError("invalid index for unix fd")
}
msg.Body[i] = UnixFD(fds[j])
+ case []UnixFDIndex:
+ idxArray := v.([]UnixFDIndex)
+ fdArray := make([]UnixFD, len(idxArray))
+ for k, j := range idxArray {
+ if uint32(j) >= unixfds {
+ return nil, InvalidMessageError("invalid index for unix fd")
+ }
+ fdArray[k] = UnixFD(fds[j])
+ }
+ msg.Body[i] = fdArray
}
}
return msg, nil
diff --git a/vendor/github.com/google/go-github/github/github-accessors.go b/vendor/github.com/google/go-github/github/github-accessors.go
index 3ec79c2c..f86ae74b 100644
--- a/vendor/github.com/google/go-github/github/github-accessors.go
+++ b/vendor/github.com/google/go-github/github/github-accessors.go
@@ -1292,6 +1292,14 @@ func (c *CommitFile) GetPatch() string {
return *c.Patch
}
+// GetPreviousFilename returns the PreviousFilename field if it's non-nil, zero value otherwise.
+func (c *CommitFile) GetPreviousFilename() string {
+ if c == nil || c.PreviousFilename == nil {
+ return ""
+ }
+ return *c.PreviousFilename
+}
+
// GetRawURL returns the RawURL field if it's non-nil, zero value otherwise.
func (c *CommitFile) GetRawURL() string {
if c == nil || c.RawURL == nil {
@@ -2292,6 +2300,14 @@ func (d *DeploymentStatusRequest) GetDescription() string {
return *d.Description
}
+// GetEnvironment returns the Environment field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatusRequest) GetEnvironment() string {
+ if d == nil || d.Environment == nil {
+ return ""
+ }
+ return *d.Environment
+}
+
// GetEnvironmentURL returns the EnvironmentURL field if it's non-nil, zero value otherwise.
func (d *DeploymentStatusRequest) GetEnvironmentURL() string {
if d == nil || d.EnvironmentURL == nil {
@@ -10100,6 +10116,22 @@ func (s *ServiceHook) GetName() string {
return *s.Name
}
+// GetEnabled returns the Enabled field if it's non-nil, zero value otherwise.
+func (s *SignaturesProtectedBranch) GetEnabled() bool {
+ if s == nil || s.Enabled == nil {
+ return false
+ }
+ return *s.Enabled
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (s *SignaturesProtectedBranch) GetURL() string {
+ if s == nil || s.URL == nil {
+ return ""
+ }
+ return *s.URL
+}
+
// GetPayload returns the Payload field if it's non-nil, zero value otherwise.
func (s *SignatureVerification) GetPayload() string {
if s == nil || s.Payload == nil {
diff --git a/vendor/github.com/google/go-github/github/github.go b/vendor/github.com/google/go-github/github/github.go
index 320b8104..c58d7f9b 100644
--- a/vendor/github.com/google/go-github/github/github.go
+++ b/vendor/github.com/google/go-github/github/github.go
@@ -54,6 +54,9 @@ const (
// https://developer.github.com/changes/2016-04-06-deployment-and-deployment-status-enhancements/
mediaTypeDeploymentStatusPreview = "application/vnd.github.ant-man-preview+json"
+ // https://developer.github.com/changes/2018-10-16-deployments-environments-states-and-auto-inactive-updates/
+ mediaTypeExpandDeploymentStatusPreview = "application/vnd.github.flash-preview+json"
+
// https://developer.github.com/changes/2016-02-19-source-import-preview-api/
mediaTypeImportPreview = "application/vnd.github.barred-rock-preview"
@@ -122,6 +125,9 @@ const (
// https://developer.github.com/enterprise/2.13/v3/repos/pre_receive_hooks/
mediaTypePreReceiveHooksPreview = "application/vnd.github.eye-scream-preview"
+
+ // https://developer.github.com/changes/2018-02-22-protected-branches-required-signatures/
+ mediaTypeSignaturePreview = "application/vnd.github.zzzax-preview+json"
)
// A Client manages communication with the GitHub API.
diff --git a/vendor/github.com/google/go-github/github/pulls.go b/vendor/github.com/google/go-github/github/pulls.go
index a0c3c041..60261142 100644
--- a/vendor/github.com/google/go-github/github/pulls.go
+++ b/vendor/github.com/google/go-github/github/pulls.go
@@ -107,7 +107,7 @@ type PullRequestBranch struct {
// PullRequestsService.List method.
type PullRequestListOptions struct {
// State filters pull requests based on their state. Possible values are:
- // open, closed. Default is "open".
+ // open, closed, all. Default is "open".
State string `url:"state,omitempty"`
// Head filters pull requests by head user and branch name in the format of:
diff --git a/vendor/github.com/google/go-github/github/repos.go b/vendor/github.com/google/go-github/github/repos.go
index e783ccbe..d09b5cc8 100644
--- a/vendor/github.com/google/go-github/github/repos.go
+++ b/vendor/github.com/google/go-github/github/repos.go
@@ -698,6 +698,13 @@ type DismissalRestrictionsRequest struct {
Teams *[]string `json:"teams,omitempty"`
}
+// SignaturesProtectedBranch represents the protection status of an individual branch.
+type SignaturesProtectedBranch struct {
+ URL *string `json:"url,omitempty"`
+ // Commits pushed to matching branches must have verified signatures.
+ Enabled *bool `json:"enabled,omitempty"`
+}
+
// ListBranches lists branches for the specified repository.
//
// GitHub API docs: https://developer.github.com/v3/repos/#list-branches
@@ -850,6 +857,67 @@ func (s *RepositoriesService) RemoveBranchProtection(ctx context.Context, owner,
return s.client.Do(ctx, req, nil)
}
+// GetSignaturesProtectedBranch gets required signatures of protected branch.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-required-signatures-of-protected-branch
+func (s *RepositoriesService) GetSignaturesProtectedBranch(ctx context.Context, owner, repo, branch string) (*SignaturesProtectedBranch, *Response, error) {
+ u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_signatures", owner, repo, branch)
+ req, err := s.client.NewRequest("GET", u, nil)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ // TODO: remove custom Accept header when this API fully launches
+ req.Header.Set("Accept", mediaTypeSignaturePreview)
+
+ p := new(SignaturesProtectedBranch)
+ resp, err := s.client.Do(ctx, req, p)
+ if err != nil {
+ return nil, resp, err
+ }
+
+ return p, resp, nil
+}
+
+// RequireSignaturesOnProtectedBranch makes signed commits required on a protected branch.
+// It requires admin access and branch protection to be enabled.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#add-required-signatures-of-protected-branch
+func (s *RepositoriesService) RequireSignaturesOnProtectedBranch(ctx context.Context, owner, repo, branch string) (*SignaturesProtectedBranch, *Response, error) {
+ u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_signatures", owner, repo, branch)
+ req, err := s.client.NewRequest("POST", u, nil)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ // TODO: remove custom Accept header when this API fully launches
+ req.Header.Set("Accept", mediaTypeSignaturePreview)
+
+ r := new(SignaturesProtectedBranch)
+ resp, err := s.client.Do(ctx, req, r)
+ if err != nil {
+ return nil, resp, err
+ }
+
+ return r, resp, err
+}
+
+// OptionalSignaturesOnProtectedBranch removes required signed commits on a given branch.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-required-signatures-of-protected-branch
+func (s *RepositoriesService) OptionalSignaturesOnProtectedBranch(ctx context.Context, owner, repo, branch string) (*Response, error) {
+ u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_signatures", owner, repo, branch)
+ req, err := s.client.NewRequest("DELETE", u, nil)
+ if err != nil {
+ return nil, err
+ }
+
+ // TODO: remove custom Accept header when this API fully launches
+ req.Header.Set("Accept", mediaTypeSignaturePreview)
+
+ return s.client.Do(ctx, req, nil)
+}
+
// UpdateRequiredStatusChecks updates the required status checks for a given protected branch.
//
// GitHub API docs: https://developer.github.com/v3/repos/branches/#update-required-status-checks-of-protected-branch
diff --git a/vendor/github.com/google/go-github/github/repos_commits.go b/vendor/github.com/google/go-github/github/repos_commits.go
index 04faa3ea..1acfa5ad 100644
--- a/vendor/github.com/google/go-github/github/repos_commits.go
+++ b/vendor/github.com/google/go-github/github/repos_commits.go
@@ -48,16 +48,17 @@ func (c CommitStats) String() string {
// CommitFile represents a file modified in a commit.
type CommitFile struct {
- SHA *string `json:"sha,omitempty"`
- Filename *string `json:"filename,omitempty"`
- Additions *int `json:"additions,omitempty"`
- Deletions *int `json:"deletions,omitempty"`
- Changes *int `json:"changes,omitempty"`
- Status *string `json:"status,omitempty"`
- Patch *string `json:"patch,omitempty"`
- BlobURL *string `json:"blob_url,omitempty"`
- RawURL *string `json:"raw_url,omitempty"`
- ContentsURL *string `json:"contents_url,omitempty"`
+ SHA *string `json:"sha,omitempty"`
+ Filename *string `json:"filename,omitempty"`
+ Additions *int `json:"additions,omitempty"`
+ Deletions *int `json:"deletions,omitempty"`
+ Changes *int `json:"changes,omitempty"`
+ Status *string `json:"status,omitempty"`
+ Patch *string `json:"patch,omitempty"`
+ BlobURL *string `json:"blob_url,omitempty"`
+ RawURL *string `json:"raw_url,omitempty"`
+ ContentsURL *string `json:"contents_url,omitempty"`
+ PreviousFilename *string `json:"previous_filename,omitempty"`
}
func (c CommitFile) String() string {
diff --git a/vendor/github.com/google/go-github/github/repos_deployments.go b/vendor/github.com/google/go-github/github/repos_deployments.go
index 794c3232..604632e9 100644
--- a/vendor/github.com/google/go-github/github/repos_deployments.go
+++ b/vendor/github.com/google/go-github/github/repos_deployments.go
@@ -9,6 +9,7 @@ import (
"context"
"encoding/json"
"fmt"
+ "strings"
)
// Deployment represents a deployment in a repo
@@ -116,7 +117,8 @@ func (s *RepositoriesService) CreateDeployment(ctx context.Context, owner, repo
}
// TODO: remove custom Accept headers when APIs fully launch.
- req.Header.Set("Accept", mediaTypeDeploymentStatusPreview)
+ acceptHeaders := []string{mediaTypeDeploymentStatusPreview, mediaTypeExpandDeploymentStatusPreview}
+ req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
d := new(Deployment)
resp, err := s.client.Do(ctx, req, d)
@@ -149,6 +151,7 @@ type DeploymentStatusRequest struct {
State *string `json:"state,omitempty"`
LogURL *string `json:"log_url,omitempty"`
Description *string `json:"description,omitempty"`
+ Environment *string `json:"environment,omitempty"`
EnvironmentURL *string `json:"environment_url,omitempty"`
AutoInactive *bool `json:"auto_inactive,omitempty"`
}
@@ -189,7 +192,8 @@ func (s *RepositoriesService) GetDeploymentStatus(ctx context.Context, owner, re
}
// TODO: remove custom Accept headers when APIs fully launch.
- req.Header.Set("Accept", mediaTypeDeploymentStatusPreview)
+ acceptHeaders := []string{mediaTypeDeploymentStatusPreview, mediaTypeExpandDeploymentStatusPreview}
+ req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
d := new(DeploymentStatus)
resp, err := s.client.Do(ctx, req, d)
@@ -212,7 +216,8 @@ func (s *RepositoriesService) CreateDeploymentStatus(ctx context.Context, owner,
}
// TODO: remove custom Accept headers when APIs fully launch.
- req.Header.Set("Accept", mediaTypeDeploymentStatusPreview)
+ acceptHeaders := []string{mediaTypeDeploymentStatusPreview, mediaTypeExpandDeploymentStatusPreview}
+ req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
d := new(DeploymentStatus)
resp, err := s.client.Do(ctx, req, d)
diff --git a/vendor/github.com/rivo/tview/README.md b/vendor/github.com/rivo/tview/README.md
index 99e89b6b..5a182b66 100644
--- a/vendor/github.com/rivo/tview/README.md
+++ b/vendor/github.com/rivo/tview/README.md
@@ -65,6 +65,8 @@ Add your issue here on GitHub. Feel free to get in touch if you have any questio
(There are no corresponding tags in the project. I only keep such a history in this README.)
+- v0.19 (2018-10-28)
+ - Added `QueueUpdate()` and `QueueEvent()` to `Application` to help with modifications to primitives from goroutines.
- v0.18 (2018-10-18)
- `InputField` elements can now be navigated freely.
- v0.17 (2018-06-20)
diff --git a/vendor/github.com/rivo/tview/application.go b/vendor/github.com/rivo/tview/application.go
index 146954a1..1cf113c7 100644
--- a/vendor/github.com/rivo/tview/application.go
+++ b/vendor/github.com/rivo/tview/application.go
@@ -1,25 +1,34 @@
package tview
import (
- "fmt"
- "os"
"sync"
"github.com/gdamore/tcell"
)
+// The size of the event/update/redraw channels.
+const queueSize = 100
+
// Application represents the top node of an application.
//
// It is not strictly required to use this class as none of the other classes
// depend on it. However, it provides useful tools to set up an application and
// plays nicely with all widgets.
+//
+// The following command displays a primitive p on the screen until Ctrl-C is
+// pressed:
+//
+// if err := tview.NewApplication().SetRoot(p, true).Run(); err != nil {
+// panic(err)
+// }
type Application struct {
sync.RWMutex
// The application's screen.
screen tcell.Screen
- // Indicates whether the application's screen is currently active.
+ // Indicates whether the application's screen is currently active. This is
+ // false during suspended mode.
running bool
// The primitive which currently has the keyboard focus.
@@ -44,13 +53,23 @@ type Application struct {
// was drawn.
afterDraw func(screen tcell.Screen)
- // Halts the event loop during suspended mode.
- suspendMutex sync.Mutex
+ // Used to send screen events from separate goroutine to main event loop
+ events chan tcell.Event
+
+ // Functions queued from goroutines, used to serialize updates to primitives.
+ updates chan func()
+
+ // A channel which signals the end of the suspended mode.
+ suspendToken chan struct{}
}
// NewApplication creates and returns a new application.
func NewApplication() *Application {
- return &Application{}
+ return &Application{
+ events: make(chan tcell.Event, queueSize),
+ updates: make(chan func(), queueSize),
+ suspendToken: make(chan struct{}, 1),
+ }
}
// SetInputCapture sets a function which captures all key events before they are
@@ -134,65 +153,105 @@ func (a *Application) Run() error {
// Draw the screen for the first time.
a.Unlock()
- a.Draw()
+ a.draw()
+
+ // Separate loop to wait for screen events.
+ var wg sync.WaitGroup
+ wg.Add(1)
+ a.suspendToken <- struct{}{} // We need this to get started.
+ go func() {
+ defer wg.Done()
+ for range a.suspendToken {
+ for {
+ a.RLock()
+ screen := a.screen
+ a.RUnlock()
+ if screen == nil {
+ // We have no screen. We might need to stop.
+ break
+ }
+
+ // Wait for next event and queue it.
+ event := screen.PollEvent()
+ if event != nil {
+ // Regular event. Queue.
+ a.QueueEvent(event)
+ continue
+ }
+
+ // A screen was finalized (event is nil).
+ a.RLock()
+ running := a.running
+ a.RUnlock()
+ if running {
+ // The application was stopped. End the event loop.
+ a.QueueEvent(nil)
+ return
+ }
+
+ // We're in suspended mode (running is false). Pause and wait for new
+ // token.
+ break
+ }
+ }
+ }()
// Start event loop.
+EventLoop:
for {
- // Do not poll events during suspend mode
- a.suspendMutex.Lock()
- a.RLock()
- screen := a.screen
- a.RUnlock()
- if screen == nil {
- a.suspendMutex.Unlock()
- break
- }
+ select {
+ case event := <-a.events:
+ if event == nil {
+ break EventLoop
+ }
- // Wait for next event.
- event := a.screen.PollEvent()
- a.suspendMutex.Unlock()
- if event == nil {
- // The screen was finalized. Exit the loop.
- break
- }
+ switch event := event.(type) {
+ case *tcell.EventKey:
+ a.RLock()
+ p := a.focus
+ inputCapture := a.inputCapture
+ a.RUnlock()
- switch event := event.(type) {
- case *tcell.EventKey:
- a.RLock()
- p := a.focus
- a.RUnlock()
-
- // Intercept keys.
- if a.inputCapture != nil {
- event = a.inputCapture(event)
- if event == nil {
- break // Don't forward event.
+ // Intercept keys.
+ if inputCapture != nil {
+ event = inputCapture(event)
+ if event == nil {
+ continue // Don't forward event.
+ }
}
- }
- // Ctrl-C closes the application.
- if event.Key() == tcell.KeyCtrlC {
- a.Stop()
- }
-
- // Pass other key events to the currently focused primitive.
- if p != nil {
- if handler := p.InputHandler(); handler != nil {
- handler(event, func(p Primitive) {
- a.SetFocus(p)
- })
- a.Draw()
+ // Ctrl-C closes the application.
+ if event.Key() == tcell.KeyCtrlC {
+ a.Stop()
}
+
+ // Pass other key events to the currently focused primitive.
+ if p != nil {
+ if handler := p.InputHandler(); handler != nil {
+ handler(event, func(p Primitive) {
+ a.SetFocus(p)
+ })
+ a.draw()
+ }
+ }
+ case *tcell.EventResize:
+ a.RLock()
+ screen := a.screen
+ a.RUnlock()
+ screen.Clear()
+ a.draw()
}
- case *tcell.EventResize:
- a.RLock()
- screen := a.screen
- a.RUnlock()
- screen.Clear()
- a.Draw()
+
+ // If we have updates, now is the time to execute them.
+ case updater := <-a.updates:
+ updater()
}
}
+ a.running = false
+ close(a.suspendToken)
+ wg.Wait()
+
return nil
}
@@ -200,12 +259,13 @@ func (a *Application) Run() error {
func (a *Application) Stop() {
a.Lock()
defer a.Unlock()
- if a.screen == nil {
+ screen := a.screen
+ if screen == nil {
return
}
- a.screen.Fini()
a.screen = nil
- a.running = false
+ screen.Fini()
+ // a.running is still true, the main loop will clean up.
}
// Suspend temporarily suspends the application by exiting terminal UI mode and
@@ -216,32 +276,26 @@ func (a *Application) Stop() {
// was called. If false is returned, the application was already suspended,
// terminal UI mode was not exited, and "f" was not called.
func (a *Application) Suspend(f func()) bool {
- a.RLock()
+ a.Lock()
- if a.screen == nil {
+ screen := a.screen
+ if screen == nil {
// Screen has not yet been initialized.
- a.RUnlock()
+ a.Unlock()
return false
}
- // Enter suspended mode.
- a.suspendMutex.Lock()
- defer a.suspendMutex.Unlock()
- a.RUnlock()
- a.Stop()
-
- // Deal with panics during suspended mode. Exit the program.
- defer func() {
- if p := recover(); p != nil {
- fmt.Println(p)
- os.Exit(1)
- }
- }()
+ // Enter suspended mode. Make a new screen here already so our event loop can
+ // continue.
+ a.screen = nil
+ a.running = false
+ screen.Fini()
+ a.Unlock()
// Wait for "f" to return.
f()
- // Make a new screen and redraw.
+ // Initialize our new screen and draw the contents.
a.Lock()
var err error
a.screen, err = tcell.NewScreen()
@@ -255,15 +309,26 @@ func (a *Application) Suspend(f func()) bool {
}
a.running = true
a.Unlock()
- a.Draw()
+ a.draw()
+ a.suspendToken <- struct{}{}
+ // One key event will get lost, see https://github.com/gdamore/tcell/issues/194
// Continue application loop.
return true
}
-// Draw refreshes the screen. It calls the Draw() function of the application's
-// root primitive and then syncs the screen buffer.
+// Draw refreshes the screen (during the next update cycle). It calls the Draw()
+// function of the application's root primitive and then syncs the screen
+// buffer.
func (a *Application) Draw() *Application {
+ a.QueueUpdate(func() {
+ a.draw()
+ })
+ return a
+}
+
+// draw actually does what Draw() promises to do.
+func (a *Application) draw() *Application {
a.Lock()
defer a.Unlock()
@@ -404,3 +469,35 @@ func (a *Application) GetFocus() Primitive {
defer a.RUnlock()
return a.focus
}
+
+// QueueUpdate is used to synchronize access to primitives from non-main
+// goroutines. The provided function will be executed as part of the event loop
+// and thus will not cause race conditions with other such update functions or
+// the Draw() function.
+//
+// Note that Draw() is not implicitly called after the execution of f as that
+// may not be desirable. You can call Draw() from f if the screen should be
+// refreshed after each update. Alternatively, use QueueUpdateDraw() to follow
+// up with an immediate refresh of the screen.
+func (a *Application) QueueUpdate(f func()) *Application {
+ a.updates <- f
+ return a
+}
+
+// QueueUpdateDraw works like QueueUpdate() except it refreshes the screen
+// immediately after executing f.
+func (a *Application) QueueUpdateDraw(f func()) *Application {
+ a.QueueUpdate(func() {
+ f()
+ a.draw()
+ })
+ return a
+}
+
+// QueueEvent sends an event to the Application event loop.
+//
+// It is not recommended for event to be nil.
+func (a *Application) QueueEvent(event tcell.Event) *Application {
+ a.events <- event
+ return a
+}
diff --git a/vendor/github.com/rivo/tview/doc.go b/vendor/github.com/rivo/tview/doc.go
index 1b51a273..acde2b41 100644
--- a/vendor/github.com/rivo/tview/doc.go
+++ b/vendor/github.com/rivo/tview/doc.go
@@ -137,6 +137,27 @@ Unicode Support
This package supports unicode characters including wide characters.
+Concurrency
+
+Many functions in this package are not thread-safe. For many applications, this
+may not be an issue: If your code makes changes in response to key events, it
+will execute in the main goroutine and thus will not cause any race conditions.
+
+If you access your primitives from other goroutines, however, you will need to
+synchronize execution. The easiest way to do this is to call
+Application.QueueUpdate() or Application.QueueUpdateDraw() (see the function
+documentation for details):
+
+ go func() {
+ app.QueueUpdateDraw(func() {
+ table.SetCellSimple(0, 0, "Foo bar")
+ })
+ }()
+
+One exception to this is the io.Writer interface implemented by TextView. You
+can safely write to a TextView from any goroutine. See the TextView
+documentation for details.
+
Type Hierarchy
All widgets listed above contain the Box type. All of Box's functions are
diff --git a/vendor/github.com/rivo/tview/inputfield.go b/vendor/github.com/rivo/tview/inputfield.go
index 86c9c208..a0b193b7 100644
--- a/vendor/github.com/rivo/tview/inputfield.go
+++ b/vendor/github.com/rivo/tview/inputfield.go
@@ -102,6 +102,7 @@ func NewInputField() *InputField {
// SetText sets the current text of the input field.
func (i *InputField) SetText(text string) *InputField {
i.text = text
+ i.cursorPos = len(text)
if i.changed != nil {
i.changed(text)
}
@@ -359,21 +360,22 @@ func (i *InputField) InputHandler() func(event *tcell.EventKey, setFocus func(p
i.cursorPos = len(i.text) - len(regexp.MustCompile(`^\s*\S+\s*`).ReplaceAllString(i.text[i.cursorPos:], ""))
}
+ // Add character function. Returns whether or not the rune character is
+ // accepted.
+ add := func(r rune) bool {
+ newText := i.text[:i.cursorPos] + string(r) + i.text[i.cursorPos:]
+ if i.accept != nil {
+ return i.accept(newText, r)
+ }
+ i.text = newText
+ i.cursorPos += len(string(r))
+ return true
+ }
+
// Process key event.
switch key := event.Key(); key {
case tcell.KeyRune: // Regular character.
- modifiers := event.Modifiers()
- if modifiers == tcell.ModNone {
- ch := string(event.Rune())
- newText := i.text[:i.cursorPos] + ch + i.text[i.cursorPos:]
- if i.accept != nil {
- if !i.accept(newText, event.Rune()) {
- break
- }
- }
- i.text = newText
- i.cursorPos += len(ch)
- } else if modifiers&tcell.ModAlt > 0 {
+ if event.Modifiers()&tcell.ModAlt > 0 {
// We accept some Alt- key combinations.
switch event.Rune() {
case 'a': // Home.
@@ -385,6 +387,11 @@ func (i *InputField) InputHandler() func(event *tcell.EventKey, setFocus func(p
case 'f': // Move word right.
moveWordRight()
}
+ } else {
+ // Other keys are simply accepted as regular characters.
+ if !add(event.Rune()) {
+ break
+ }
}
case tcell.KeyCtrlU: // Delete all.
i.text = ""
diff --git a/vendor/github.com/rivo/tview/table.go b/vendor/github.com/rivo/tview/table.go
index cd0de94a..2a10aad1 100644
--- a/vendor/github.com/rivo/tview/table.go
+++ b/vendor/github.com/rivo/tview/table.go
@@ -389,7 +389,7 @@ func (t *Table) SetDoneFunc(handler func(key tcell.Key)) *Table {
}
// SetCell sets the content of a cell the specified position. It is ok to
-// directly instantiate a TableCell object. If the cell has contain, at least
+// directly instantiate a TableCell object. If the cell has content, at least
// the Text and Color fields should be set.
//
// Note that setting cells in previously unknown rows and columns will
@@ -422,7 +422,7 @@ func (t *Table) SetCellSimple(row, column int, text string) *Table {
}
// GetCell returns the contents of the cell at the specified position. A valid
-// TableCell object is always returns but it will be uninitialized if the cell
+// TableCell object is always returned but it will be uninitialized if the cell
// was not previously set.
func (t *Table) GetCell(row, column int) *TableCell {
if row >= len(t.cells) || column >= len(t.cells[row]) {
@@ -431,6 +431,31 @@ func (t *Table) GetCell(row, column int) *TableCell {
return t.cells[row][column]
}
+// RemoveRow removes the row at the given position from the table. If there is
+// no such row, this has no effect.
+func (t *Table) RemoveRow(row int) *Table {
+ if row < 0 || row >= len(t.cells) {
+ return t
+ }
+
+ t.cells = append(t.cells[:row], t.cells[row+1:]...)
+
+ return t
+}
+
+// RemoveColumn removes the column at the given position from the table. If
+// there is no such column, this has no effect.
+func (t *Table) RemoveColumn(column int) *Table {
+ for row := range t.cells {
+ if column < 0 || column >= len(t.cells[row]) {
+ continue
+ }
+ t.cells[row] = append(t.cells[row][:column], t.cells[row][column+1:]...)
+ }
+
+ return t
+}
+
// GetRowCount returns the number of rows in the table.
func (t *Table) GetRowCount() int {
return len(t.cells)
diff --git a/vendor/github.com/rivo/tview/textview.go b/vendor/github.com/rivo/tview/textview.go
index d3c5f5e7..00ac88cd 100644
--- a/vendor/github.com/rivo/tview/textview.go
+++ b/vendor/github.com/rivo/tview/textview.go
@@ -31,7 +31,7 @@ type textViewIndex struct {
// TextView is a box which displays text. It implements the io.Writer interface
// so you can stream text to it. This does not trigger a redraw automatically
// but if a handler is installed via SetChangedFunc(), you can cause it to be
-// redrawn.
+// redrawn. (See SetChangedFunc() for more details.)
//
// Navigation
//
@@ -260,8 +260,20 @@ func (t *TextView) SetRegions(regions bool) *TextView {
}
// SetChangedFunc sets a handler function which is called when the text of the
-// text view has changed. This is typically used to cause the application to
-// redraw the screen.
+// text view has changed. This is useful when text is written to this io.Writer
+// in a separate goroutine. This does not automatically cause the screen to be
+// refreshed so you may want to use the "changed" handler to redraw the screen.
+//
+// Note that to avoid race conditions or deadlocks, there are a few rules you
+// should follow:
+//
+// - You can call Application.Draw() from this handler.
+// - You can call TextView.HasFocus() from this handler.
+// - During the execution of this handler, access to any other variables from
+// this primitive or any other primitive should be queued using
+// Application.QueueUpdate().
+//
+// See package description for details on dealing with concurrency.
func (t *TextView) SetChangedFunc(handler func()) *TextView {
t.changed = handler
return t
@@ -441,13 +453,33 @@ func (t *TextView) GetRegionText(regionID string) string {
return escapePattern.ReplaceAllString(buffer.String(), `[$1$2]`)
}
+// Focus is called when this primitive receives focus.
+func (t *TextView) Focus(delegate func(p Primitive)) {
+ // Implemented here with locking because this is used by layout primitives.
+ t.Lock()
+ defer t.Unlock()
+ t.hasFocus = true
+}
+
+// HasFocus returns whether or not this primitive has focus.
+func (t *TextView) HasFocus() bool {
+ // Implemented here with locking because this may be used in the "changed"
+ // callback.
+ t.Lock()
+ defer t.Unlock()
+ return t.hasFocus
+}
+
// Write lets us implement the io.Writer interface. Tab characters will be
// replaced with TabSize space characters. A "\n" or "\r\n" will be interpreted
// as a new line.
func (t *TextView) Write(p []byte) (n int, err error) {
// Notify at the end.
- if t.changed != nil {
- defer t.changed()
+ t.Lock()
+ changed := t.changed
+ t.Unlock()
+ if changed != nil {
+ defer changed() // Deadlocks may occur if we lock here.
}
t.Lock()
@@ -840,18 +872,21 @@ func (t *TextView) Draw(screen tcell.Screen) {
// Print the line.
var colorPos, regionPos, escapePos, tagOffset, skipped int
iterateString(strippedText, func(main rune, comb []rune, textPos, textWidth, screenPos, screenWidth int) bool {
- // Get the color.
- if colorPos < len(colorTags) && textPos+tagOffset >= colorTagIndices[colorPos][0] && textPos+tagOffset < colorTagIndices[colorPos][1] {
- foregroundColor, backgroundColor, attributes = styleFromTag(foregroundColor, backgroundColor, attributes, colorTags[colorPos])
- tagOffset += colorTagIndices[colorPos][1] - colorTagIndices[colorPos][0]
- colorPos++
- }
-
- // Get the region.
- if regionPos < len(regionIndices) && textPos+tagOffset >= regionIndices[regionPos][0] && textPos+tagOffset < regionIndices[regionPos][1] {
- regionID = regions[regionPos][1]
- tagOffset += regionIndices[regionPos][1] - regionIndices[regionPos][0]
- regionPos++
+ // Process tags.
+ for {
+ if colorPos < len(colorTags) && textPos+tagOffset >= colorTagIndices[colorPos][0] && textPos+tagOffset < colorTagIndices[colorPos][1] {
+ // Get the color.
+ foregroundColor, backgroundColor, attributes = styleFromTag(foregroundColor, backgroundColor, attributes, colorTags[colorPos])
+ tagOffset += colorTagIndices[colorPos][1] - colorTagIndices[colorPos][0]
+ colorPos++
+ } else if regionPos < len(regionIndices) && textPos+tagOffset >= regionIndices[regionPos][0] && textPos+tagOffset < regionIndices[regionPos][1] {
+ // Get the region.
+ regionID = regions[regionPos][1]
+ tagOffset += regionIndices[regionPos][1] - regionIndices[regionPos][0]
+ regionPos++
+ } else {
+ break
+ }
}
// Skip the second-to-last character of an escape tag.
@@ -894,7 +929,7 @@ func (t *TextView) Draw(screen tcell.Screen) {
}
// Stop at the right border.
- if posX+screenWidth >= width {
+ if posX+screenWidth > width {
return true
}
diff --git a/vendor/github.com/rivo/tview/treeview.go b/vendor/github.com/rivo/tview/treeview.go
index d90302c0..aec12a88 100644
--- a/vendor/github.com/rivo/tview/treeview.go
+++ b/vendor/github.com/rivo/tview/treeview.go
@@ -569,7 +569,7 @@ func (t *TreeView) Draw(screen tcell.Screen) {
// Draw the tree.
posY := y
- lineStyle := tcell.StyleDefault.Foreground(t.graphicsColor)
+ lineStyle := tcell.StyleDefault.Background(t.backgroundColor).Foreground(t.graphicsColor)
for index, node := range t.nodes {
// Skip invisible parts.
if posY >= y+height+1 {
diff --git a/vendor/github.com/xanzy/go-gitlab/README.md b/vendor/github.com/xanzy/go-gitlab/README.md
index dc918d3b..995558f0 100644
--- a/vendor/github.com/xanzy/go-gitlab/README.md
+++ b/vendor/github.com/xanzy/go-gitlab/README.md
@@ -46,7 +46,7 @@ to add new and/or missing endpoints. Currently the following services are suppor
- [x] Jobs
- [x] Keys
- [x] Labels
-- [ ] License
+- [x] License
- [x] Merge Requests
- [x] Merge Request Approvals
- [x] Project Milestones
diff --git a/vendor/github.com/xanzy/go-gitlab/gitlab.go b/vendor/github.com/xanzy/go-gitlab/gitlab.go
index 1b82e9b6..c1aa169f 100644
--- a/vendor/github.com/xanzy/go-gitlab/gitlab.go
+++ b/vendor/github.com/xanzy/go-gitlab/gitlab.go
@@ -303,6 +303,7 @@ type Client struct {
Keys *KeysService
Boards *IssueBoardsService
Labels *LabelsService
+ License *LicenseService
LicenseTemplates *LicenseTemplatesService
MergeRequests *MergeRequestsService
MergeRequestApprovals *MergeRequestApprovalsService
@@ -442,6 +443,7 @@ func newClient(httpClient *http.Client) *Client {
c.Keys = &KeysService{client: c}
c.Boards = &IssueBoardsService{client: c}
c.Labels = &LabelsService{client: c}
+ c.License = &LicenseService{client: c}
c.LicenseTemplates = &LicenseTemplatesService{client: c}
c.MergeRequests = &MergeRequestsService{client: c, timeStats: timeStats}
c.MergeRequestApprovals = &MergeRequestApprovalsService{client: c}
diff --git a/vendor/github.com/xanzy/go-gitlab/go.mod b/vendor/github.com/xanzy/go-gitlab/go.mod
new file mode 100644
index 00000000..594df266
--- /dev/null
+++ b/vendor/github.com/xanzy/go-gitlab/go.mod
@@ -0,0 +1,7 @@
+module github.com/xanzy/go-gitlab
+
+require (
+ github.com/google/go-querystring v1.0.0
+ golang.org/x/net v0.0.0-20181108082009-03003ca0c849 // indirect
+ golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288
+)
diff --git a/vendor/github.com/xanzy/go-gitlab/go.sum b/vendor/github.com/xanzy/go-gitlab/go.sum
new file mode 100644
index 00000000..db63e00e
--- /dev/null
+++ b/vendor/github.com/xanzy/go-gitlab/go.sum
@@ -0,0 +1,6 @@
+github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
+github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
+golang.org/x/net v0.0.0-20181108082009-03003ca0c849 h1:FSqE2GGG7wzsYUsWiQ8MZrvEd1EOyU3NCF0AW3Wtltg=
+golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288 h1:JIqe8uIcRBHXDQVvZtHwp80ai3Lw3IJAeJEs55Dc1W0=
+golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
diff --git a/vendor/github.com/xanzy/go-gitlab/issues.go b/vendor/github.com/xanzy/go-gitlab/issues.go
index 04852942..fc999c05 100644
--- a/vendor/github.com/xanzy/go-gitlab/issues.go
+++ b/vendor/github.com/xanzy/go-gitlab/issues.go
@@ -42,30 +42,30 @@ type Issue struct {
ProjectID int `json:"project_id"`
Milestone *Milestone `json:"milestone"`
Author struct {
- ID int `json:"id"`
- Username string `json:"username"`
- Email string `json:"email"`
- Name string `json:"name"`
- State string `json:"state"`
- CreatedAt *time.Time `json:"created_at"`
+ ID int `json:"id"`
+ State string `json:"state"`
+ WebURL string `json:"web_url"`
+ Name string `json:"name"`
+ AvatarURL string `json:"avatar_url"`
+ Username string `json:"username"`
} `json:"author"`
Description string `json:"description"`
State string `json:"state"`
Assignees []struct {
- ID int `json:"id"`
- Username string `json:"username"`
- Email string `json:"email"`
- Name string `json:"name"`
- State string `json:"state"`
- CreatedAt *time.Time `json:"created_at"`
+ ID int `json:"id"`
+ State string `json:"state"`
+ WebURL string `json:"web_url"`
+ Name string `json:"name"`
+ AvatarURL string `json:"avatar_url"`
+ Username string `json:"username"`
} `json:"assignees"`
Assignee struct {
ID int `json:"id"`
- Name string `json:"name"`
- Username string `json:"username"`
State string `json:"state"`
- AvatarURL string `json:"avatar_url"`
WebURL string `json:"web_url"`
+ Name string `json:"name"`
+ AvatarURL string `json:"avatar_url"`
+ Username string `json:"username"`
} `json:"assignee"`
Upvotes int `json:"upvotes"`
Downvotes int `json:"downvotes"`
diff --git a/vendor/github.com/xanzy/go-gitlab/license.go b/vendor/github.com/xanzy/go-gitlab/license.go
new file mode 100644
index 00000000..746e99ae
--- /dev/null
+++ b/vendor/github.com/xanzy/go-gitlab/license.go
@@ -0,0 +1,94 @@
+//
+// Copyright 2018, Patrick Webster
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package gitlab
+
+// LicenseService handles communication with the license
+// related methods of the GitLab API.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/license.html
+type LicenseService struct {
+ client *Client
+}
+
+// License represents a GitLab license.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/license.html
+type License struct {
+ StartsAt *ISOTime `json:"starts_at"`
+ ExpiresAt *ISOTime `json:"expires_at"`
+ Licensee struct {
+ Name string `json:"Name"`
+ Company string `json:"Company"`
+ Email string `json:"Email"`
+ } `json:"licensee"`
+ UserLimit int `json:"user_limit"`
+ ActiveUsers int `json:"active_users"`
+ AddOns struct {
+ GitLabFileLocks int `json:"GitLabFileLocks"`
+ } `json:"add_ons"`
+}
+
+func (l License) String() string {
+ return Stringify(l)
+}
+
+// GetLicense retrieves information about the current license.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/license.html#retrieve-information-about-the-current-license
+func (s *LicenseService) GetLicense() (*License, *Response, error) {
+ req, err := s.client.NewRequest("GET", "license", nil, nil)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ l := new(License)
+ resp, err := s.client.Do(req, l)
+ if err != nil {
+ return nil, resp, err
+ }
+
+ return l, resp, err
+}
+
+// AddLicenseOptions represents the available AddLicense() options.
+//
+// https://docs.gitlab.com/ee/api/license.html#add-a-new-license
+type AddLicenseOptions struct {
+ License *string `url:"license" json:"license"`
+}
+
+// AddLicense adds a new license.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/license.html#add-a-new-license
+func (s *LicenseService) AddLicense(opt *AddLicenseOptions, options ...OptionFunc) (*License, *Response, error) {
+ req, err := s.client.NewRequest("POST", "license", opt, options)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ l := new(License)
+ resp, err := s.client.Do(req, l)
+ if err != nil {
+ return nil, resp, err
+ }
+
+ return l, resp, err
+}
diff --git a/vendor/github.com/xanzy/go-gitlab/merge_request_approvals.go b/vendor/github.com/xanzy/go-gitlab/merge_request_approvals.go
index 81aa4fb4..fdaf87cd 100644
--- a/vendor/github.com/xanzy/go-gitlab/merge_request_approvals.go
+++ b/vendor/github.com/xanzy/go-gitlab/merge_request_approvals.go
@@ -77,7 +77,7 @@ func (m MergeRequestApprovals) String() string {
// GitLab API docs:
// https://docs.gitlab.com/ee/api/merge_request_approvals.html#approve-merge-request
type ApproveMergeRequestOptions struct {
- Sha *string `url:"sha,omitempty" json:"sha,omitempty"`
+ SHA *string `url:"sha,omitempty" json:"sha,omitempty"`
}
// ApproveMergeRequest approves a merge request on GitLab. If a non-empty sha
@@ -92,7 +92,7 @@ func (s *MergeRequestApprovalsService) ApproveMergeRequest(pid interface{}, mr i
}
u := fmt.Sprintf("projects/%s/merge_requests/%d/approve", url.QueryEscape(project), mr)
- req, err := s.client.NewRequest("GET", u, opt, options)
+ req, err := s.client.NewRequest("POST", u, opt, options)
if err != nil {
return nil, nil, err
}
@@ -117,7 +117,7 @@ func (s *MergeRequestApprovalsService) UnapproveMergeRequest(pid interface{}, mr
}
u := fmt.Sprintf("projects/%s/merge_requests/%d/unapprove", url.QueryEscape(project), mr)
- req, err := s.client.NewRequest("GET", u, nil, options)
+ req, err := s.client.NewRequest("POST", u, nil, options)
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/xanzy/go-gitlab/projects.go b/vendor/github.com/xanzy/go-gitlab/projects.go
index 7afbd42b..901458ad 100644
--- a/vendor/github.com/xanzy/go-gitlab/projects.go
+++ b/vendor/github.com/xanzy/go-gitlab/projects.go
@@ -1026,3 +1026,149 @@ func (s *ProjectsService) ListProjectForks(pid interface{}, opt *ListProjectsOpt
return forks, resp, err
}
+
+// ProjectPushRules represents a project push rule.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/projects.html#push-rules
+type ProjectPushRules struct {
+ ID int `json:"id"`
+ ProjectID int `json:"project_id"`
+ CommitMessageRegex string `json:"commit_message_regex"`
+ BranchNameRegex string `json:"branch_name_regex"`
+ DenyDeleteTag bool `json:"deny_delete_tag"`
+ CreatedAt *time.Time `json:"created_at"`
+ MemberCheck bool `json:"member_check"`
+ PreventSecrets bool `json:"prevent_secrets"`
+ AuthorEmailRegex string `json:"author_email_regex"`
+ FileNameRegex string `json:"file_name_regex"`
+ MaxFileSize int `json:"max_file_size"`
+}
+
+// GetProjectPushRules gets the push rules of a project.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/projects.html#get-project-push-rules
+func (s *ProjectsService) GetProjectPushRules(pid interface{}, options ...OptionFunc) (*ProjectPushRules, *Response, error) {
+ project, err := parseID(pid)
+ if err != nil {
+ return nil, nil, err
+ }
+ u := fmt.Sprintf("projects/%s/push_rule", url.QueryEscape(project))
+
+ req, err := s.client.NewRequest("GET", u, nil, options)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ ppr := new(ProjectPushRules)
+ resp, err := s.client.Do(req, ppr)
+ if err != nil {
+ return nil, resp, err
+ }
+
+ return ppr, resp, err
+}
+
+// AddProjectPushRuleOptions represents the available AddProjectPushRule()
+// options.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/projects.html#add-project-push-rule
+type AddProjectPushRuleOptions struct {
+ DenyDeleteTag *bool `url:"deny_delete_tag,omitempty" json:"deny_delete_tag,omitempty"`
+ MemberCheck *bool `url:"member_check,omitempty" json:"member_check,omitempty"`
+ PreventSecrets *bool `url:"prevent_secrets,omitempty" json:"prevent_secrets,omitempty"`
+ CommitMessageRegex *string `url:"commit_message_regex,omitempty" json:"commit_message_regex,omitempty"`
+ BranchNameRegex *string `url:"branch_name_regex,omitempty" json:"branch_name_regex,omitempty"`
+ AuthorEmailRegex *string `url:"author_email_regex,omitempty" json:"author_email_regex,omitempty"`
+ FileNameRegex *string `url:"file_name_regex,omitempty" json:"file_name_regex,omitempty"`
+ MaxFileSize *int `url:"max_file_size,omitempty" json:"max_file_size,omitempty"`
+}
+
+// AddProjectPushRule adds a push rule to a specified project.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/projects.html#add-project-push-rule
+func (s *ProjectsService) AddProjectPushRule(pid interface{}, opt *AddProjectPushRuleOptions, options ...OptionFunc) (*ProjectPushRules, *Response, error) {
+ project, err := parseID(pid)
+ if err != nil {
+ return nil, nil, err
+ }
+ u := fmt.Sprintf("projects/%s/push_rule", url.QueryEscape(project))
+
+ req, err := s.client.NewRequest("POST", u, opt, options)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ ppr := new(ProjectPushRules)
+ resp, err := s.client.Do(req, ppr)
+ if err != nil {
+ return nil, resp, err
+ }
+
+ return ppr, resp, err
+}
+
+// EditProjectPushRuleOptions represents the available EditProjectPushRule()
+// options.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/projects.html#edit-project-push-rule
+type EditProjectPushRuleOptions struct {
+ AuthorEmailRegex *string `url:"author_email_regex,omitempty" json:"author_email_regex,omitempty"`
+ BranchNameRegex *string `url:"branch_name_regex,omitempty" json:"branch_name_regex,omitempty"`
+ CommitMessageRegex *string `url:"commit_message_regex,omitempty" json:"commit_message_regex,omitempty"`
+ FileNameRegex *string `url:"file_name_regex,omitempty" json:"file_name_regex,omitempty"`
+ DenyDeleteTag *bool `url:"deny_delete_tag,omitempty" json:"deny_delete_tag,omitempty"`
+ MemberCheck *bool `url:"member_check,omitempty" json:"member_check,omitempty"`
+ PreventSecrets *bool `url:"prevent_secrets,omitempty" json:"prevent_secrets,omitempty"`
+ MaxFileSize *int `url:"max_file_size,omitempty" json:"max_file_size,omitempty"`
+}
+
+// EditProjectPushRule edits a push rule for a specified project.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/projects.html#edit-project-push-rule
+func (s *ProjectsService) EditProjectPushRule(pid interface{}, opt *EditProjectPushRuleOptions, options ...OptionFunc) (*ProjectPushRules, *Response, error) {
+ project, err := parseID(pid)
+ if err != nil {
+ return nil, nil, err
+ }
+ u := fmt.Sprintf("projects/%s/push_rule", url.QueryEscape(project))
+
+ req, err := s.client.NewRequest("PUT", u, opt, options)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ ppr := new(ProjectPushRules)
+ resp, err := s.client.Do(req, ppr)
+ if err != nil {
+ return nil, resp, err
+ }
+
+ return ppr, resp, err
+}
+
+// DeleteProjectPushRule removes a push rule from a project. This is an
+// idempotent method and can be called multiple times. Either the push rule is
+// available or not.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/projects.html#delete-project-push-rule
+func (s *ProjectsService) DeleteProjectPushRule(pid interface{}, options ...OptionFunc) (*Response, error) {
+ project, err := parseID(pid)
+ if err != nil {
+ return nil, err
+ }
+ u := fmt.Sprintf("projects/%s/push_rule", url.QueryEscape(project))
+
+ req, err := s.client.NewRequest("DELETE", u, nil, options)
+ if err != nil {
+ return nil, err
+ }
+
+ return s.client.Do(req, nil)
+}
diff --git a/vendor/github.com/xanzy/go-gitlab/repositories.go b/vendor/github.com/xanzy/go-gitlab/repositories.go
index 01d767a8..d35f930c 100644
--- a/vendor/github.com/xanzy/go-gitlab/repositories.go
+++ b/vendor/github.com/xanzy/go-gitlab/repositories.go
@@ -230,8 +230,7 @@ func (c Contributor) String() string {
return Stringify(c)
}
-// ListContributorsOptions represents the available ListContributorsOptions()
-// options.
+// ListContributorsOptions represents the available ListContributors() options.
//
// GitLab API docs: https://docs.gitlab.com/ce/api/repositories.html#contributors
type ListContributorsOptions ListOptions
@@ -259,3 +258,37 @@ func (s *RepositoriesService) Contributors(pid interface{}, opt *ListContributor
return c, resp, err
}
+
+// MergeBaseOptions represents the available MergeBase() options.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ce/api/repositories.html#merge-base
+type MergeBaseOptions struct {
+ Ref []string `url:"refs[],omitempty" json:"refs,omitempty"`
+}
+
+// MergeBase gets the common ancestor for 2 refs (commit SHAs, branch
+// names or tags).
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ce/api/repositories.html#merge-base
+func (s *RepositoriesService) MergeBase(pid interface{}, opt *MergeBaseOptions, options ...OptionFunc) (*Commit, *Response, error) {
+ project, err := parseID(pid)
+ if err != nil {
+ return nil, nil, err
+ }
+ u := fmt.Sprintf("projects/%s/repository/merge_base", url.QueryEscape(project))
+
+ req, err := s.client.NewRequest("GET", u, opt, options)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ c := new(Commit)
+ resp, err := s.client.Do(req, c)
+ if err != nil {
+ return nil, resp, err
+ }
+
+ return c, resp, err
+}
diff --git a/vendor/github.com/xanzy/go-gitlab/repository_files.go b/vendor/github.com/xanzy/go-gitlab/repository_files.go
index cbfd4249..5e8ce419 100644
--- a/vendor/github.com/xanzy/go-gitlab/repository_files.go
+++ b/vendor/github.com/xanzy/go-gitlab/repository_files.go
@@ -20,6 +20,7 @@ import (
"bytes"
"fmt"
"net/url"
+ "strconv"
)
// RepositoryFilesService handles communication with the repository files
@@ -66,7 +67,11 @@ func (s *RepositoryFilesService) GetFile(pid interface{}, fileName string, opt *
if err != nil {
return nil, nil, err
}
- u := fmt.Sprintf("projects/%s/repository/files/%s", url.QueryEscape(project), url.PathEscape(fileName))
+ u := fmt.Sprintf(
+ "projects/%s/repository/files/%s",
+ url.QueryEscape(project),
+ url.PathEscape(fileName),
+ )
req, err := s.client.NewRequest("GET", u, opt, options)
if err != nil {
@@ -82,6 +87,59 @@ func (s *RepositoryFilesService) GetFile(pid interface{}, fileName string, opt *
return f, resp, err
}
+// GetFileMetaDataOptions represents the available GetFileMetaData() options.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ce/api/repository_files.html#get-file-from-repository
+type GetFileMetaDataOptions struct {
+ Ref *string `url:"ref,omitempty" json:"ref,omitempty"`
+}
+
+// GetFileMetaData allows you to receive meta information about a file in
+// repository like name, size.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ce/api/repository_files.html#get-file-from-repository
+func (s *RepositoryFilesService) GetFileMetaData(pid interface{}, fileName string, opt *GetFileMetaDataOptions, options ...OptionFunc) (*File, *Response, error) {
+ project, err := parseID(pid)
+ if err != nil {
+ return nil, nil, err
+ }
+ u := fmt.Sprintf(
+ "projects/%s/repository/files/%s",
+ url.QueryEscape(project),
+ url.PathEscape(fileName),
+ )
+
+ req, err := s.client.NewRequest("HEAD", u, opt, options)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ resp, err := s.client.Do(req, nil)
+ if err != nil {
+ return nil, resp, err
+ }
+
+ f := &File{
+ BlobID: resp.Header.Get("X-Gitlab-Blob-Id"),
+ CommitID: resp.Header.Get("X-Gitlab-Last-Commit-Id"),
+ Encoding: resp.Header.Get("X-Gitlab-Encoding"),
+ FileName: resp.Header.Get("X-Gitlab-File-Name"),
+ FilePath: resp.Header.Get("X-Gitlab-File-Path"),
+ Ref: resp.Header.Get("X-Gitlab-Ref"),
+ }
+
+ if sizeString := resp.Header.Get("X-Gitlab-Size"); sizeString != "" {
+ f.Size, err = strconv.Atoi(sizeString)
+ if err != nil {
+ return nil, resp, err
+ }
+ }
+
+ return f, resp, err
+}
+
// GetRawFileOptions represents the available GetRawFile() options.
//
// GitLab API docs:
@@ -99,7 +157,11 @@ func (s *RepositoryFilesService) GetRawFile(pid interface{}, fileName string, op
if err != nil {
return nil, nil, err
}
- u := fmt.Sprintf("projects/%s/repository/files/%s/raw", url.QueryEscape(project), url.PathEscape(fileName))
+ u := fmt.Sprintf(
+ "projects/%s/repository/files/%s/raw",
+ url.QueryEscape(project),
+ url.PathEscape(fileName),
+ )
req, err := s.client.NewRequest("GET", u, opt, options)
if err != nil {
@@ -149,7 +211,11 @@ func (s *RepositoryFilesService) CreateFile(pid interface{}, fileName string, op
if err != nil {
return nil, nil, err
}
- u := fmt.Sprintf("projects/%s/repository/files/%s", url.QueryEscape(project), url.PathEscape(fileName))
+ u := fmt.Sprintf(
+ "projects/%s/repository/files/%s",
+ url.QueryEscape(project),
+ url.PathEscape(fileName),
+ )
req, err := s.client.NewRequest("POST", u, opt, options)
if err != nil {
@@ -188,7 +254,11 @@ func (s *RepositoryFilesService) UpdateFile(pid interface{}, fileName string, op
if err != nil {
return nil, nil, err
}
- u := fmt.Sprintf("projects/%s/repository/files/%s", url.QueryEscape(project), url.PathEscape(fileName))
+ u := fmt.Sprintf(
+ "projects/%s/repository/files/%s",
+ url.QueryEscape(project),
+ url.PathEscape(fileName),
+ )
req, err := s.client.NewRequest("PUT", u, opt, options)
if err != nil {
@@ -224,7 +294,11 @@ func (s *RepositoryFilesService) DeleteFile(pid interface{}, fileName string, op
if err != nil {
return nil, err
}
- u := fmt.Sprintf("projects/%s/repository/files/%s", url.QueryEscape(project), url.PathEscape(fileName))
+ u := fmt.Sprintf(
+ "projects/%s/repository/files/%s",
+ url.QueryEscape(project),
+ url.PathEscape(fileName),
+ )
req, err := s.client.NewRequest("DELETE", u, opt, options)
if err != nil {
diff --git a/vendor/github.com/xanzy/go-gitlab/users.go b/vendor/github.com/xanzy/go-gitlab/users.go
index 1fed18c6..e11db03d 100644
--- a/vendor/github.com/xanzy/go-gitlab/users.go
+++ b/vendor/github.com/xanzy/go-gitlab/users.go
@@ -769,3 +769,81 @@ func (s *UsersService) GetUserActivities(opt *GetUserActivitiesOptions, options
return t, resp, err
}
+
+// UserStatus represents the current status of a user
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ce/api/users.html#user-status
+type UserStatus struct {
+ Emoji string `json:"emoji"`
+ Message string `json:"message"`
+ MessageHTML string `json:"message_html"`
+}
+
+// CurrentUserStatus retrieves the user status
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ce/api/users.html#user-status
+func (s *UsersService) CurrentUserStatus(options ...OptionFunc) (*UserStatus, *Response, error) {
+ req, err := s.client.NewRequest("GET", "user/status", nil, options)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ status := new(UserStatus)
+ resp, err := s.client.Do(req, status)
+ if err != nil {
+ return nil, resp, err
+ }
+
+ return status, resp, err
+}
+
+// GetUserStatus retrieves a user's status
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ce/api/users.html#get-the-status-of-a-user
+func (s *UsersService) GetUserStatus(user int, options ...OptionFunc) (*UserStatus, *Response, error) {
+ u := fmt.Sprintf("users/%d/status", user)
+
+ req, err := s.client.NewRequest("GET", u, nil, options)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ status := new(UserStatus)
+ resp, err := s.client.Do(req, status)
+ if err != nil {
+ return nil, resp, err
+ }
+
+ return status, resp, err
+}
+
+// UserStatusOptions represents the options required to set the status
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ce/api/users.html#set-user-status
+type UserStatusOptions struct {
+ Emoji *string `url:"emoji,omitempty" json:"emoji,omitempty"`
+ Message *string `url:"message,omitempty" json:"message,omitempty"`
+}
+
+// SetUserStatus sets the user's status
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ce/api/users.html#set-user-status
+func (s *UsersService) SetUserStatus(opt *UserStatusOptions, options ...OptionFunc) (*UserStatus, *Response, error) {
+ req, err := s.client.NewRequest("PUT", "user/status", opt, options)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ status := new(UserStatus)
+ resp, err := s.client.Do(req, status)
+ if err != nil {
+ return nil, resp, err
+ }
+
+ return status, resp, err
+}
diff --git a/vendor/github.com/zorkian/go-datadog-api/.travis.yml b/vendor/github.com/zorkian/go-datadog-api/.travis.yml
index e29d0fff..deecba41 100644
--- a/vendor/github.com/zorkian/go-datadog-api/.travis.yml
+++ b/vendor/github.com/zorkian/go-datadog-api/.travis.yml
@@ -1,10 +1,9 @@
language: go
go:
- - "1.7"
- - "1.8"
- "1.9"
- "1.10.x"
+ - "1.11.x"
- "tip"
env:
diff --git a/vendor/github.com/zorkian/go-datadog-api/datadog-accessors.go b/vendor/github.com/zorkian/go-datadog-api/datadog-accessors.go
index 415b3537..8a8f291d 100644
--- a/vendor/github.com/zorkian/go-datadog-api/datadog-accessors.go
+++ b/vendor/github.com/zorkian/go-datadog-api/datadog-accessors.go
@@ -5779,6 +5779,37 @@ func (o *Options) SetThresholds(v ThresholdCount) {
o.Thresholds = &v
}
+// GetThresholdWindows returns the ThresholdWindows field if non-nil, zero value otherwise.
+func (o *Options) GetThresholdWindows() ThresholdWindows {
+ if o == nil || o.ThresholdWindows == nil {
+ return ThresholdWindows{}
+ }
+ return *o.ThresholdWindows
+}
+
+// GetThresholdWindowsOk returns a tuple with the ThresholdWindows field if it's non-nil, zero value otherwise
+// and a boolean to check if the value has been set.
+func (o *Options) GetThresholdWindowsOk() (ThresholdWindows, bool) {
+ if o == nil || o.ThresholdWindows == nil {
+ return ThresholdWindows{}, false
+ }
+ return *o.ThresholdWindows, true
+}
+
+// HasThresholdWindows returns a boolean if a field has been set.
+func (o *Options) HasThresholdWindows() bool {
+ if o != nil && o.ThresholdWindows != nil {
+ return true
+ }
+
+ return false
+}
+
+// SetThresholdWindows allocates a new o.ThresholdWindows and returns the pointer to it.
+func (o *Options) SetThresholdWindows(v ThresholdWindows) {
+ o.ThresholdWindows = &v
+}
+
// GetTimeoutH returns the TimeoutH field if non-nil, zero value otherwise.
func (o *Options) GetTimeoutH() int {
if o == nil || o.TimeoutH == nil {
@@ -6338,18 +6369,18 @@ func (r *Rule) SetTimeframe(v string) {
}
// GetHeight returns the Height field if non-nil, zero value otherwise.
-func (s *Screenboard) GetHeight() string {
+func (s *Screenboard) GetHeight() int {
if s == nil || s.Height == nil {
- return ""
+ return 0
}
return *s.Height
}
// GetHeightOk returns a tuple with the Height field if it's non-nil, zero value otherwise
// and a boolean to check if the value has been set.
-func (s *Screenboard) GetHeightOk() (string, bool) {
+func (s *Screenboard) GetHeightOk() (int, bool) {
if s == nil || s.Height == nil {
- return "", false
+ return 0, false
}
return *s.Height, true
}
@@ -6364,7 +6395,7 @@ func (s *Screenboard) HasHeight() bool {
}
// SetHeight allocates a new s.Height and returns the pointer to it.
-func (s *Screenboard) SetHeight(v string) {
+func (s *Screenboard) SetHeight(v int) {
s.Height = &v
}
@@ -6493,18 +6524,18 @@ func (s *Screenboard) SetTitle(v string) {
}
// GetWidth returns the Width field if non-nil, zero value otherwise.
-func (s *Screenboard) GetWidth() string {
+func (s *Screenboard) GetWidth() int {
if s == nil || s.Width == nil {
- return ""
+ return 0
}
return *s.Width
}
// GetWidthOk returns a tuple with the Width field if it's non-nil, zero value otherwise
// and a boolean to check if the value has been set.
-func (s *Screenboard) GetWidthOk() (string, bool) {
+func (s *Screenboard) GetWidthOk() (int, bool) {
if s == nil || s.Width == nil {
- return "", false
+ return 0, false
}
return *s.Width, true
}
@@ -6519,7 +6550,7 @@ func (s *Screenboard) HasWidth() bool {
}
// SetWidth allocates a new s.Width and returns the pointer to it.
-func (s *Screenboard) SetWidth(v string) {
+func (s *Screenboard) SetWidth(v int) {
s.Width = &v
}
@@ -7546,6 +7577,68 @@ func (t *ThresholdCount) SetWarningRecovery(v json.Number) {
t.WarningRecovery = &v
}
+// GetRecoveryWindow returns the RecoveryWindow field if non-nil, zero value otherwise.
+func (t *ThresholdWindows) GetRecoveryWindow() string {
+ if t == nil || t.RecoveryWindow == nil {
+ return ""
+ }
+ return *t.RecoveryWindow
+}
+
+// GetRecoveryWindowOk returns a tuple with the RecoveryWindow field if it's non-nil, zero value otherwise
+// and a boolean to check if the value has been set.
+func (t *ThresholdWindows) GetRecoveryWindowOk() (string, bool) {
+ if t == nil || t.RecoveryWindow == nil {
+ return "", false
+ }
+ return *t.RecoveryWindow, true
+}
+
+// HasRecoveryWindow returns a boolean if a field has been set.
+func (t *ThresholdWindows) HasRecoveryWindow() bool {
+ if t != nil && t.RecoveryWindow != nil {
+ return true
+ }
+
+ return false
+}
+
+// SetRecoveryWindow allocates a new t.RecoveryWindow and returns the pointer to it.
+func (t *ThresholdWindows) SetRecoveryWindow(v string) {
+ t.RecoveryWindow = &v
+}
+
+// GetTriggerWindow returns the TriggerWindow field if non-nil, zero value otherwise.
+func (t *ThresholdWindows) GetTriggerWindow() string {
+ if t == nil || t.TriggerWindow == nil {
+ return ""
+ }
+ return *t.TriggerWindow
+}
+
+// GetTriggerWindowOk returns a tuple with the TriggerWindow field if it's non-nil, zero value otherwise
+// and a boolean to check if the value has been set.
+func (t *ThresholdWindows) GetTriggerWindowOk() (string, bool) {
+ if t == nil || t.TriggerWindow == nil {
+ return "", false
+ }
+ return *t.TriggerWindow, true
+}
+
+// HasTriggerWindow returns a boolean if a field has been set.
+func (t *ThresholdWindows) HasTriggerWindow() bool {
+ if t != nil && t.TriggerWindow != nil {
+ return true
+ }
+
+ return false
+}
+
+// SetTriggerWindow allocates a new t.TriggerWindow and returns the pointer to it.
+func (t *ThresholdWindows) SetTriggerWindow(v string) {
+ t.TriggerWindow = &v
+}
+
// GetAutoscale returns the Autoscale field if non-nil, zero value otherwise.
func (t *TileDef) GetAutoscale() bool {
if t == nil || t.Autoscale == nil {
diff --git a/vendor/github.com/zorkian/go-datadog-api/monitors.go b/vendor/github.com/zorkian/go-datadog-api/monitors.go
index f8a10c9d..2f6e2cc5 100644
--- a/vendor/github.com/zorkian/go-datadog-api/monitors.go
+++ b/vendor/github.com/zorkian/go-datadog-api/monitors.go
@@ -25,6 +25,11 @@ type ThresholdCount struct {
WarningRecovery *json.Number `json:"warning_recovery,omitempty"`
}
+type ThresholdWindows struct {
+ RecoveryWindow *string `json:"recovery_window,omitempty"`
+ TriggerWindow *string `json:"trigger_window,omitempty"`
+}
+
type NoDataTimeframe int
func (tf *NoDataTimeframe) UnmarshalJSON(data []byte) error {
@@ -42,19 +47,20 @@ func (tf *NoDataTimeframe) UnmarshalJSON(data []byte) error {
}
type Options struct {
- NoDataTimeframe NoDataTimeframe `json:"no_data_timeframe,omitempty"`
- NotifyAudit *bool `json:"notify_audit,omitempty"`
- NotifyNoData *bool `json:"notify_no_data,omitempty"`
- RenotifyInterval *int `json:"renotify_interval,omitempty"`
- NewHostDelay *int `json:"new_host_delay,omitempty"`
- EvaluationDelay *int `json:"evaluation_delay,omitempty"`
- Silenced map[string]int `json:"silenced,omitempty"`
- TimeoutH *int `json:"timeout_h,omitempty"`
- EscalationMessage *string `json:"escalation_message,omitempty"`
- Thresholds *ThresholdCount `json:"thresholds,omitempty"`
- IncludeTags *bool `json:"include_tags,omitempty"`
- RequireFullWindow *bool `json:"require_full_window,omitempty"`
- Locked *bool `json:"locked,omitempty"`
+ NoDataTimeframe NoDataTimeframe `json:"no_data_timeframe,omitempty"`
+ NotifyAudit *bool `json:"notify_audit,omitempty"`
+ NotifyNoData *bool `json:"notify_no_data,omitempty"`
+ RenotifyInterval *int `json:"renotify_interval,omitempty"`
+ NewHostDelay *int `json:"new_host_delay,omitempty"`
+ EvaluationDelay *int `json:"evaluation_delay,omitempty"`
+ Silenced map[string]int `json:"silenced,omitempty"`
+ TimeoutH *int `json:"timeout_h,omitempty"`
+ EscalationMessage *string `json:"escalation_message,omitempty"`
+ Thresholds *ThresholdCount `json:"thresholds,omitempty"`
+ ThresholdWindows *ThresholdWindows `json:"threshold_windows,omitempty"`
+ IncludeTags *bool `json:"include_tags,omitempty"`
+ RequireFullWindow *bool `json:"require_full_window,omitempty"`
+ Locked *bool `json:"locked,omitempty"`
}
type TriggeringValue struct {
diff --git a/vendor/github.com/zorkian/go-datadog-api/screen_widgets.go b/vendor/github.com/zorkian/go-datadog-api/screen_widgets.go
index d5c4d466..282e00e3 100644
--- a/vendor/github.com/zorkian/go-datadog-api/screen_widgets.go
+++ b/vendor/github.com/zorkian/go-datadog-api/screen_widgets.go
@@ -90,8 +90,8 @@ type Widget struct {
TitleSize *int `json:"title_size,omitempty"`
Height *int `json:"height,omitempty"`
Width *int `json:"width,omitempty"`
- X *int `json:"y,omitempty"`
- Y *int `json:"x,omitempty"`
+ X *int `json:"x,omitempty"`
+ Y *int `json:"y,omitempty"`
// For Timeseries, TopList, EventTimeline, EvenStream, AlertGraph, CheckStatus, ServiceSummary, LogStream widgets
Time *Time `json:"time,omitempty"`
diff --git a/vendor/github.com/zorkian/go-datadog-api/screenboards.go b/vendor/github.com/zorkian/go-datadog-api/screenboards.go
index 3bc52a5f..2786c962 100644
--- a/vendor/github.com/zorkian/go-datadog-api/screenboards.go
+++ b/vendor/github.com/zorkian/go-datadog-api/screenboards.go
@@ -17,8 +17,8 @@ import (
type Screenboard struct {
Id *int `json:"id,omitempty"`
Title *string `json:"board_title,omitempty"`
- Height *string `json:"height,omitempty"`
- Width *string `json:"width,omitempty"`
+ Height *int `json:"height,omitempty"`
+ Width *int `json:"width,omitempty"`
Shared *bool `json:"shared,omitempty"`
TemplateVariables []TemplateVariable `json:"template_variables,omitempty"`
Widgets []Widget `json:"widgets"`
diff --git a/vendor/golang.org/x/oauth2/README.md b/vendor/golang.org/x/oauth2/README.md
index eb8dcee1..68f436ed 100644
--- a/vendor/golang.org/x/oauth2/README.md
+++ b/vendor/golang.org/x/oauth2/README.md
@@ -24,7 +24,9 @@ See godoc for further documentation and examples.
In change 96e89be (March 2015), we removed the `oauth2.Context2` type in favor
of the [`context.Context`](https://golang.org/x/net/context#Context) type from
-the `golang.org/x/net/context` package
+the `golang.org/x/net/context` package. Later replaced by the standard `context` package
+of the [`context.Context`](https://golang.org/pkg/context#Context) type.
+
This means it's no longer possible to use the "Classic App Engine"
`appengine.Context` type with the `oauth2` package. (You're using
@@ -44,7 +46,7 @@ with the `oauth2` package.
```go
import (
- "golang.org/x/net/context"
+ "context"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
newappengine "google.golang.org/appengine"
@@ -68,6 +70,13 @@ func handler(w http.ResponseWriter, r *http.Request) {
}
```
+## Policy for new packages
+
+We no longer accept new provider-specific packages in this repo. For
+defining provider endpoints and provider-specific OAuth2 behavior, we
+encourage you to create packages elsewhere. We'll keep the existing
+packages for compatibility.
+
## Report Issues / Send Patches
This repository uses Gerrit for code changes. To learn how to submit changes to
diff --git a/vendor/golang.org/x/oauth2/google/appengine.go b/vendor/golang.org/x/oauth2/google/appengine.go
index 50d918b8..feb1157b 100644
--- a/vendor/golang.org/x/oauth2/google/appengine.go
+++ b/vendor/golang.org/x/oauth2/google/appengine.go
@@ -5,85 +5,34 @@
package google
import (
- "sort"
- "strings"
- "sync"
+ "context"
"time"
- "golang.org/x/net/context"
"golang.org/x/oauth2"
)
-// appengineFlex is set at init time by appengineflex_hook.go. If true, we are on App Engine Flex.
-var appengineFlex bool
-
-// Set at init time by appengine_hook.go. If nil, we're not on App Engine.
+// Set at init time by appengine_gen1.go. If nil, we're not on App Engine standard first generation (<= Go 1.9) or App Engine flexible.
var appengineTokenFunc func(c context.Context, scopes ...string) (token string, expiry time.Time, err error)
-// Set at init time by appengine_hook.go. If nil, we're not on App Engine.
+// Set at init time by appengine_gen1.go. If nil, we're not on App Engine standard first generation (<= Go 1.9) or App Engine flexible.
var appengineAppIDFunc func(c context.Context) string
-// AppEngineTokenSource returns a token source that fetches tokens
-// issued to the current App Engine application's service account.
-// If you are implementing a 3-legged OAuth 2.0 flow on App Engine
-// that involves user accounts, see oauth2.Config instead.
+// AppEngineTokenSource returns a token source that fetches tokens from either
+// the current application's service account or from the metadata server,
+// depending on the App Engine environment. See below for environment-specific
+// details. If you are implementing a 3-legged OAuth 2.0 flow on App Engine that
+// involves user accounts, see oauth2.Config instead.
//
-// The provided context must have come from appengine.NewContext.
+// First generation App Engine runtimes (<= Go 1.9):
+// AppEngineTokenSource returns a token source that fetches tokens issued to the
+// current App Engine application's service account. The provided context must have
+// come from appengine.NewContext.
+//
+// Second generation App Engine runtimes (>= Go 1.11) and App Engine flexible:
+// AppEngineTokenSource is DEPRECATED on second generation runtimes and on the
+// flexible environment. It delegates to ComputeTokenSource, and the provided
+// context and scopes are not used. Please use DefaultTokenSource (or ComputeTokenSource,
+// which DefaultTokenSource will use in this case) instead.
func AppEngineTokenSource(ctx context.Context, scope ...string) oauth2.TokenSource {
- if appengineTokenFunc == nil {
- panic("google: AppEngineTokenSource can only be used on App Engine.")
- }
- scopes := append([]string{}, scope...)
- sort.Strings(scopes)
- return &appEngineTokenSource{
- ctx: ctx,
- scopes: scopes,
- key: strings.Join(scopes, " "),
- }
-}
-
-// aeTokens helps the fetched tokens to be reused until their expiration.
-var (
- aeTokensMu sync.Mutex
- aeTokens = make(map[string]*tokenLock) // key is space-separated scopes
-)
-
-type tokenLock struct {
- mu sync.Mutex // guards t; held while fetching or updating t
- t *oauth2.Token
-}
-
-type appEngineTokenSource struct {
- ctx context.Context
- scopes []string
- key string // to aeTokens map; space-separated scopes
-}
-
-func (ts *appEngineTokenSource) Token() (*oauth2.Token, error) {
- if appengineTokenFunc == nil {
- panic("google: AppEngineTokenSource can only be used on App Engine.")
- }
-
- aeTokensMu.Lock()
- tok, ok := aeTokens[ts.key]
- if !ok {
- tok = &tokenLock{}
- aeTokens[ts.key] = tok
- }
- aeTokensMu.Unlock()
-
- tok.mu.Lock()
- defer tok.mu.Unlock()
- if tok.t.Valid() {
- return tok.t, nil
- }
- access, exp, err := appengineTokenFunc(ts.ctx, ts.scopes...)
- if err != nil {
- return nil, err
- }
- tok.t = &oauth2.Token{
- AccessToken: access,
- Expiry: exp,
- }
- return tok.t, nil
+ return appEngineTokenSource(ctx, scope...)
}
diff --git a/vendor/golang.org/x/oauth2/google/appengine_gen1.go b/vendor/golang.org/x/oauth2/google/appengine_gen1.go
new file mode 100644
index 00000000..83dacac3
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/google/appengine_gen1.go
@@ -0,0 +1,77 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build appengine
+
+// This file applies to App Engine first generation runtimes (<= Go 1.9).
+
+package google
+
+import (
+ "context"
+ "sort"
+ "strings"
+ "sync"
+
+ "golang.org/x/oauth2"
+ "google.golang.org/appengine"
+)
+
+func init() {
+ appengineTokenFunc = appengine.AccessToken
+ appengineAppIDFunc = appengine.AppID
+}
+
+// See comment on AppEngineTokenSource in appengine.go.
+func appEngineTokenSource(ctx context.Context, scope ...string) oauth2.TokenSource {
+ scopes := append([]string{}, scope...)
+ sort.Strings(scopes)
+ return &gaeTokenSource{
+ ctx: ctx,
+ scopes: scopes,
+ key: strings.Join(scopes, " "),
+ }
+}
+
+// aeTokens helps the fetched tokens to be reused until their expiration.
+var (
+ aeTokensMu sync.Mutex
+ aeTokens = make(map[string]*tokenLock) // key is space-separated scopes
+)
+
+type tokenLock struct {
+ mu sync.Mutex // guards t; held while fetching or updating t
+ t *oauth2.Token
+}
+
+type gaeTokenSource struct {
+ ctx context.Context
+ scopes []string
+ key string // to aeTokens map; space-separated scopes
+}
+
+func (ts *gaeTokenSource) Token() (*oauth2.Token, error) {
+ aeTokensMu.Lock()
+ tok, ok := aeTokens[ts.key]
+ if !ok {
+ tok = &tokenLock{}
+ aeTokens[ts.key] = tok
+ }
+ aeTokensMu.Unlock()
+
+ tok.mu.Lock()
+ defer tok.mu.Unlock()
+ if tok.t.Valid() {
+ return tok.t, nil
+ }
+ access, exp, err := appengineTokenFunc(ts.ctx, ts.scopes...)
+ if err != nil {
+ return nil, err
+ }
+ tok.t = &oauth2.Token{
+ AccessToken: access,
+ Expiry: exp,
+ }
+ return tok.t, nil
+}
diff --git a/vendor/golang.org/x/oauth2/google/appengine_gen2_flex.go b/vendor/golang.org/x/oauth2/google/appengine_gen2_flex.go
new file mode 100644
index 00000000..04c2c221
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/google/appengine_gen2_flex.go
@@ -0,0 +1,27 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !appengine
+
+// This file applies to App Engine second generation runtimes (>= Go 1.11) and App Engine flexible.
+
+package google
+
+import (
+ "context"
+ "log"
+ "sync"
+
+ "golang.org/x/oauth2"
+)
+
+var logOnce sync.Once // only spam about deprecation once
+
+// See comment on AppEngineTokenSource in appengine.go.
+func appEngineTokenSource(ctx context.Context, scope ...string) oauth2.TokenSource {
+ logOnce.Do(func() {
+ log.Print("google: AppEngineTokenSource is deprecated on App Engine standard second generation runtimes (>= Go 1.11) and App Engine flexible. Please use DefaultTokenSource or ComputeTokenSource.")
+ })
+ return ComputeTokenSource("")
+}
diff --git a/vendor/golang.org/x/oauth2/google/appengine_hook.go b/vendor/golang.org/x/oauth2/google/appengine_hook.go
deleted file mode 100644
index 56669eaa..00000000
--- a/vendor/golang.org/x/oauth2/google/appengine_hook.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build appengine appenginevm
-
-package google
-
-import "google.golang.org/appengine"
-
-func init() {
- appengineTokenFunc = appengine.AccessToken
- appengineAppIDFunc = appengine.AppID
-}
diff --git a/vendor/golang.org/x/oauth2/google/appengineflex_hook.go b/vendor/golang.org/x/oauth2/google/appengineflex_hook.go
deleted file mode 100644
index 5d0231af..00000000
--- a/vendor/golang.org/x/oauth2/google/appengineflex_hook.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build appenginevm
-
-package google
-
-func init() {
- appengineFlex = true // Flex doesn't support appengine.AccessToken; depend on metadata server.
-}
diff --git a/vendor/golang.org/x/oauth2/google/default.go b/vendor/golang.org/x/oauth2/google/default.go
index a3160743..5087d845 100644
--- a/vendor/golang.org/x/oauth2/google/default.go
+++ b/vendor/golang.org/x/oauth2/google/default.go
@@ -5,6 +5,7 @@
package google
import (
+ "context"
"encoding/json"
"fmt"
"io/ioutil"
@@ -14,10 +15,28 @@ import (
"runtime"
"cloud.google.com/go/compute/metadata"
- "golang.org/x/net/context"
"golang.org/x/oauth2"
)
+// Credentials holds Google credentials, including "Application Default Credentials".
+// For more details, see:
+// https://developers.google.com/accounts/docs/application-default-credentials
+type Credentials struct {
+ ProjectID string // may be empty
+ TokenSource oauth2.TokenSource
+
+ // JSON contains the raw bytes from a JSON credentials file.
+ // This field may be nil if authentication is provided by the
+ // environment and not with a credentials file, e.g. when code is
+ // running on Google Cloud Platform.
+ JSON []byte
+}
+
+// DefaultCredentials is the old name of Credentials.
+//
+// Deprecated: use Credentials instead.
+type DefaultCredentials = Credentials
+
// DefaultClient returns an HTTP Client that uses the
// DefaultTokenSource to obtain authentication credentials.
func DefaultClient(ctx context.Context, scope ...string) (*http.Client, error) {
@@ -39,8 +58,23 @@ func DefaultTokenSource(ctx context.Context, scope ...string) (oauth2.TokenSourc
return creds.TokenSource, nil
}
-// Common implementation for FindDefaultCredentials.
-func findDefaultCredentials(ctx context.Context, scopes []string) (*DefaultCredentials, error) {
+// FindDefaultCredentials searches for "Application Default Credentials".
+//
+// It looks for credentials in the following places,
+// preferring the first location found:
+//
+// 1. A JSON file whose path is specified by the
+// GOOGLE_APPLICATION_CREDENTIALS environment variable.
+// 2. A JSON file in a location known to the gcloud command-line tool.
+// On Windows, this is %APPDATA%/gcloud/application_default_credentials.json.
+// On other systems, $HOME/.config/gcloud/application_default_credentials.json.
+// 3. On Google App Engine standard first generation runtimes (<= Go 1.9) it uses
+// the appengine.AccessToken function.
+// 4. On Google Compute Engine, Google App Engine standard second generation runtimes
+// (>= Go 1.11), and Google App Engine flexible environment, it fetches
+// credentials from the metadata server.
+// (In this final case any provided scopes are ignored.)
+func FindDefaultCredentials(ctx context.Context, scopes ...string) (*Credentials, error) {
// First, try the environment variable.
const envVar = "GOOGLE_APPLICATION_CREDENTIALS"
if filename := os.Getenv(envVar); filename != "" {
@@ -59,15 +93,18 @@ func findDefaultCredentials(ctx context.Context, scopes []string) (*DefaultCrede
return nil, fmt.Errorf("google: error getting credentials using well-known file (%v): %v", filename, err)
}
- // Third, if we're on Google App Engine use those credentials.
- if appengineTokenFunc != nil && !appengineFlex {
+ // Third, if we're on a Google App Engine standard first generation runtime (<= Go 1.9)
+ // use those credentials. App Engine standard second generation runtimes (>= Go 1.11)
+ // and App Engine flexible use ComputeTokenSource and the metadata server.
+ if appengineTokenFunc != nil {
return &DefaultCredentials{
ProjectID: appengineAppIDFunc(ctx),
TokenSource: AppEngineTokenSource(ctx, scopes...),
}, nil
}
- // Fourth, if we're on Google Compute Engine use the metadata server.
+ // Fourth, if we're on Google Compute Engine, an App Engine standard second generation runtime,
+ // or App Engine flexible, use the metadata server.
if metadata.OnGCE() {
id, _ := metadata.ProjectID()
return &DefaultCredentials{
@@ -81,8 +118,11 @@ func findDefaultCredentials(ctx context.Context, scopes []string) (*DefaultCrede
return nil, fmt.Errorf("google: could not find default credentials. See %v for more information.", url)
}
-// Common implementation for CredentialsFromJSON.
-func credentialsFromJSON(ctx context.Context, jsonData []byte, scopes []string) (*DefaultCredentials, error) {
+// CredentialsFromJSON obtains Google credentials from a JSON value. The JSON can
+// represent either a Google Developers Console client_credentials.json file (as in
+// ConfigFromJSON) or a Google Developers service account key file (as in
+// JWTConfigFromJSON).
+func CredentialsFromJSON(ctx context.Context, jsonData []byte, scopes ...string) (*Credentials, error) {
var f credentialsFile
if err := json.Unmarshal(jsonData, &f); err != nil {
return nil, err
diff --git a/vendor/golang.org/x/oauth2/google/doc_go19.go b/vendor/golang.org/x/oauth2/google/doc.go
similarity index 99%
rename from vendor/golang.org/x/oauth2/google/doc_go19.go
rename to vendor/golang.org/x/oauth2/google/doc.go
index 2a86325f..73be6290 100644
--- a/vendor/golang.org/x/oauth2/google/doc_go19.go
+++ b/vendor/golang.org/x/oauth2/google/doc.go
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build go1.9
-
// Package google provides support for making OAuth2 authorized and authenticated
// HTTP requests to Google APIs. It supports the Web server flow, client-side
// credentials, service accounts, Google Compute Engine service accounts, and Google
diff --git a/vendor/golang.org/x/oauth2/google/doc_not_go19.go b/vendor/golang.org/x/oauth2/google/doc_not_go19.go
deleted file mode 100644
index 5c3c6e14..00000000
--- a/vendor/golang.org/x/oauth2/google/doc_not_go19.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !go1.9
-
-// Package google provides support for making OAuth2 authorized and authenticated
-// HTTP requests to Google APIs. It supports the Web server flow, client-side
-// credentials, service accounts, Google Compute Engine service accounts, and Google
-// App Engine service accounts.
-//
-// A brief overview of the package follows. For more information, please read
-// https://developers.google.com/accounts/docs/OAuth2
-// and
-// https://developers.google.com/accounts/docs/application-default-credentials.
-//
-// OAuth2 Configs
-//
-// Two functions in this package return golang.org/x/oauth2.Config values from Google credential
-// data. Google supports two JSON formats for OAuth2 credentials: one is handled by ConfigFromJSON,
-// the other by JWTConfigFromJSON. The returned Config can be used to obtain a TokenSource or
-// create an http.Client.
-//
-//
-// Credentials
-//
-// The DefaultCredentials type represents Google Application Default Credentials, as
-// well as other forms of credential.
-//
-// Use FindDefaultCredentials to obtain Application Default Credentials.
-// FindDefaultCredentials looks in some well-known places for a credentials file, and
-// will call AppEngineTokenSource or ComputeTokenSource as needed.
-//
-// DefaultClient and DefaultTokenSource are convenience methods. They first call FindDefaultCredentials,
-// then use the credentials to construct an http.Client or an oauth2.TokenSource.
-//
-// Use CredentialsFromJSON to obtain credentials from either of the two JSON
-// formats described in OAuth2 Configs, above. (The DefaultCredentials returned may
-// not be "Application Default Credentials".) The TokenSource in the returned value
-// is the same as the one obtained from the oauth2.Config returned from
-// ConfigFromJSON or JWTConfigFromJSON, but the DefaultCredentials may contain
-// additional information that is useful is some circumstances.
-package google // import "golang.org/x/oauth2/google"
diff --git a/vendor/golang.org/x/oauth2/google/go19.go b/vendor/golang.org/x/oauth2/google/go19.go
deleted file mode 100644
index 4d0318b1..00000000
--- a/vendor/golang.org/x/oauth2/google/go19.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.9
-
-package google
-
-import (
- "golang.org/x/net/context"
- "golang.org/x/oauth2"
-)
-
-// Credentials holds Google credentials, including "Application Default Credentials".
-// For more details, see:
-// https://developers.google.com/accounts/docs/application-default-credentials
-type Credentials struct {
- ProjectID string // may be empty
- TokenSource oauth2.TokenSource
-
- // JSON contains the raw bytes from a JSON credentials file.
- // This field may be nil if authentication is provided by the
- // environment and not with a credentials file, e.g. when code is
- // running on Google Cloud Platform.
- JSON []byte
-}
-
-// DefaultCredentials is the old name of Credentials.
-//
-// Deprecated: use Credentials instead.
-type DefaultCredentials = Credentials
-
-// FindDefaultCredentials searches for "Application Default Credentials".
-//
-// It looks for credentials in the following places,
-// preferring the first location found:
-//
-// 1. A JSON file whose path is specified by the
-// GOOGLE_APPLICATION_CREDENTIALS environment variable.
-// 2. A JSON file in a location known to the gcloud command-line tool.
-// On Windows, this is %APPDATA%/gcloud/application_default_credentials.json.
-// On other systems, $HOME/.config/gcloud/application_default_credentials.json.
-// 3. On Google App Engine it uses the appengine.AccessToken function.
-// 4. On Google Compute Engine and Google App Engine Managed VMs, it fetches
-// credentials from the metadata server.
-// (In this final case any provided scopes are ignored.)
-func FindDefaultCredentials(ctx context.Context, scopes ...string) (*Credentials, error) {
- return findDefaultCredentials(ctx, scopes)
-}
-
-// CredentialsFromJSON obtains Google credentials from a JSON value. The JSON can
-// represent either a Google Developers Console client_credentials.json file (as in
-// ConfigFromJSON) or a Google Developers service account key file (as in
-// JWTConfigFromJSON).
-func CredentialsFromJSON(ctx context.Context, jsonData []byte, scopes ...string) (*Credentials, error) {
- return credentialsFromJSON(ctx, jsonData, scopes)
-}
diff --git a/vendor/golang.org/x/oauth2/google/google.go b/vendor/golang.org/x/oauth2/google/google.go
index f7481fbc..ca7d208d 100644
--- a/vendor/golang.org/x/oauth2/google/google.go
+++ b/vendor/golang.org/x/oauth2/google/google.go
@@ -5,6 +5,7 @@
package google
import (
+ "context"
"encoding/json"
"errors"
"fmt"
@@ -12,7 +13,6 @@ import (
"time"
"cloud.google.com/go/compute/metadata"
- "golang.org/x/net/context"
"golang.org/x/oauth2"
"golang.org/x/oauth2/jwt"
)
diff --git a/vendor/golang.org/x/oauth2/google/not_go19.go b/vendor/golang.org/x/oauth2/google/not_go19.go
deleted file mode 100644
index 544e4062..00000000
--- a/vendor/golang.org/x/oauth2/google/not_go19.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !go1.9
-
-package google
-
-import (
- "golang.org/x/net/context"
- "golang.org/x/oauth2"
-)
-
-// DefaultCredentials holds Google credentials, including "Application Default Credentials".
-// For more details, see:
-// https://developers.google.com/accounts/docs/application-default-credentials
-type DefaultCredentials struct {
- ProjectID string // may be empty
- TokenSource oauth2.TokenSource
-
- // JSON contains the raw bytes from a JSON credentials file.
- // This field may be nil if authentication is provided by the
- // environment and not with a credentials file, e.g. when code is
- // running on Google Cloud Platform.
- JSON []byte
-}
-
-// FindDefaultCredentials searches for "Application Default Credentials".
-//
-// It looks for credentials in the following places,
-// preferring the first location found:
-//
-// 1. A JSON file whose path is specified by the
-// GOOGLE_APPLICATION_CREDENTIALS environment variable.
-// 2. A JSON file in a location known to the gcloud command-line tool.
-// On Windows, this is %APPDATA%/gcloud/application_default_credentials.json.
-// On other systems, $HOME/.config/gcloud/application_default_credentials.json.
-// 3. On Google App Engine it uses the appengine.AccessToken function.
-// 4. On Google Compute Engine and Google App Engine Managed VMs, it fetches
-// credentials from the metadata server.
-// (In this final case any provided scopes are ignored.)
-func FindDefaultCredentials(ctx context.Context, scopes ...string) (*DefaultCredentials, error) {
- return findDefaultCredentials(ctx, scopes)
-}
-
-// CredentialsFromJSON obtains Google credentials from a JSON value. The JSON can
-// represent either a Google Developers Console client_credentials.json file (as in
-// ConfigFromJSON) or a Google Developers service account key file (as in
-// JWTConfigFromJSON).
-//
-// Note: despite the name, the returned credentials may not be Application Default Credentials.
-func CredentialsFromJSON(ctx context.Context, jsonData []byte, scopes ...string) (*DefaultCredentials, error) {
- return credentialsFromJSON(ctx, jsonData, scopes)
-}
diff --git a/vendor/golang.org/x/oauth2/google/sdk.go b/vendor/golang.org/x/oauth2/google/sdk.go
index b9660cad..456224bc 100644
--- a/vendor/golang.org/x/oauth2/google/sdk.go
+++ b/vendor/golang.org/x/oauth2/google/sdk.go
@@ -6,6 +6,7 @@ package google
import (
"bufio"
+ "context"
"encoding/json"
"errors"
"fmt"
@@ -18,7 +19,6 @@ import (
"strings"
"time"
- "golang.org/x/net/context"
"golang.org/x/oauth2"
)
diff --git a/vendor/golang.org/x/oauth2/internal/oauth2.go b/vendor/golang.org/x/oauth2/internal/oauth2.go
index fc63fcab..c0ab196c 100644
--- a/vendor/golang.org/x/oauth2/internal/oauth2.go
+++ b/vendor/golang.org/x/oauth2/internal/oauth2.go
@@ -26,7 +26,7 @@ func ParseKey(key []byte) (*rsa.PrivateKey, error) {
if err != nil {
parsedKey, err = x509.ParsePKCS1PrivateKey(key)
if err != nil {
- return nil, fmt.Errorf("private key should be a PEM or plain PKSC1 or PKCS8; parse error: %v", err)
+ return nil, fmt.Errorf("private key should be a PEM or plain PKCS1 or PKCS8; parse error: %v", err)
}
}
parsed, ok := parsedKey.(*rsa.PrivateKey)
diff --git a/vendor/golang.org/x/oauth2/internal/token.go b/vendor/golang.org/x/oauth2/internal/token.go
index 53259a41..5ab17b9a 100644
--- a/vendor/golang.org/x/oauth2/internal/token.go
+++ b/vendor/golang.org/x/oauth2/internal/token.go
@@ -5,6 +5,7 @@
package internal
import (
+ "context"
"encoding/json"
"errors"
"fmt"
@@ -17,7 +18,6 @@ import (
"strings"
"time"
- "golang.org/x/net/context"
"golang.org/x/net/context/ctxhttp"
)
diff --git a/vendor/golang.org/x/oauth2/internal/transport.go b/vendor/golang.org/x/oauth2/internal/transport.go
index d16f9ae1..572074a6 100644
--- a/vendor/golang.org/x/oauth2/internal/transport.go
+++ b/vendor/golang.org/x/oauth2/internal/transport.go
@@ -5,9 +5,8 @@
package internal
import (
+ "context"
"net/http"
-
- "golang.org/x/net/context"
)
// HTTPClient is the context key to use with golang.org/x/net/context's
diff --git a/vendor/golang.org/x/oauth2/jwt/jwt.go b/vendor/golang.org/x/oauth2/jwt/jwt.go
index e08f3159..0783a94c 100644
--- a/vendor/golang.org/x/oauth2/jwt/jwt.go
+++ b/vendor/golang.org/x/oauth2/jwt/jwt.go
@@ -9,6 +9,7 @@
package jwt
import (
+ "context"
"encoding/json"
"fmt"
"io"
@@ -18,7 +19,6 @@ import (
"strings"
"time"
- "golang.org/x/net/context"
"golang.org/x/oauth2"
"golang.org/x/oauth2/internal"
"golang.org/x/oauth2/jws"
diff --git a/vendor/golang.org/x/oauth2/oauth2.go b/vendor/golang.org/x/oauth2/oauth2.go
index 16775d08..1e8e1b74 100644
--- a/vendor/golang.org/x/oauth2/oauth2.go
+++ b/vendor/golang.org/x/oauth2/oauth2.go
@@ -10,13 +10,13 @@ package oauth2 // import "golang.org/x/oauth2"
import (
"bytes"
+ "context"
"errors"
"net/http"
"net/url"
"strings"
"sync"
- "golang.org/x/net/context"
"golang.org/x/oauth2/internal"
)
@@ -164,8 +164,7 @@ func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string {
// and when other authorization grant types are not available."
// See https://tools.ietf.org/html/rfc6749#section-4.3 for more info.
//
-// The HTTP client to use is derived from the context.
-// If nil, http.DefaultClient is used.
+// The provided context optionally controls which HTTP client is used. See the HTTPClient variable.
func (c *Config) PasswordCredentialsToken(ctx context.Context, username, password string) (*Token, error) {
v := url.Values{
"grant_type": {"password"},
@@ -183,8 +182,7 @@ func (c *Config) PasswordCredentialsToken(ctx context.Context, username, passwor
// It is used after a resource provider redirects the user back
// to the Redirect URI (the URL obtained from AuthCodeURL).
//
-// The HTTP client to use is derived from the context.
-// If a client is not provided via the context, http.DefaultClient is used.
+// The provided context optionally controls which HTTP client is used. See the HTTPClient variable.
//
// The code will be in the *http.Request.FormValue("code"). Before
// calling Exchange, be sure to validate FormValue("state").
diff --git a/vendor/golang.org/x/oauth2/token.go b/vendor/golang.org/x/oauth2/token.go
index 34db8cdc..9be1ae53 100644
--- a/vendor/golang.org/x/oauth2/token.go
+++ b/vendor/golang.org/x/oauth2/token.go
@@ -5,6 +5,7 @@
package oauth2
import (
+ "context"
"fmt"
"net/http"
"net/url"
@@ -12,7 +13,6 @@ import (
"strings"
"time"
- "golang.org/x/net/context"
"golang.org/x/oauth2/internal"
)
diff --git a/vendor/google.golang.org/api/calendar/v3/calendar-api.json b/vendor/google.golang.org/api/calendar/v3/calendar-api.json
index 0aab2d09..83f735e4 100644
--- a/vendor/google.golang.org/api/calendar/v3/calendar-api.json
+++ b/vendor/google.golang.org/api/calendar/v3/calendar-api.json
@@ -3,7 +3,7 @@
"oauth2": {
"scopes": {
"https://www.googleapis.com/auth/calendar": {
- "description": "Manage your calendars"
+ "description": "See, edit, share, and permanently delete all the calendars you can access using Google Calendar"
},
"https://www.googleapis.com/auth/calendar.events": {
"description": "View and edit events on all your calendars"
@@ -26,7 +26,7 @@
"description": "Manipulates events and other calendar data.",
"discoveryVersion": "v1",
"documentationLink": "https://developers.google.com/google-apps/calendar/firstapp",
- "etag": "\"J3WqvAcMk4eQjJXvfSI4Yr8VouA/HcEmuhTEJ15i1AnuK6mgjI8kmMs\"",
+ "etag": "\"J3WqvAcMk4eQjJXvfSI4Yr8VouA/7shFmGJYOQm8lYcU7swGRcnQGuU\"",
"icons": {
"x16": "http://www.google.com/images/icons/product/calendar-16.png",
"x32": "http://www.google.com/images/icons/product/calendar-32.png"
@@ -1724,7 +1724,7 @@
}
}
},
- "revision": "20181002",
+ "revision": "20181023",
"rootUrl": "https://www.googleapis.com/",
"schemas": {
"Acl": {
diff --git a/vendor/google.golang.org/api/calendar/v3/calendar-gen.go b/vendor/google.golang.org/api/calendar/v3/calendar-gen.go
index 19c8015e..e51619c8 100644
--- a/vendor/google.golang.org/api/calendar/v3/calendar-gen.go
+++ b/vendor/google.golang.org/api/calendar/v3/calendar-gen.go
@@ -11,18 +11,18 @@ package calendar // import "google.golang.org/api/calendar/v3"
import (
"bytes"
+ "context"
"encoding/json"
"errors"
"fmt"
- context "golang.org/x/net/context"
- ctxhttp "golang.org/x/net/context/ctxhttp"
- gensupport "google.golang.org/api/gensupport"
- googleapi "google.golang.org/api/googleapi"
"io"
"net/http"
"net/url"
"strconv"
"strings"
+
+ gensupport "google.golang.org/api/gensupport"
+ googleapi "google.golang.org/api/googleapi"
)
// Always reference these packages, just in case the auto-generated code
@@ -38,7 +38,6 @@ var _ = googleapi.Version
var _ = errors.New
var _ = strings.Replace
var _ = context.Canceled
-var _ = ctxhttp.Do
const apiId = "calendar:v3"
const apiName = "calendar"
@@ -47,7 +46,8 @@ const basePath = "https://www.googleapis.com/calendar/v3/"
// OAuth2 scopes used by this API.
const (
- // Manage your calendars
+ // See, edit, share, and permanently delete all the calendars you can
+ // access using Google Calendar
CalendarScope = "https://www.googleapis.com/auth/calendar"
// View and edit events on all your calendars
diff --git a/vendor/google.golang.org/api/gensupport/resumable.go b/vendor/google.golang.org/api/gensupport/resumable.go
index dcd591f7..2552a6ac 100644
--- a/vendor/google.golang.org/api/gensupport/resumable.go
+++ b/vendor/google.golang.org/api/gensupport/resumable.go
@@ -5,14 +5,13 @@
package gensupport
import (
+ "context"
"errors"
"fmt"
"io"
"net/http"
"sync"
"time"
-
- "golang.org/x/net/context"
)
const (
diff --git a/vendor/google.golang.org/api/gensupport/retry.go b/vendor/google.golang.org/api/gensupport/retry.go
index e58c75e4..fdde3f42 100644
--- a/vendor/google.golang.org/api/gensupport/retry.go
+++ b/vendor/google.golang.org/api/gensupport/retry.go
@@ -15,12 +15,11 @@
package gensupport
import (
+ "context"
"io"
"net"
"net/http"
"time"
-
- "golang.org/x/net/context"
)
// Retry invokes the given function, retrying it multiple times if the connection failed or
diff --git a/vendor/google.golang.org/api/gensupport/send.go b/vendor/google.golang.org/api/gensupport/send.go
index 0f75aa86..57993930 100644
--- a/vendor/google.golang.org/api/gensupport/send.go
+++ b/vendor/google.golang.org/api/gensupport/send.go
@@ -5,12 +5,10 @@
package gensupport
import (
+ "context"
"encoding/json"
"errors"
"net/http"
-
- "golang.org/x/net/context"
- "golang.org/x/net/context/ctxhttp"
)
// Hook is the type of a function that is called once before each HTTP request
@@ -32,7 +30,8 @@ func RegisterHook(h Hook) {
// SendRequest sends a single HTTP request using the given client.
// If ctx is non-nil, it calls all hooks, then sends the request with
-// ctxhttp.Do, then calls any functions returned by the hooks in reverse order.
+// req.WithContext, then calls any functions returned by the hooks in
+// reverse order.
func SendRequest(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) {
// Disallow Accept-Encoding because it interferes with the automatic gzip handling
// done by the default http.Transport. See https://github.com/google/google-api-go-client/issues/219.
@@ -50,7 +49,7 @@ func SendRequest(ctx context.Context, client *http.Client, req *http.Request) (*
}
// Send request.
- resp, err := ctxhttp.Do(ctx, client, req)
+ resp, err := send(ctx, client, req)
// Call returned funcs in reverse order.
for i := len(post) - 1; i >= 0; i-- {
@@ -61,6 +60,23 @@ func SendRequest(ctx context.Context, client *http.Client, req *http.Request) (*
return resp, err
}
+func send(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) {
+ if client == nil {
+ client = http.DefaultClient
+ }
+ resp, err := client.Do(req.WithContext(ctx))
+ // If we got an error, and the context has been canceled,
+ // the context's error is probably more useful.
+ if err != nil {
+ select {
+ case <-ctx.Done():
+ err = ctx.Err()
+ default:
+ }
+ }
+ return resp, err
+}
+
// DecodeResponse decodes the body of res into target. If there is no body,
// target is unchanged.
func DecodeResponse(target interface{}, res *http.Response) error {
diff --git a/vendor/google.golang.org/api/sheets/v4/sheets-gen.go b/vendor/google.golang.org/api/sheets/v4/sheets-gen.go
index 2e3172d8..d5367d3a 100644
--- a/vendor/google.golang.org/api/sheets/v4/sheets-gen.go
+++ b/vendor/google.golang.org/api/sheets/v4/sheets-gen.go
@@ -11,18 +11,18 @@ package sheets // import "google.golang.org/api/sheets/v4"
import (
"bytes"
+ "context"
"encoding/json"
"errors"
"fmt"
- context "golang.org/x/net/context"
- ctxhttp "golang.org/x/net/context/ctxhttp"
- gensupport "google.golang.org/api/gensupport"
- googleapi "google.golang.org/api/googleapi"
"io"
"net/http"
"net/url"
"strconv"
"strings"
+
+ gensupport "google.golang.org/api/gensupport"
+ googleapi "google.golang.org/api/googleapi"
)
// Always reference these packages, just in case the auto-generated code
@@ -38,7 +38,6 @@ var _ = googleapi.Version
var _ = errors.New
var _ = strings.Replace
var _ = context.Canceled
-var _ = ctxhttp.Do
const apiId = "sheets:v4"
const apiName = "sheets"
diff --git a/vendor/google.golang.org/appengine/.travis.yml b/vendor/google.golang.org/appengine/.travis.yml
index 7ef8b6c7..70ffe89d 100644
--- a/vendor/google.golang.org/appengine/.travis.yml
+++ b/vendor/google.golang.org/appengine/.travis.yml
@@ -1,24 +1,20 @@
language: go
-go:
- - 1.6.x
- - 1.7.x
- - 1.8.x
- - 1.9.x
-
go_import_path: google.golang.org/appengine
install:
- - go get -u -v $(go list -f '{{join .Imports "\n"}}{{"\n"}}{{join .TestImports "\n"}}' ./... | sort | uniq | grep -v appengine)
- - mkdir /tmp/sdk
- - curl -o /tmp/sdk.zip "https://storage.googleapis.com/appengine-sdks/featured/go_appengine_sdk_linux_amd64-1.9.40.zip"
- - unzip -q /tmp/sdk.zip -d /tmp/sdk
- - export PATH="$PATH:/tmp/sdk/go_appengine"
- - export APPENGINE_DEV_APPSERVER=/tmp/sdk/go_appengine/dev_appserver.py
+ - ./travis_install.sh
script:
- - goapp version
- - go version
- - go test -v google.golang.org/appengine/...
- - go test -v -race google.golang.org/appengine/...
- - goapp test -v google.golang.org/appengine/...
+ - ./travis_test.sh
+
+matrix:
+ include:
+ - go: 1.8.x
+ env: GOAPP=true
+ - go: 1.9.x
+ env: GOAPP=true
+ - go: 1.10.x
+ env: GOAPP=false
+ - go: 1.11.x
+ env: GO111MODULE=on
diff --git a/vendor/google.golang.org/appengine/appengine.go b/vendor/google.golang.org/appengine/appengine.go
index 76dedc81..79525454 100644
--- a/vendor/google.golang.org/appengine/appengine.go
+++ b/vendor/google.golang.org/appengine/appengine.go
@@ -60,6 +60,24 @@ func IsDevAppServer() bool {
return internal.IsDevAppServer()
}
+// IsStandard reports whether the App Engine app is running in the standard
+// environment. This includes both the first generation runtimes (<= Go 1.9)
+// and the second generation runtimes (>= Go 1.11).
+func IsStandard() bool {
+ return internal.IsStandard()
+}
+
+// IsFlex reports whether the App Engine app is running in the flexible environment.
+func IsFlex() bool {
+ return internal.IsFlex()
+}
+
+// IsAppEngine reports whether the App Engine app is running on App Engine, in either
+// the standard or flexible environment.
+func IsAppEngine() bool {
+ return internal.IsAppEngine()
+}
+
// NewContext returns a context for an in-flight HTTP request.
// This function is cheap.
func NewContext(req *http.Request) context.Context {
diff --git a/vendor/google.golang.org/appengine/go.sum b/vendor/google.golang.org/appengine/go.sum
index 5e644c2e..1a221c08 100644
--- a/vendor/google.golang.org/appengine/go.sum
+++ b/vendor/google.golang.org/appengine/go.sum
@@ -1,3 +1,6 @@
+github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225 h1:kNX+jCowfMYzvlSvJu5pQWEmyWFrBXJ3PBy10xKMXK8=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
diff --git a/vendor/google.golang.org/appengine/internal/api.go b/vendor/google.golang.org/appengine/internal/api.go
index 16f87c5d..c9514952 100644
--- a/vendor/google.golang.org/appengine/internal/api.go
+++ b/vendor/google.golang.org/appengine/internal/api.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
// +build !appengine
-// +build go1.7
package internal
@@ -130,7 +129,13 @@ func handleHTTP(w http.ResponseWriter, r *http.Request) {
flushes++
}
c.pendingLogs.Unlock()
- go c.flushLog(false)
+ flushed := make(chan struct{})
+ go func() {
+ defer close(flushed)
+ // Force a log flush, because with very short requests we
+ // may not ever flush logs.
+ c.flushLog(true)
+ }()
w.Header().Set(logFlushHeader, strconv.Itoa(flushes))
// Avoid nil Write call if c.Write is never called.
@@ -140,6 +145,9 @@ func handleHTTP(w http.ResponseWriter, r *http.Request) {
if c.outBody != nil {
w.Write(c.outBody)
}
+ // Wait for the last flush to complete before returning,
+ // otherwise the security ticket will not be valid.
+ <-flushed
}
func executeRequestSafely(c *context, r *http.Request) {
diff --git a/vendor/google.golang.org/appengine/internal/api_pre17.go b/vendor/google.golang.org/appengine/internal/api_pre17.go
deleted file mode 100644
index 028b4f05..00000000
--- a/vendor/google.golang.org/appengine/internal/api_pre17.go
+++ /dev/null
@@ -1,682 +0,0 @@
-// Copyright 2011 Google Inc. All rights reserved.
-// Use of this source code is governed by the Apache 2.0
-// license that can be found in the LICENSE file.
-
-// +build !appengine
-// +build !go1.7
-
-package internal
-
-import (
- "bytes"
- "errors"
- "fmt"
- "io/ioutil"
- "log"
- "net"
- "net/http"
- "net/url"
- "os"
- "runtime"
- "strconv"
- "strings"
- "sync"
- "sync/atomic"
- "time"
-
- "github.com/golang/protobuf/proto"
- netcontext "golang.org/x/net/context"
-
- basepb "google.golang.org/appengine/internal/base"
- logpb "google.golang.org/appengine/internal/log"
- remotepb "google.golang.org/appengine/internal/remote_api"
-)
-
-const (
- apiPath = "/rpc_http"
- defaultTicketSuffix = "/default.20150612t184001.0"
-)
-
-var (
- // Incoming headers.
- ticketHeader = http.CanonicalHeaderKey("X-AppEngine-API-Ticket")
- dapperHeader = http.CanonicalHeaderKey("X-Google-DapperTraceInfo")
- traceHeader = http.CanonicalHeaderKey("X-Cloud-Trace-Context")
- curNamespaceHeader = http.CanonicalHeaderKey("X-AppEngine-Current-Namespace")
- userIPHeader = http.CanonicalHeaderKey("X-AppEngine-User-IP")
- remoteAddrHeader = http.CanonicalHeaderKey("X-AppEngine-Remote-Addr")
-
- // Outgoing headers.
- apiEndpointHeader = http.CanonicalHeaderKey("X-Google-RPC-Service-Endpoint")
- apiEndpointHeaderValue = []string{"app-engine-apis"}
- apiMethodHeader = http.CanonicalHeaderKey("X-Google-RPC-Service-Method")
- apiMethodHeaderValue = []string{"/VMRemoteAPI.CallRemoteAPI"}
- apiDeadlineHeader = http.CanonicalHeaderKey("X-Google-RPC-Service-Deadline")
- apiContentType = http.CanonicalHeaderKey("Content-Type")
- apiContentTypeValue = []string{"application/octet-stream"}
- logFlushHeader = http.CanonicalHeaderKey("X-AppEngine-Log-Flush-Count")
-
- apiHTTPClient = &http.Client{
- Transport: &http.Transport{
- Proxy: http.ProxyFromEnvironment,
- Dial: limitDial,
- },
- }
-
- defaultTicketOnce sync.Once
- defaultTicket string
-)
-
-func apiURL() *url.URL {
- host, port := "appengine.googleapis.internal", "10001"
- if h := os.Getenv("API_HOST"); h != "" {
- host = h
- }
- if p := os.Getenv("API_PORT"); p != "" {
- port = p
- }
- return &url.URL{
- Scheme: "http",
- Host: host + ":" + port,
- Path: apiPath,
- }
-}
-
-func handleHTTP(w http.ResponseWriter, r *http.Request) {
- c := &context{
- req: r,
- outHeader: w.Header(),
- apiURL: apiURL(),
- }
- stopFlushing := make(chan int)
-
- ctxs.Lock()
- ctxs.m[r] = c
- ctxs.Unlock()
- defer func() {
- ctxs.Lock()
- delete(ctxs.m, r)
- ctxs.Unlock()
- }()
-
- // Patch up RemoteAddr so it looks reasonable.
- if addr := r.Header.Get(userIPHeader); addr != "" {
- r.RemoteAddr = addr
- } else if addr = r.Header.Get(remoteAddrHeader); addr != "" {
- r.RemoteAddr = addr
- } else {
- // Should not normally reach here, but pick a sensible default anyway.
- r.RemoteAddr = "127.0.0.1"
- }
- // The address in the headers will most likely be of these forms:
- // 123.123.123.123
- // 2001:db8::1
- // net/http.Request.RemoteAddr is specified to be in "IP:port" form.
- if _, _, err := net.SplitHostPort(r.RemoteAddr); err != nil {
- // Assume the remote address is only a host; add a default port.
- r.RemoteAddr = net.JoinHostPort(r.RemoteAddr, "80")
- }
-
- // Start goroutine responsible for flushing app logs.
- // This is done after adding c to ctx.m (and stopped before removing it)
- // because flushing logs requires making an API call.
- go c.logFlusher(stopFlushing)
-
- executeRequestSafely(c, r)
- c.outHeader = nil // make sure header changes aren't respected any more
-
- stopFlushing <- 1 // any logging beyond this point will be dropped
-
- // Flush any pending logs asynchronously.
- c.pendingLogs.Lock()
- flushes := c.pendingLogs.flushes
- if len(c.pendingLogs.lines) > 0 {
- flushes++
- }
- c.pendingLogs.Unlock()
- go c.flushLog(false)
- w.Header().Set(logFlushHeader, strconv.Itoa(flushes))
-
- // Avoid nil Write call if c.Write is never called.
- if c.outCode != 0 {
- w.WriteHeader(c.outCode)
- }
- if c.outBody != nil {
- w.Write(c.outBody)
- }
-}
-
-func executeRequestSafely(c *context, r *http.Request) {
- defer func() {
- if x := recover(); x != nil {
- logf(c, 4, "%s", renderPanic(x)) // 4 == critical
- c.outCode = 500
- }
- }()
-
- http.DefaultServeMux.ServeHTTP(c, r)
-}
-
-func renderPanic(x interface{}) string {
- buf := make([]byte, 16<<10) // 16 KB should be plenty
- buf = buf[:runtime.Stack(buf, false)]
-
- // Remove the first few stack frames:
- // this func
- // the recover closure in the caller
- // That will root the stack trace at the site of the panic.
- const (
- skipStart = "internal.renderPanic"
- skipFrames = 2
- )
- start := bytes.Index(buf, []byte(skipStart))
- p := start
- for i := 0; i < skipFrames*2 && p+1 < len(buf); i++ {
- p = bytes.IndexByte(buf[p+1:], '\n') + p + 1
- if p < 0 {
- break
- }
- }
- if p >= 0 {
- // buf[start:p+1] is the block to remove.
- // Copy buf[p+1:] over buf[start:] and shrink buf.
- copy(buf[start:], buf[p+1:])
- buf = buf[:len(buf)-(p+1-start)]
- }
-
- // Add panic heading.
- head := fmt.Sprintf("panic: %v\n\n", x)
- if len(head) > len(buf) {
- // Extremely unlikely to happen.
- return head
- }
- copy(buf[len(head):], buf)
- copy(buf, head)
-
- return string(buf)
-}
-
-var ctxs = struct {
- sync.Mutex
- m map[*http.Request]*context
- bg *context // background context, lazily initialized
- // dec is used by tests to decorate the netcontext.Context returned
- // for a given request. This allows tests to add overrides (such as
- // WithAppIDOverride) to the context. The map is nil outside tests.
- dec map[*http.Request]func(netcontext.Context) netcontext.Context
-}{
- m: make(map[*http.Request]*context),
-}
-
-// context represents the context of an in-flight HTTP request.
-// It implements the appengine.Context and http.ResponseWriter interfaces.
-type context struct {
- req *http.Request
-
- outCode int
- outHeader http.Header
- outBody []byte
-
- pendingLogs struct {
- sync.Mutex
- lines []*logpb.UserAppLogLine
- flushes int
- }
-
- apiURL *url.URL
-}
-
-var contextKey = "holds a *context"
-
-// fromContext returns the App Engine context or nil if ctx is not
-// derived from an App Engine context.
-func fromContext(ctx netcontext.Context) *context {
- c, _ := ctx.Value(&contextKey).(*context)
- return c
-}
-
-func withContext(parent netcontext.Context, c *context) netcontext.Context {
- ctx := netcontext.WithValue(parent, &contextKey, c)
- if ns := c.req.Header.Get(curNamespaceHeader); ns != "" {
- ctx = withNamespace(ctx, ns)
- }
- return ctx
-}
-
-func toContext(c *context) netcontext.Context {
- return withContext(netcontext.Background(), c)
-}
-
-func IncomingHeaders(ctx netcontext.Context) http.Header {
- if c := fromContext(ctx); c != nil {
- return c.req.Header
- }
- return nil
-}
-
-func ReqContext(req *http.Request) netcontext.Context {
- return WithContext(netcontext.Background(), req)
-}
-
-func WithContext(parent netcontext.Context, req *http.Request) netcontext.Context {
- ctxs.Lock()
- c := ctxs.m[req]
- d := ctxs.dec[req]
- ctxs.Unlock()
-
- if d != nil {
- parent = d(parent)
- }
-
- if c == nil {
- // Someone passed in an http.Request that is not in-flight.
- // We panic here rather than panicking at a later point
- // so that stack traces will be more sensible.
- log.Panic("appengine: NewContext passed an unknown http.Request")
- }
- return withContext(parent, c)
-}
-
-// DefaultTicket returns a ticket used for background context or dev_appserver.
-func DefaultTicket() string {
- defaultTicketOnce.Do(func() {
- if IsDevAppServer() {
- defaultTicket = "testapp" + defaultTicketSuffix
- return
- }
- appID := partitionlessAppID()
- escAppID := strings.Replace(strings.Replace(appID, ":", "_", -1), ".", "_", -1)
- majVersion := VersionID(nil)
- if i := strings.Index(majVersion, "."); i > 0 {
- majVersion = majVersion[:i]
- }
- defaultTicket = fmt.Sprintf("%s/%s.%s.%s", escAppID, ModuleName(nil), majVersion, InstanceID())
- })
- return defaultTicket
-}
-
-func BackgroundContext() netcontext.Context {
- ctxs.Lock()
- defer ctxs.Unlock()
-
- if ctxs.bg != nil {
- return toContext(ctxs.bg)
- }
-
- // Compute background security ticket.
- ticket := DefaultTicket()
-
- ctxs.bg = &context{
- req: &http.Request{
- Header: http.Header{
- ticketHeader: []string{ticket},
- },
- },
- apiURL: apiURL(),
- }
-
- // TODO(dsymonds): Wire up the shutdown handler to do a final flush.
- go ctxs.bg.logFlusher(make(chan int))
-
- return toContext(ctxs.bg)
-}
-
-// RegisterTestRequest registers the HTTP request req for testing, such that
-// any API calls are sent to the provided URL. It returns a closure to delete
-// the registration.
-// It should only be used by aetest package.
-func RegisterTestRequest(req *http.Request, apiURL *url.URL, decorate func(netcontext.Context) netcontext.Context) (*http.Request, func()) {
- c := &context{
- req: req,
- apiURL: apiURL,
- }
- ctxs.Lock()
- defer ctxs.Unlock()
- if _, ok := ctxs.m[req]; ok {
- log.Panic("req already associated with context")
- }
- if _, ok := ctxs.dec[req]; ok {
- log.Panic("req already associated with context")
- }
- if ctxs.dec == nil {
- ctxs.dec = make(map[*http.Request]func(netcontext.Context) netcontext.Context)
- }
- ctxs.m[req] = c
- ctxs.dec[req] = decorate
-
- return req, func() {
- ctxs.Lock()
- delete(ctxs.m, req)
- delete(ctxs.dec, req)
- ctxs.Unlock()
- }
-}
-
-var errTimeout = &CallError{
- Detail: "Deadline exceeded",
- Code: int32(remotepb.RpcError_CANCELLED),
- Timeout: true,
-}
-
-func (c *context) Header() http.Header { return c.outHeader }
-
-// Copied from $GOROOT/src/pkg/net/http/transfer.go. Some response status
-// codes do not permit a response body (nor response entity headers such as
-// Content-Length, Content-Type, etc).
-func bodyAllowedForStatus(status int) bool {
- switch {
- case status >= 100 && status <= 199:
- return false
- case status == 204:
- return false
- case status == 304:
- return false
- }
- return true
-}
-
-func (c *context) Write(b []byte) (int, error) {
- if c.outCode == 0 {
- c.WriteHeader(http.StatusOK)
- }
- if len(b) > 0 && !bodyAllowedForStatus(c.outCode) {
- return 0, http.ErrBodyNotAllowed
- }
- c.outBody = append(c.outBody, b...)
- return len(b), nil
-}
-
-func (c *context) WriteHeader(code int) {
- if c.outCode != 0 {
- logf(c, 3, "WriteHeader called multiple times on request.") // error level
- return
- }
- c.outCode = code
-}
-
-func (c *context) post(body []byte, timeout time.Duration) (b []byte, err error) {
- hreq := &http.Request{
- Method: "POST",
- URL: c.apiURL,
- Header: http.Header{
- apiEndpointHeader: apiEndpointHeaderValue,
- apiMethodHeader: apiMethodHeaderValue,
- apiContentType: apiContentTypeValue,
- apiDeadlineHeader: []string{strconv.FormatFloat(timeout.Seconds(), 'f', -1, 64)},
- },
- Body: ioutil.NopCloser(bytes.NewReader(body)),
- ContentLength: int64(len(body)),
- Host: c.apiURL.Host,
- }
- if info := c.req.Header.Get(dapperHeader); info != "" {
- hreq.Header.Set(dapperHeader, info)
- }
- if info := c.req.Header.Get(traceHeader); info != "" {
- hreq.Header.Set(traceHeader, info)
- }
-
- tr := apiHTTPClient.Transport.(*http.Transport)
-
- var timedOut int32 // atomic; set to 1 if timed out
- t := time.AfterFunc(timeout, func() {
- atomic.StoreInt32(&timedOut, 1)
- tr.CancelRequest(hreq)
- })
- defer t.Stop()
- defer func() {
- // Check if timeout was exceeded.
- if atomic.LoadInt32(&timedOut) != 0 {
- err = errTimeout
- }
- }()
-
- hresp, err := apiHTTPClient.Do(hreq)
- if err != nil {
- return nil, &CallError{
- Detail: fmt.Sprintf("service bridge HTTP failed: %v", err),
- Code: int32(remotepb.RpcError_UNKNOWN),
- }
- }
- defer hresp.Body.Close()
- hrespBody, err := ioutil.ReadAll(hresp.Body)
- if hresp.StatusCode != 200 {
- return nil, &CallError{
- Detail: fmt.Sprintf("service bridge returned HTTP %d (%q)", hresp.StatusCode, hrespBody),
- Code: int32(remotepb.RpcError_UNKNOWN),
- }
- }
- if err != nil {
- return nil, &CallError{
- Detail: fmt.Sprintf("service bridge response bad: %v", err),
- Code: int32(remotepb.RpcError_UNKNOWN),
- }
- }
- return hrespBody, nil
-}
-
-func Call(ctx netcontext.Context, service, method string, in, out proto.Message) error {
- if ns := NamespaceFromContext(ctx); ns != "" {
- if fn, ok := NamespaceMods[service]; ok {
- fn(in, ns)
- }
- }
-
- if f, ctx, ok := callOverrideFromContext(ctx); ok {
- return f(ctx, service, method, in, out)
- }
-
- // Handle already-done contexts quickly.
- select {
- case <-ctx.Done():
- return ctx.Err()
- default:
- }
-
- c := fromContext(ctx)
- if c == nil {
- // Give a good error message rather than a panic lower down.
- return errNotAppEngineContext
- }
-
- // Apply transaction modifications if we're in a transaction.
- if t := transactionFromContext(ctx); t != nil {
- if t.finished {
- return errors.New("transaction context has expired")
- }
- applyTransaction(in, &t.transaction)
- }
-
- // Default RPC timeout is 60s.
- timeout := 60 * time.Second
- if deadline, ok := ctx.Deadline(); ok {
- timeout = deadline.Sub(time.Now())
- }
-
- data, err := proto.Marshal(in)
- if err != nil {
- return err
- }
-
- ticket := c.req.Header.Get(ticketHeader)
- // Use a test ticket under test environment.
- if ticket == "" {
- if appid := ctx.Value(&appIDOverrideKey); appid != nil {
- ticket = appid.(string) + defaultTicketSuffix
- }
- }
- // Fall back to use background ticket when the request ticket is not available in Flex or dev_appserver.
- if ticket == "" {
- ticket = DefaultTicket()
- }
- req := &remotepb.Request{
- ServiceName: &service,
- Method: &method,
- Request: data,
- RequestId: &ticket,
- }
- hreqBody, err := proto.Marshal(req)
- if err != nil {
- return err
- }
-
- hrespBody, err := c.post(hreqBody, timeout)
- if err != nil {
- return err
- }
-
- res := &remotepb.Response{}
- if err := proto.Unmarshal(hrespBody, res); err != nil {
- return err
- }
- if res.RpcError != nil {
- ce := &CallError{
- Detail: res.RpcError.GetDetail(),
- Code: *res.RpcError.Code,
- }
- switch remotepb.RpcError_ErrorCode(ce.Code) {
- case remotepb.RpcError_CANCELLED, remotepb.RpcError_DEADLINE_EXCEEDED:
- ce.Timeout = true
- }
- return ce
- }
- if res.ApplicationError != nil {
- return &APIError{
- Service: *req.ServiceName,
- Detail: res.ApplicationError.GetDetail(),
- Code: *res.ApplicationError.Code,
- }
- }
- if res.Exception != nil || res.JavaException != nil {
- // This shouldn't happen, but let's be defensive.
- return &CallError{
- Detail: "service bridge returned exception",
- Code: int32(remotepb.RpcError_UNKNOWN),
- }
- }
- return proto.Unmarshal(res.Response, out)
-}
-
-func (c *context) Request() *http.Request {
- return c.req
-}
-
-func (c *context) addLogLine(ll *logpb.UserAppLogLine) {
- // Truncate long log lines.
- // TODO(dsymonds): Check if this is still necessary.
- const lim = 8 << 10
- if len(*ll.Message) > lim {
- suffix := fmt.Sprintf("...(length %d)", len(*ll.Message))
- ll.Message = proto.String((*ll.Message)[:lim-len(suffix)] + suffix)
- }
-
- c.pendingLogs.Lock()
- c.pendingLogs.lines = append(c.pendingLogs.lines, ll)
- c.pendingLogs.Unlock()
-}
-
-var logLevelName = map[int64]string{
- 0: "DEBUG",
- 1: "INFO",
- 2: "WARNING",
- 3: "ERROR",
- 4: "CRITICAL",
-}
-
-func logf(c *context, level int64, format string, args ...interface{}) {
- if c == nil {
- panic("not an App Engine context")
- }
- s := fmt.Sprintf(format, args...)
- s = strings.TrimRight(s, "\n") // Remove any trailing newline characters.
- c.addLogLine(&logpb.UserAppLogLine{
- TimestampUsec: proto.Int64(time.Now().UnixNano() / 1e3),
- Level: &level,
- Message: &s,
- })
- log.Print(logLevelName[level] + ": " + s)
-}
-
-// flushLog attempts to flush any pending logs to the appserver.
-// It should not be called concurrently.
-func (c *context) flushLog(force bool) (flushed bool) {
- c.pendingLogs.Lock()
- // Grab up to 30 MB. We can get away with up to 32 MB, but let's be cautious.
- n, rem := 0, 30<<20
- for ; n < len(c.pendingLogs.lines); n++ {
- ll := c.pendingLogs.lines[n]
- // Each log line will require about 3 bytes of overhead.
- nb := proto.Size(ll) + 3
- if nb > rem {
- break
- }
- rem -= nb
- }
- lines := c.pendingLogs.lines[:n]
- c.pendingLogs.lines = c.pendingLogs.lines[n:]
- c.pendingLogs.Unlock()
-
- if len(lines) == 0 && !force {
- // Nothing to flush.
- return false
- }
-
- rescueLogs := false
- defer func() {
- if rescueLogs {
- c.pendingLogs.Lock()
- c.pendingLogs.lines = append(lines, c.pendingLogs.lines...)
- c.pendingLogs.Unlock()
- }
- }()
-
- buf, err := proto.Marshal(&logpb.UserAppLogGroup{
- LogLine: lines,
- })
- if err != nil {
- log.Printf("internal.flushLog: marshaling UserAppLogGroup: %v", err)
- rescueLogs = true
- return false
- }
-
- req := &logpb.FlushRequest{
- Logs: buf,
- }
- res := &basepb.VoidProto{}
- c.pendingLogs.Lock()
- c.pendingLogs.flushes++
- c.pendingLogs.Unlock()
- if err := Call(toContext(c), "logservice", "Flush", req, res); err != nil {
- log.Printf("internal.flushLog: Flush RPC: %v", err)
- rescueLogs = true
- return false
- }
- return true
-}
-
-const (
- // Log flushing parameters.
- flushInterval = 1 * time.Second
- forceFlushInterval = 60 * time.Second
-)
-
-func (c *context) logFlusher(stop <-chan int) {
- lastFlush := time.Now()
- tick := time.NewTicker(flushInterval)
- for {
- select {
- case <-stop:
- // Request finished.
- tick.Stop()
- return
- case <-tick.C:
- force := time.Now().Sub(lastFlush) > forceFlushInterval
- if c.flushLog(force) {
- lastFlush = time.Now()
- }
- }
- }
-}
-
-func ContextForTesting(req *http.Request) netcontext.Context {
- return toContext(&context{req: req})
-}
diff --git a/vendor/google.golang.org/appengine/internal/identity.go b/vendor/google.golang.org/appengine/internal/identity.go
index d538701a..6d89d637 100644
--- a/vendor/google.golang.org/appengine/internal/identity.go
+++ b/vendor/google.golang.org/appengine/internal/identity.go
@@ -4,11 +4,46 @@
package internal
-import netcontext "golang.org/x/net/context"
+import (
+ "os"
-// These functions are implementations of the wrapper functions
-// in ../appengine/identity.go. See that file for commentary.
+ netcontext "golang.org/x/net/context"
+)
+var (
+ // This is set to true in identity_classic.go, which is behind the appengine build tag.
+ // The appengine build tag is set for the first generation runtimes (<= Go 1.9) but not
+ // the second generation runtimes (>= Go 1.11), so this indicates whether we're on a
+ // first-gen runtime. See IsStandard below for the second-gen check.
+ appengineStandard bool
+
+ // This is set to true in identity_flex.go, which is behind the appenginevm build tag.
+ appengineFlex bool
+)
+
+// AppID is the implementation of the wrapper function of the same name in
+// ../identity.go. See that file for commentary.
func AppID(c netcontext.Context) string {
return appID(FullyQualifiedAppID(c))
}
+
+// IsStandard is the implementation of the wrapper function of the same name in
+// ../appengine.go. See that file for commentary.
+func IsStandard() bool {
+ // appengineStandard will be true for first-gen runtimes (<= Go 1.9) but not
+ // second-gen (>= Go 1.11). Second-gen runtimes set $GAE_ENV so we use that
+ // to check if we're on a second-gen runtime.
+ return appengineStandard || os.Getenv("GAE_ENV") == "standard"
+}
+
+// IsFlex is the implementation of the wrapper function of the same name in
+// ../appengine.go. See that file for commentary.
+func IsFlex() bool {
+ return appengineFlex
+}
+
+// IsAppEngine is the implementation of the wrapper function of the same name in
+// ../appengine.go. See that file for commentary.
+func IsAppEngine() bool {
+ return IsStandard() || IsFlex()
+}
diff --git a/vendor/google.golang.org/appengine/internal/identity_classic.go b/vendor/google.golang.org/appengine/internal/identity_classic.go
index b59603f1..4e979f45 100644
--- a/vendor/google.golang.org/appengine/internal/identity_classic.go
+++ b/vendor/google.golang.org/appengine/internal/identity_classic.go
@@ -12,6 +12,10 @@ import (
netcontext "golang.org/x/net/context"
)
+func init() {
+ appengineStandard = true
+}
+
func DefaultVersionHostname(ctx netcontext.Context) string {
c := fromContext(ctx)
if c == nil {
diff --git a/vendor/google.golang.org/appengine/internal/identity_flex.go b/vendor/google.golang.org/appengine/internal/identity_flex.go
new file mode 100644
index 00000000..d5e2e7b5
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/identity_flex.go
@@ -0,0 +1,11 @@
+// Copyright 2018 Google LLC. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+// +build appenginevm
+
+package internal
+
+func init() {
+ appengineFlex = true
+}
diff --git a/vendor/google.golang.org/appengine/travis_install.sh b/vendor/google.golang.org/appengine/travis_install.sh
new file mode 100755
index 00000000..785b62f4
--- /dev/null
+++ b/vendor/google.golang.org/appengine/travis_install.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+set -e
+
+if [[ $GO111MODULE == "on" ]]; then
+ go get .
+else
+ go get -u -v $(go list -f '{{join .Imports "\n"}}{{"\n"}}{{join .TestImports "\n"}}' ./... | sort | uniq | grep -v appengine)
+fi
+
+if [[ $GOAPP == "true" ]]; then
+ mkdir /tmp/sdk
+ curl -o /tmp/sdk.zip "https://storage.googleapis.com/appengine-sdks/featured/go_appengine_sdk_linux_amd64-1.9.68.zip"
+ unzip -q /tmp/sdk.zip -d /tmp/sdk
+ # NOTE: Set the following env vars in the test script:
+ # export PATH="$PATH:/tmp/sdk/go_appengine"
+ # export APPENGINE_DEV_APPSERVER=/tmp/sdk/go_appengine/dev_appserver.py
+fi
+
diff --git a/vendor/google.golang.org/appengine/travis_test.sh b/vendor/google.golang.org/appengine/travis_test.sh
new file mode 100755
index 00000000..d4390f04
--- /dev/null
+++ b/vendor/google.golang.org/appengine/travis_test.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+set -e
+
+go version
+go test -v google.golang.org/appengine/...
+go test -v -race google.golang.org/appengine/...
+if [[ $GOAPP == "true" ]]; then
+ export PATH="$PATH:/tmp/sdk/go_appengine"
+ export APPENGINE_DEV_APPSERVER=/tmp/sdk/go_appengine/dev_appserver.py
+ goapp version
+ goapp test -v google.golang.org/appengine/...
+fi