1
0
mirror of https://github.com/taigrr/wtf synced 2025-01-18 04:03:14 -08:00

Update dependencies to latest versions

This commit is contained in:
Chris Cummer 2019-01-11 16:44:42 -08:00
parent ea27f40164
commit 48cb7ba773
358 changed files with 29553 additions and 8982 deletions

118
Gopkg.lock generated
View File

@ -2,12 +2,12 @@
[[projects]] [[projects]]
digest = "1:5c3894b2aa4d6bead0ceeea6831b305d62879c871780e7b76296ded1b004bc57" digest = "1:5ad08b0e14866764a6d7475eb11c9cf05cad9a52c442593bdfa544703ff77f61"
name = "cloud.google.com/go" name = "cloud.google.com/go"
packages = ["compute/metadata"] packages = ["compute/metadata"]
pruneopts = "UT" pruneopts = "UT"
revision = "dfffe386c33fb24c34ee501e5723df5b97b98514" revision = "0ebda48a7f143b1cce9eb37a8c1106ac762a3430"
version = "v0.30.0" version = "v0.34.0"
[[projects]] [[projects]]
branch = "master" branch = "master"
@ -34,7 +34,7 @@
revision = "e4cc07c871d0ee17c5579131fc1c786efbb5fe2a" revision = "e4cc07c871d0ee17c5579131fc1c786efbb5fe2a"
[[projects]] [[projects]]
digest = "1:9253f97cfbbe049b631877c80badecc69620711b3e335f6cf97a7809681da388" digest = "1:aa94227e54ee105fcd03f25c85d3e5bbe13d2f2d5eb02379b5b4db5320dfb371"
name = "github.com/alecthomas/chroma" name = "github.com/alecthomas/chroma"
packages = [ packages = [
".", ".",
@ -70,16 +70,16 @@
"styles", "styles",
] ]
pruneopts = "UT" pruneopts = "UT"
revision = "5d7fef2ae60b501bbf28d476c3f273b8017d8261" revision = "881a441774f9d707d3b7852025b7f2149a556182"
version = "v0.5.0" version = "v0.6.2"
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:579829cc9bf515e2f9e39f91df03b9333c311402bac5a4935dc8ef81e3a57160" digest = "1:a7955b3402449f2e9ef351d0d6d9d42af3e0b24967340b738078d80c90deb6c2"
name = "github.com/andygrunwald/go-gerrit" name = "github.com/andygrunwald/go-gerrit"
packages = ["."] packages = ["."]
pruneopts = "UT" pruneopts = "UT"
revision = "30ce279197661497040ec81c4b64539562eb2d4b" revision = "f48c3d16616fdb85d96efcead2402bfd339d8c89"
[[projects]] [[projects]]
branch = "master" branch = "master"
@ -90,12 +90,12 @@
revision = "5f41b7c9d92de5d74bf32f4486375c7547bc8a3c" revision = "5f41b7c9d92de5d74bf32f4486375c7547bc8a3c"
[[projects]] [[projects]]
digest = "1:2209584c0f7c9b68c23374e659357ab546e1b70eec2761f03280f69a8fd23d77" digest = "1:166438587ed45ac211dab8a3ecebf4fa0c186d0db63430fb9127bbc2e5fcdc67"
name = "github.com/cenkalti/backoff" name = "github.com/cenkalti/backoff"
packages = ["."] packages = ["."]
pruneopts = "UT" pruneopts = "UT"
revision = "2ea60e5f094469f9e65adb9cd103795b73ae743e" revision = "1e4cf3da559842a91afcb6ea6141451e6c30c618"
version = "v2.0.0" version = "v2.1.1"
[[projects]] [[projects]]
branch = "master" branch = "master"
@ -141,42 +141,42 @@
version = "v1.0.0" version = "v1.0.0"
[[projects]] [[projects]]
branch = "master" digest = "1:0e16b03c72bd42739ca68d055c10369e60d17838428f512f3b29ae115ba788e0"
digest = "1:40d0056c1b1f503c366ba441df92a82b5a2654d6f3747b1689a611eb5c9ce0a2"
name = "github.com/gdamore/encoding" name = "github.com/gdamore/encoding"
packages = ["."] packages = ["."]
pruneopts = "UT" pruneopts = "UT"
revision = "b23993cbb6353f0e6aa98d0ee318a34728f628b9" revision = "6289cdc94c00ac4aa177771c5fce7af2f96b626d"
version = "v1.0.0"
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:490cf9d7deec1b0dcac6cc8b17f307c48c4821bc2140d46e48175a83acbfe40d" digest = "1:937011a37a09b93be68052dfb3195fcfbff33b9472b37401b54027e9954906fb"
name = "github.com/gdamore/tcell" name = "github.com/gdamore/tcell"
packages = [ packages = [
".", ".",
"terminfo", "terminfo",
] ]
pruneopts = "UT" pruneopts = "UT"
revision = "493f3b46b3c20880afc8e04ceeb1c6d5aa3363d7" revision = "aaadc574a6ed8dc3abe56036ca130dcee1ee6b6e"
[[projects]] [[projects]]
digest = "1:64a5a67c69b70c2420e607a8545d674a23778ed9c3e80607bfd17b77c6c87f6a" digest = "1:c96d16a4451e48e2c44b2c3531fd8ec9248d822637f1911a88959ca0bcae4a64"
name = "github.com/go-ole/go-ole" name = "github.com/go-ole/go-ole"
packages = [ packages = [
".", ".",
"oleutil", "oleutil",
] ]
pruneopts = "UT" pruneopts = "UT"
revision = "a41e3c4b706f6ae8dfbff342b06e40fa4d2d0506" revision = "39dc8486bd0952279431257138bc428275b86797"
version = "v1.2.1" version = "v1.2.2"
[[projects]] [[projects]]
digest = "1:57fa4c058c21ce25d0b7272518dd746065117abf6cc706158b0d361202024520" digest = "1:b3d20bcdedab2050e6bc58e52f4fdc46f710b4c74e1a1ecee262ebec1aee7b6e"
name = "github.com/godbus/dbus" name = "github.com/godbus/dbus"
packages = ["."] packages = ["."]
pruneopts = "UT" pruneopts = "UT"
revision = "a389bdde4dd695d414e47b755e95e72b7826432c" revision = "2ff6f7ffd60f0f2410b3105864bdd12c7894f844"
version = "v4.1.0" version = "v5.0.1"
[[projects]] [[projects]]
digest = "1:97df918963298c287643883209a2c3f642e6593379f97ab400c2a2e219ab647d" digest = "1:97df918963298c287643883209a2c3f642e6593379f97ab400c2a2e219ab647d"
@ -188,11 +188,11 @@
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:8c90219e8a1f5f7cad019b77697aaae2b236db5a1a46ae688e5ede406e109182" digest = "1:fc71ff099a9d9e73a66556c3115c78ca64cd7f01e08a7eddcaddcba5e8fa02fd"
name = "github.com/google/go-github" name = "github.com/google/go-github"
packages = ["github"] packages = ["github"]
pruneopts = "UT" pruneopts = "UT"
revision = "68a79fc6a32bab9406083545e667a65ba67b0a3e" revision = "ce65dacfeac482f2a13b59e19c5a25947282c171"
[[projects]] [[projects]]
digest = "1:a63cff6b5d8b95638bfe300385d93b2a6d9d687734b863da8e09dc834510a690" digest = "1:a63cff6b5d8b95638bfe300385d93b2a6d9d687734b863da8e09dc834510a690"
@ -219,12 +219,12 @@
version = "v1.0" version = "v1.0"
[[projects]] [[projects]]
digest = "1:cdb899c199f907ac9fb50495ec71212c95cb5b0e0a8ee0800da0238036091033" digest = "1:0356f3312c9bd1cbeda81505b7fd437501d8e778ab66998ef69f00d7f9b3a0d7"
name = "github.com/mattn/go-runewidth" name = "github.com/mattn/go-runewidth"
packages = ["."] packages = ["."]
pruneopts = "UT" pruneopts = "UT"
revision = "ce7b0b5c7b45a81508558cd1dba6bb1e4ddb51bb" revision = "3ee7d812e62a0804a7d0a324e0249ca2db3476d3"
version = "v0.0.3" version = "v0.0.4"
[[projects]] [[projects]]
branch = "master" branch = "master"
@ -235,12 +235,12 @@
revision = "57f804269e64d41bfe46efb76232c47f49d40902" revision = "57f804269e64d41bfe46efb76232c47f49d40902"
[[projects]] [[projects]]
digest = "1:40e195917a951a8bf867cd05de2a46aaf1806c50cf92eebf4c16f78cd196f747" digest = "1:cf31692c14422fa27c83a05292eb5cbe0fb2775972e8f1f8446a71549bd8980b"
name = "github.com/pkg/errors" name = "github.com/pkg/errors"
packages = ["."] packages = ["."]
pruneopts = "UT" pruneopts = "UT"
revision = "645ef00459ed84a119197bfb8d8205042c6df63d" revision = "ba968bfe8b2f7e042a574c888954fccecfa385b4"
version = "v0.8.0" version = "v0.8.1"
[[projects]] [[projects]]
digest = "1:cfa0d7741863a0e1d30e0ccdd4b48a96a471cdb47892303de8b92c3713af3e77" digest = "1:cfa0d7741863a0e1d30e0ccdd4b48a96a471cdb47892303de8b92c3713af3e77"
@ -259,23 +259,23 @@
version = "v1.0.0" version = "v1.0.0"
[[projects]] [[projects]]
digest = "1:0665976cc6d8c2e60dafca32820b6b7eca70f37ded0bcccc103388e1c0d05c53" digest = "1:46f5782e57d221d76a19fb9c9c4f2b139f1d85ae7115a95e945a79221e1a7031"
name = "github.com/radovskyb/watcher" name = "github.com/radovskyb/watcher"
packages = ["."] packages = ["."]
pruneopts = "UT" pruneopts = "UT"
revision = "6145e1439b9de93806925353403f91d2abbad8a5" revision = "3818ec23ec59ea15084fe26bfb114b3bb58aa132"
version = "v1.0.2" version = "v1.0.5"
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:00d9f4017b55d590139b77fbd851aef56f179479fc40a4afdedaf187e828f99d" digest = "1:0f44ebd1757c5725456f2d6c564b196dd96593e68fda7236e345642940b9a88a"
name = "github.com/rivo/tview" name = "github.com/rivo/tview"
packages = ["."] packages = ["."]
pruneopts = "UT" pruneopts = "UT"
revision = "a7c1880d62d37422830f0a15823b51301ca9f354" revision = "36893a66979260e9758701ae306ec0d69c0f53c8"
[[projects]] [[projects]]
digest = "1:266b1517f99511a50e97cf782c496eae4226ff94e884ef7e1ed53f423795b310" digest = "1:afee7cbe8cde64304b8bd397d5832b0e60c93f8b158e4102254558d2f862b0a6"
name = "github.com/shirou/gopsutil" name = "github.com/shirou/gopsutil"
packages = [ packages = [
"cpu", "cpu",
@ -283,8 +283,8 @@
"mem", "mem",
] ]
pruneopts = "UT" pruneopts = "UT"
revision = "3ec50d2876a36047b2ca39f955ba88fb7a455e92" revision = "ccc1c1016bc5d10e803189ee43417c50cdde7f1b"
version = "v2.18.10" version = "v2.18.12"
[[projects]] [[projects]]
branch = "master" branch = "master"
@ -295,20 +295,20 @@
revision = "98632f6f94b087f2582be76980f76bc070d37176" revision = "98632f6f94b087f2582be76980f76bc070d37176"
[[projects]] [[projects]]
digest = "1:18752d0b95816a1b777505a97f71c7467a8445b8ffb55631a7bf779f6ba4fa83" digest = "1:972c2427413d41a1e06ca4897e8528e5a1622894050e2f527b38ddf0f343f759"
name = "github.com/stretchr/testify" name = "github.com/stretchr/testify"
packages = ["assert"] packages = ["assert"]
pruneopts = "UT" pruneopts = "UT"
revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686" revision = "ffdc059bfe9ce6a4e144ba849dbedead332c6053"
version = "v1.2.2" version = "v1.3.0"
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:afc7e1c726a88e6cd5689cca19fbc86128dffe86fd37e3e0841767f3a951182e" digest = "1:fc5ea767f62a8a35b136db9e8629dc7718aea555c8480e44695a7d0894ae8303"
name = "github.com/xanzy/go-gitlab" name = "github.com/xanzy/go-gitlab"
packages = ["."] packages = ["."]
pruneopts = "UT" pruneopts = "UT"
revision = "1444249c1b2a8e4cdb5a76dc9c8d02d1133180be" revision = "d85a1530126065c71277db28196ec196daafc9dc"
[[projects]] [[projects]]
branch = "master" branch = "master"
@ -328,26 +328,26 @@
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:02a2f8f0718f239866000d2d1bca016d14f0f6de37615c315f34da17dc630259" digest = "1:0af28605549b0c849891b2ea4e99de9fe20d2f48d3ae5d42f9b06391e02a466e"
name = "github.com/zorkian/go-datadog-api" name = "github.com/zorkian/go-datadog-api"
packages = ["."] packages = ["."]
pruneopts = "UT" pruneopts = "UT"
revision = "dc324c09cf05eef3e3a82bde06ae0c4dd349a767" revision = "66f4fd4202d9d3e543608051a91a09eebc870966"
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:d6b719875cf8091fbab38527d81d34e71f4521b9ee9ccfbd4a32cff2ac5af96e" digest = "1:f8b491a7c25030a895a0e579742d07136e6958e77ef2d46e769db8eec4e58fcd"
name = "golang.org/x/net" name = "golang.org/x/net"
packages = [ packages = [
"context", "context",
"context/ctxhttp", "context/ctxhttp",
] ]
pruneopts = "UT" pruneopts = "UT"
revision = "04a2e542c03f1d053ab3e4d6e5abcd4b66e2be8e" revision = "915654e7eabcea33ae277abbecf52f0d8b7a9fdc"
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:faa25cb78cf9c8cec9345d4ed07322cdef6a8c968b3d0a6b6c3609067c7386eb" digest = "1:c58bbfb91df5a7eae08cb9894f9897165f254e459f07666986cd448f9be4ad35"
name = "golang.org/x/oauth2" name = "golang.org/x/oauth2"
packages = [ packages = [
".", ".",
@ -357,18 +357,18 @@
"jwt", "jwt",
] ]
pruneopts = "UT" pruneopts = "UT"
revision = "9dcd33a902f40452422c2367fefcb95b54f9f8f8" revision = "36a7019397c4c86cf59eeab3bc0d188bac444277"
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:f343f077a5b0bc3a3788b3a04e24dd417e3e25b2acb529c413e212d2c42416ef" digest = "1:5ee4df7ab18e945607ac822de8d10b180baea263b5e8676a1041727543b9c1e4"
name = "golang.org/x/sys" name = "golang.org/x/sys"
packages = [ packages = [
"unix", "unix",
"windows", "windows",
] ]
pruneopts = "UT" pruneopts = "UT"
revision = "62eef0e2fa9b2c385f7b2778e763486da6880d37" revision = "48ac38b7c8cbedd50b1613c0fccacfc7d88dfcdf"
[[projects]] [[projects]]
digest = "1:37672ad5821719e2df8509c2edd4ba5ae192463237c73c3a2d24ef8b2bc9e36f" digest = "1:37672ad5821719e2df8509c2edd4ba5ae192463237c73c3a2d24ef8b2bc9e36f"
@ -386,7 +386,7 @@
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:a1d58b7c9eeceeac201a6f6b10092cd2a5985791a45843c838151ee3f751d3c3" digest = "1:4b5fd36b449e451b5b4a4e8b31870c9230647f409413f13169ab93af268311da"
name = "google.golang.org/api" name = "google.golang.org/api"
packages = [ packages = [
"calendar/v3", "calendar/v3",
@ -396,10 +396,10 @@
"sheets/v4", "sheets/v4",
] ]
pruneopts = "UT" pruneopts = "UT"
revision = "a2651947f503a1793446d4058bb073a6fdf99e53" revision = "455dee39f703f70d67ceea7c56a61041712c1447"
[[projects]] [[projects]]
digest = "1:193950893ea275f89ed92e5da11ed8fa1436872f755a9ea5d4afa83dc9d9c3a8" digest = "1:fa026a5c59bd2df343ec4a3538e6288dcf4e2ec5281d743ae82c120affe6926a"
name = "google.golang.org/appengine" name = "google.golang.org/appengine"
packages = [ packages = [
".", ".",
@ -414,16 +414,16 @@
"urlfetch", "urlfetch",
] ]
pruneopts = "UT" pruneopts = "UT"
revision = "ae0ab99deb4dc413a2b4bd6c8bdd0eb67f1e4d06" revision = "e9657d882bb81064595ca3b56cbe2546bbabf7b1"
version = "v1.2.0" version = "v1.4.0"
[[projects]] [[projects]]
digest = "1:342378ac4dcb378a5448dd723f0784ae519383532f5e70ade24132c4c8693202" digest = "1:4d2e5a73dc1500038e504a8d78b986630e3626dc027bc030ba5c75da257cdb96"
name = "gopkg.in/yaml.v2" name = "gopkg.in/yaml.v2"
packages = ["."] packages = ["."]
pruneopts = "UT" pruneopts = "UT"
revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183" revision = "51d6538a90f86fe93ac480b35f37b2be17fef232"
version = "v2.2.1" version = "v2.2.2"
[solve-meta] [solve-meta]
analyzer-name = "dep" analyzer-name = "dep"

View File

@ -20,6 +20,7 @@
package metadata // import "cloud.google.com/go/compute/metadata" package metadata // import "cloud.google.com/go/compute/metadata"
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
@ -31,9 +32,6 @@ import (
"strings" "strings"
"sync" "sync"
"time" "time"
"golang.org/x/net/context"
"golang.org/x/net/context/ctxhttp"
) )
const ( const (
@ -143,7 +141,7 @@ func testOnGCE() bool {
go func() { go func() {
req, _ := http.NewRequest("GET", "http://"+metadataIP, nil) req, _ := http.NewRequest("GET", "http://"+metadataIP, nil)
req.Header.Set("User-Agent", userAgent) req.Header.Set("User-Agent", userAgent)
res, err := ctxhttp.Do(ctx, defaultClient.hc, req) res, err := defaultClient.hc.Do(req.WithContext(ctx))
if err != nil { if err != nil {
resc <- false resc <- false
return return

View File

@ -29,7 +29,32 @@ translators for Pygments lexers and styles.
## Supported languages ## Supported languages
ABNF, ANTLR, APL, ActionScript, ActionScript 3, Ada, Angular2, ApacheConf, AppleScript, Awk, BNF, Ballerina, Base Makefile, Bash, Batchfile, BlitzBasic, Brainfuck, C, C#, C++, CFEngine3, CMake, COBOL, CSS, Cap'n Proto, Ceylon, ChaiScript, Cheetah, Clojure, CoffeeScript, Common Lisp, Coq, Crystal, Cython, DTD, Dart, Diff, Django/Jinja, Docker, EBNF, Elixir, Elm, EmacsLisp, Erlang, FSharp, Factor, Fish, Forth, Fortran, GAS, GDScript, GLSL, Genshi, Genshi HTML, Genshi Text, Gnuplot, Go, Go HTML Template, Go Text Template, Groovy, HTML, HTTP, Handlebars, Haskell, Haxe, Hexdump, Hy, INI, Idris, Io, JSON, JSX, Java, JavaScript, Julia, Kotlin, LLVM, Lighttpd configuration file, Lua, Mako, Mason, Mathematica, MiniZinc, Modula-2, MorrowindScript, MySQL, Myghty, NASM, Newspeak, Nginx configuration file, Nim, Nix, OCaml, Objective-C, Octave, Org Mode, PHP, PL/pgSQL, POVRay, PacmanConf, Perl, Pig, PkgConfig, PostScript, PostgreSQL SQL dialect, PowerShell, Prolog, Protocol Buffer, Puppet, Python, Python 3, QBasic, R, Racket, Ragel, Rexx, Ruby, Rust, SCSS, SPARQL, SQL, Sass, Scala, Scheme, Scilab, Smalltalk, Smarty, Snobol, Solidity, SquidConf, Swift, TASM, TOML, Tcl, Tcsh, TeX, Termcap, Terminfo, Terraform, Thrift, Transact-SQL, Turtle, Twig, TypeScript, TypoScript, TypoScriptCssData, TypoScriptHtmlData, VHDL, VimL, WDTE, XML, Xorg, YAML, cfstatement, markdown, reStructuredText, reg, systemverilog, verilog Prefix | Language
:----: | --------
A | ABNF, ActionScript, ActionScript 3, Ada, Angular2, ANTLR, ApacheConf, APL, AppleScript, Awk
B | Ballerina, Base Makefile, Bash, Batchfile, BlitzBasic, BNF, Brainfuck
C | C, C#, C++, Cassandra CQL, CFEngine3, cfstatement/ColdFusion, CMake, COBOL, CSS, Cap'n Proto, Ceylon, ChaiScript, Cheetah, Clojure, CoffeeScript, Common Lisp, Coq, Crystal, Cython
D | Dart, Diff, Django/Jinja, Docker, DTD
E | EBNF, Elixir, Elm, EmacsLisp, Erlang
F | Factor, Fish, Forth, Fortran, FSharp
G | GAS, GDScript, GLSL, Genshi, Genshi HTML, Genshi Text, Gnuplot, Go, Go HTML Template, Go Text Template, Groovy
H | Handlebars, Haskell, Haxe, Hexdump, HTML, HTTP, Hy
I | Idris, INI, Io
J | Java, JavaScript, JSON, Jsx, Julia, Jungle
K | Kotlin
L | Lighttpd configuration file, LLVM, Lua
M | Mako, Markdown, Mason, Mathematica, MiniZinc, Modula-2, MonkeyC, MorrowindScript, Myghty, MySQL
N | NASM, Newspeak, Nginx configuration file, Nim, Nix
O | Objective-C, OCaml, Octave, OpenSCAD, Org Mode
P | PacmanConf, Perl, PHP, Pig, PkgConfig, Plaintext, PL/pgSQL, PostgreSQL SQL dialect, PostScript, POVRay, PowerShell, Prolog, Protocol Buffer, Puppet, Python, Python 3
Q | QBasic
R | R, Racket, Ragel, reg, reStructuredText, Rexx, Ruby, Rust
S | Sass, Scala, Scheme, Scilab, SCSS, Smalltalk, Smarty, Snobol, Solidity, SPARQL, SQL, SquidConf, Swift, systemd, Systemverilog
T | TASM, Tcl, Tcsh, Termcap, Terminfo, Terraform, TeX, Thrift, TOML, TradingView, Transact-SQL, Turtle, Twig, TypeScript, TypoScript, TypoScriptCssData, TypoScriptHtmlData
V | verilog, VHDL, VimL
W | WDTE
X | XML, Xorg
Y | YAML
_I will attempt to keep this section up to date, but an authoritative list can be _I will attempt to keep this section up to date, but an authoritative list can be
displayed with `chroma --list`._ displayed with `chroma --list`._

View File

@ -6,17 +6,17 @@ func Coalesce(lexer Lexer) Lexer { return &coalescer{lexer} }
type coalescer struct{ Lexer } type coalescer struct{ Lexer }
func (d *coalescer) Tokenise(options *TokeniseOptions, text string) (Iterator, error) { func (d *coalescer) Tokenise(options *TokeniseOptions, text string) (Iterator, error) {
var prev *Token var prev Token
it, err := d.Lexer.Tokenise(options, text) it, err := d.Lexer.Tokenise(options, text)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return func() *Token { return func() Token {
for token := it(); token != nil; token = it() { for token := it(); token != (EOF); token = it() {
if len(token.Value) == 0 { if len(token.Value) == 0 {
continue continue
} }
if prev == nil { if prev == EOF {
prev = token prev = token
} else { } else {
if prev.Type == token.Type && len(prev.Value) < 8192 { if prev.Type == token.Type && len(prev.Value) < 8192 {
@ -29,7 +29,7 @@ func (d *coalescer) Tokenise(options *TokeniseOptions, text string) (Iterator, e
} }
} }
out := prev out := prev
prev = nil prev = EOF
return out return out
}, nil }, nil
} }

View File

@ -31,7 +31,7 @@ func (d *delegatingLexer) Config() *Config {
// An insertion is the character range where language tokens should be inserted. // An insertion is the character range where language tokens should be inserted.
type insertion struct { type insertion struct {
start, end int start, end int
tokens []*Token tokens []Token
} }
func (d *delegatingLexer) Tokenise(options *TokeniseOptions, text string) (Iterator, error) { func (d *delegatingLexer) Tokenise(options *TokeniseOptions, text string) (Iterator, error) {
@ -44,15 +44,15 @@ func (d *delegatingLexer) Tokenise(options *TokeniseOptions, text string) (Itera
insertions := []*insertion{} insertions := []*insertion{}
var insert *insertion var insert *insertion
offset := 0 offset := 0
var last *Token var last Token
for _, t := range tokens { for _, t := range tokens {
if t.Type == Other { if t.Type == Other {
if last != nil && insert != nil && last.Type != Other { if last != EOF && insert != nil && last.Type != Other {
insert.end = offset insert.end = offset
} }
others.WriteString(t.Value) others.WriteString(t.Value)
} else { } else {
if last == nil || last.Type == Other { if last == EOF || last.Type == Other {
insert = &insertion{start: offset} insert = &insertion{start: offset}
insertions = append(insertions, insert) insertions = append(insertions, insert)
} }
@ -73,12 +73,12 @@ func (d *delegatingLexer) Tokenise(options *TokeniseOptions, text string) (Itera
} }
// Interleave the two sets of tokens. // Interleave the two sets of tokens.
out := []*Token{} var out []Token
offset = 0 // Offset into text. offset = 0 // Offset into text.
tokenIndex := 0 tokenIndex := 0
nextToken := func() *Token { nextToken := func() Token {
if tokenIndex >= len(rootTokens) { if tokenIndex >= len(rootTokens) {
return nil return EOF
} }
t := rootTokens[tokenIndex] t := rootTokens[tokenIndex]
tokenIndex++ tokenIndex++
@ -95,18 +95,18 @@ func (d *delegatingLexer) Tokenise(options *TokeniseOptions, text string) (Itera
} }
t := nextToken() t := nextToken()
i := nextInsertion() i := nextInsertion()
for t != nil || i != nil { for t != EOF || i != nil {
// fmt.Printf("%d->%d:%q %d->%d:%q\n", offset, offset+len(t.Value), t.Value, i.start, i.end, Stringify(i.tokens...)) // fmt.Printf("%d->%d:%q %d->%d:%q\n", offset, offset+len(t.Value), t.Value, i.start, i.end, Stringify(i.tokens...))
if t == nil || (i != nil && i.start < offset+len(t.Value)) { if t == EOF || (i != nil && i.start < offset+len(t.Value)) {
var l *Token var l Token
l, t = splitToken(t, i.start-offset) l, t = splitToken(t, i.start-offset)
if l != nil { if l != EOF {
out = append(out, l) out = append(out, l)
offset += len(l.Value) offset += len(l.Value)
} }
out = append(out, i.tokens...) out = append(out, i.tokens...)
offset += i.end - i.start offset += i.end - i.start
if t == nil { if t == EOF {
t = nextToken() t = nextToken()
} }
i = nextInsertion() i = nextInsertion()
@ -119,15 +119,15 @@ func (d *delegatingLexer) Tokenise(options *TokeniseOptions, text string) (Itera
return Literator(out...), nil return Literator(out...), nil
} }
func splitToken(t *Token, offset int) (l *Token, r *Token) { func splitToken(t Token, offset int) (l Token, r Token) {
if t == nil { if t == EOF {
return nil, nil return EOF, EOF
} }
if offset == 0 { if offset == 0 {
return nil, t return EOF, t
} }
if offset == len(t.Value) { if offset == len(t.Value) {
return t, nil return t, EOF
} }
l = t.Clone() l = t.Clone()
r = t.Clone() r = t.Clone()

View File

@ -11,7 +11,7 @@ import (
var ( var (
// NoOp formatter. // NoOp formatter.
NoOp = Register("noop", chroma.FormatterFunc(func(w io.Writer, s *chroma.Style, iterator chroma.Iterator) error { NoOp = Register("noop", chroma.FormatterFunc(func(w io.Writer, s *chroma.Style, iterator chroma.Iterator) error {
for t := iterator(); t != nil; t = iterator() { for t := iterator(); t != chroma.EOF; t = iterator() {
if _, err := io.WriteString(w, t.Value); err != nil { if _, err := io.WriteString(w, t.Value); err != nil {
return err return err
} }

View File

@ -25,6 +25,9 @@ func WithClasses() Option { return func(f *Formatter) { f.Classes = true } }
// TabWidth sets the number of characters for a tab. Defaults to 8. // TabWidth sets the number of characters for a tab. Defaults to 8.
func TabWidth(width int) Option { return func(f *Formatter) { f.tabWidth = width } } func TabWidth(width int) Option { return func(f *Formatter) { f.tabWidth = width } }
// PreventSurroundingPre prevents the surrounding pre tags around the generated code
func PreventSurroundingPre() Option { return func(f *Formatter) { f.preventSurroundingPre = true } }
// WithLineNumbers formats output with line numbers. // WithLineNumbers formats output with line numbers.
func WithLineNumbers() Option { func WithLineNumbers() Option {
return func(f *Formatter) { return func(f *Formatter) {
@ -73,6 +76,7 @@ type Formatter struct {
standalone bool standalone bool
prefix string prefix string
Classes bool // Exported field to detect when classes are being used Classes bool // Exported field to detect when classes are being used
preventSurroundingPre bool
tabWidth int tabWidth int
lineNumbers bool lineNumbers bool
lineNumbersInTable bool lineNumbersInTable bool
@ -125,7 +129,7 @@ func (f *Formatter) restyle(style *chroma.Style) (*chroma.Style, error) {
// We deliberately don't use html/template here because it is two orders of magnitude slower (benchmarked). // We deliberately don't use html/template here because it is two orders of magnitude slower (benchmarked).
// //
// OTOH we need to be super careful about correct escaping... // OTOH we need to be super careful about correct escaping...
func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []*chroma.Token) (err error) { // nolint: gocyclo func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.Token) (err error) { // nolint: gocyclo
style, err = f.restyle(style) style, err = f.restyle(style)
if err != nil { if err != nil {
return err return err
@ -149,7 +153,7 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []*chroma
wrapInTable := f.lineNumbers && f.lineNumbersInTable wrapInTable := f.lineNumbers && f.lineNumbersInTable
lines := splitTokensIntoLines(tokens) lines := chroma.SplitTokensIntoLines(tokens)
lineDigits := len(fmt.Sprintf("%d", len(lines))) lineDigits := len(fmt.Sprintf("%d", len(lines)))
highlightIndex := 0 highlightIndex := 0
@ -158,7 +162,9 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []*chroma
fmt.Fprintf(w, "<div%s>\n", f.styleAttr(css, chroma.Background)) fmt.Fprintf(w, "<div%s>\n", f.styleAttr(css, chroma.Background))
fmt.Fprintf(w, "<table%s><tr>", f.styleAttr(css, chroma.LineTable)) fmt.Fprintf(w, "<table%s><tr>", f.styleAttr(css, chroma.LineTable))
fmt.Fprintf(w, "<td%s>\n", f.styleAttr(css, chroma.LineTableTD)) fmt.Fprintf(w, "<td%s>\n", f.styleAttr(css, chroma.LineTableTD))
if !f.preventSurroundingPre {
fmt.Fprintf(w, "<pre%s>", f.styleAttr(css, chroma.Background)) fmt.Fprintf(w, "<pre%s>", f.styleAttr(css, chroma.Background))
}
for index := range lines { for index := range lines {
line := f.baseLineNumber + index line := f.baseLineNumber + index
highlight, next := f.shouldHighlight(highlightIndex, line) highlight, next := f.shouldHighlight(highlightIndex, line)
@ -175,11 +181,16 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []*chroma
fmt.Fprintf(w, "</span>") fmt.Fprintf(w, "</span>")
} }
} }
fmt.Fprint(w, "</pre></td>\n") if !f.preventSurroundingPre {
fmt.Fprint(w, "</pre>")
}
fmt.Fprint(w, "</td>\n")
fmt.Fprintf(w, "<td%s>\n", f.styleAttr(css, chroma.LineTableTD)) fmt.Fprintf(w, "<td%s>\n", f.styleAttr(css, chroma.LineTableTD))
} }
if !f.preventSurroundingPre {
fmt.Fprintf(w, "<pre%s>", f.styleAttr(css, chroma.Background)) fmt.Fprintf(w, "<pre%s>", f.styleAttr(css, chroma.Background))
}
highlightIndex = 0 highlightIndex = 0
for index, tokens := range lines { for index, tokens := range lines {
// 1-based line number. // 1-based line number.
@ -209,7 +220,9 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []*chroma
} }
} }
if !f.preventSurroundingPre {
fmt.Fprint(w, "</pre>") fmt.Fprint(w, "</pre>")
}
if wrapInTable { if wrapInTable {
fmt.Fprint(w, "</td></tr></table>\n") fmt.Fprint(w, "</td></tr></table>\n")
@ -377,26 +390,3 @@ func compressStyle(s string) string {
} }
return strings.Join(out, ";") return strings.Join(out, ";")
} }
func splitTokensIntoLines(tokens []*chroma.Token) (out [][]*chroma.Token) {
line := []*chroma.Token{}
for _, token := range tokens {
for strings.Contains(token.Value, "\n") {
parts := strings.SplitAfterN(token.Value, "\n", 2)
// Token becomes the tail.
token.Value = parts[1]
// Append the head to the line and flush the line.
clone := token.Clone()
clone.Value = parts[0]
line = append(line, clone)
out = append(out, line)
line = nil
}
line = append(line, token)
}
if len(line) > 0 {
out = append(out, line)
}
return
}

View File

@ -12,7 +12,7 @@ import (
var JSON = Register("json", chroma.FormatterFunc(func(w io.Writer, s *chroma.Style, it chroma.Iterator) error { var JSON = Register("json", chroma.FormatterFunc(func(w io.Writer, s *chroma.Style, it chroma.Iterator) error {
fmt.Fprintln(w, "[") fmt.Fprintln(w, "[")
i := 0 i := 0
for t := it(); t != nil; t = it() { for t := it(); t != chroma.EOF; t = it() {
if i > 0 { if i > 0 {
fmt.Fprintln(w, ",") fmt.Fprintln(w, ",")
} }

View File

@ -9,7 +9,7 @@ import (
// Tokens formatter outputs the raw token structures. // Tokens formatter outputs the raw token structures.
var Tokens = Register("tokens", chroma.FormatterFunc(func(w io.Writer, s *chroma.Style, it chroma.Iterator) error { var Tokens = Register("tokens", chroma.FormatterFunc(func(w io.Writer, s *chroma.Style, it chroma.Iterator) error {
for t := it(); t != nil; t = it() { for t := it(); t != chroma.EOF; t = it() {
if _, err := fmt.Fprintln(w, t.GoString()); err != nil { if _, err := fmt.Fprintln(w, t.GoString()); err != nil {
return err return err
} }

View File

@ -216,7 +216,7 @@ func (c *indexedTTYFormatter) Format(w io.Writer, style *chroma.Style, it chroma
} }
}() }()
theme := styleToEscapeSequence(c.table, style) theme := styleToEscapeSequence(c.table, style)
for token := it(); token != nil; token = it() { for token := it(); token != chroma.EOF; token = it() {
// TODO: Cache token lookups? // TODO: Cache token lookups?
clr, ok := theme[token.Type] clr, ok := theme[token.Type]
if !ok { if !ok {

View File

@ -11,7 +11,7 @@ import (
var TTY16m = Register("terminal16m", chroma.FormatterFunc(trueColourFormatter)) var TTY16m = Register("terminal16m", chroma.FormatterFunc(trueColourFormatter))
func trueColourFormatter(w io.Writer, style *chroma.Style, it chroma.Iterator) error { func trueColourFormatter(w io.Writer, style *chroma.Style, it chroma.Iterator) error {
for token := it(); token != nil; token = it() { for token := it(); token != chroma.EOF; token = it() {
entry := style.Get(token.Type) entry := style.Get(token.Type)
if !entry.IsZero() { if !entry.IsZero() {
out := "" out := ""

14
vendor/github.com/alecthomas/chroma/go.mod generated vendored Normal file
View File

@ -0,0 +1,14 @@
module github.com/alecthomas/chroma
require (
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 // indirect
github.com/alecthomas/kong v0.1.15
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 // indirect
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964
github.com/dlclark/regexp2 v1.1.6
github.com/mattn/go-colorable v0.0.9
github.com/mattn/go-isatty v0.0.4
github.com/sergi/go-diff v1.0.0 // indirect
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35 // indirect
)

26
vendor/github.com/alecthomas/chroma/go.sum generated vendored Normal file
View File

@ -0,0 +1,26 @@
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U=
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI=
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo=
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0=
github.com/alecthomas/kong v0.1.15 h1:IWBg+KrLvoHBicD50OzMI8fKjrtAa1okMR9g38HVM/s=
github.com/alecthomas/kong v0.1.15/go.mod h1:0m2VYms8rH0qbCqVB2gvGHk74bqLIq0HXjCs5bNbNQU=
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 h1:p9Sln00KOTlrYkxI1zYWl1QLnEqAqEARBEYa8FQnQcY=
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dlclark/regexp2 v1.1.6 h1:CqB4MjHw0MFCDj+PHHjiESmHX+N7t0tJzKvC6M97BRg=
github.com/dlclark/regexp2 v1.1.6/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35 h1:YAFjXN64LMvktoUZH9zgY4lGc/msGN7HQfoSuKCgaDU=
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=

View File

@ -1,16 +1,18 @@
package chroma package chroma
import "strings"
// An Iterator across tokens. // An Iterator across tokens.
// //
// nil will be returned at the end of the Token stream. // nil will be returned at the end of the Token stream.
// //
// If an error occurs within an Iterator, it may propagate this in a panic. Formatters should recover. // If an error occurs within an Iterator, it may propagate this in a panic. Formatters should recover.
type Iterator func() *Token type Iterator func() Token
// Tokens consumes all tokens from the iterator and returns them as a slice. // Tokens consumes all tokens from the iterator and returns them as a slice.
func (i Iterator) Tokens() []*Token { func (i Iterator) Tokens() []Token {
out := []*Token{} var out []Token
for t := i(); t != nil; t = i() { for t := i(); t != EOF; t = i() {
out = append(out, t) out = append(out, t)
} }
return out return out
@ -18,26 +20,56 @@ func (i Iterator) Tokens() []*Token {
// Concaterator concatenates tokens from a series of iterators. // Concaterator concatenates tokens from a series of iterators.
func Concaterator(iterators ...Iterator) Iterator { func Concaterator(iterators ...Iterator) Iterator {
return func() *Token { return func() Token {
for len(iterators) > 0 { for len(iterators) > 0 {
t := iterators[0]() t := iterators[0]()
if t != nil { if t != EOF {
return t return t
} }
iterators = iterators[1:] iterators = iterators[1:]
} }
return nil return EOF
} }
} }
// Literator converts a sequence of literal Tokens into an Iterator. // Literator converts a sequence of literal Tokens into an Iterator.
func Literator(tokens ...*Token) Iterator { func Literator(tokens ...Token) Iterator {
return func() (out *Token) { return func() Token {
if len(tokens) == 0 { if len(tokens) == 0 {
return nil return EOF
} }
token := tokens[0] token := tokens[0]
tokens = tokens[1:] tokens = tokens[1:]
return token return token
} }
} }
func SplitTokensIntoLines(tokens []Token) (out [][]Token) {
var line []Token
for _, token := range tokens {
for strings.Contains(token.Value, "\n") {
parts := strings.SplitAfterN(token.Value, "\n", 2)
// Token becomes the tail.
token.Value = parts[1]
// Append the head to the line and flush the line.
clone := token.Clone()
clone.Value = parts[0]
line = append(line, clone)
out = append(out, line)
line = nil
}
line = append(line, token)
}
if len(line) > 0 {
out = append(out, line)
}
// Strip empty trailing token line.
if len(out) > 0 {
last := out[len(out)-1]
if len(last) == 1 && last[0].Value == "" {
out = out[:len(out)-1]
}
}
return
}

View File

@ -66,12 +66,12 @@ type Token struct {
func (t *Token) String() string { return t.Value } func (t *Token) String() string { return t.Value }
func (t *Token) GoString() string { return fmt.Sprintf("&Token{%s, %q}", t.Type, t.Value) } func (t *Token) GoString() string { return fmt.Sprintf("&Token{%s, %q}", t.Type, t.Value) }
func (t *Token) Clone() *Token { func (t *Token) Clone() Token {
clone := &Token{} return *t
*clone = *t
return clone
} }
var EOF Token
type TokeniseOptions struct { type TokeniseOptions struct {
// State to start tokenisation in. Defaults to "root". // State to start tokenisation in. Defaults to "root".
State string State string

View File

@ -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(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}, {"\\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}, {`\A#!.+\n`, CommentPreproc, nil},
{`#.*\n`, CommentSingle, nil}, {`#.*\S`, CommentSingle, nil},
{`\\[\w\W]`, LiteralStringEscape, nil}, {`\\[\w\W]`, LiteralStringEscape, nil},
{`(\b\w+)(\s*)(\+?=)`, ByGroups(NameVariable, Text, Operator), nil}, {`(\b\w+)(\s*)(\+?=)`, ByGroups(NameVariable, Text, Operator), nil},
{`[\[\]{}()=]`, Operator, nil}, {`[\[\]{}()=]`, Operator, nil},

View File

@ -36,9 +36,9 @@ var Elixir = internal.Register(MustNewLexer(
{`\\\\|\<\<|\>\>|\=\>|\(|\)|\:|\;|\,|\[|\]`, Punctuation, nil}, {`\\\\|\<\<|\>\>|\=\>|\(|\)|\:|\;|\,|\[|\]`, Punctuation, nil},
{`&\d`, NameEntity, nil}, {`&\d`, NameEntity, nil},
{`\<|\>|\+|\-|\*|\/|\!|\^|\&`, Operator, nil}, {`\<|\>|\+|\-|\*|\/|\!|\^|\&`, Operator, nil},
{`0b[01]+`, LiteralNumberBin, nil}, {`0b[01](_?[01])*`, LiteralNumberBin, nil},
{`0o[0-7]+`, LiteralNumberOct, nil}, {`0o[0-7](_?[0-7])*`, LiteralNumberOct, nil},
{`0x[\da-fA-F]+`, LiteralNumberHex, nil}, {`0x[\da-fA-F](_?[\dA-Fa-f])*`, LiteralNumberHex, nil},
{`\d(_?\d)*\.\d(_?\d)*([eE][-+]?\d(_?\d)*)?`, LiteralNumberFloat, nil}, {`\d(_?\d)*\.\d(_?\d)*([eE][-+]?\d(_?\d)*)?`, LiteralNumberFloat, nil},
{`\d(_?\d)*`, LiteralNumberInteger, nil}, {`\d(_?\d)*`, LiteralNumberInteger, nil},
{`"""\s*`, LiteralStringHeredoc, Push("heredoc_double")}, {`"""\s*`, LiteralStringHeredoc, Push("heredoc_double")},

View File

@ -42,6 +42,7 @@ var Go = internal.Register(MustNewLexer(
{"(`)([^`]*)(`)", ByGroups(LiteralString, Using(TypeRemappingLexer(GoTextTemplate, TypeMapping{{Other, LiteralString, nil}})), LiteralString), nil}, {"(`)([^`]*)(`)", ByGroups(LiteralString, Using(TypeRemappingLexer(GoTextTemplate, TypeMapping{{Other, LiteralString, nil}})), LiteralString), nil},
{`"(\\\\|\\"|[^"])*"`, LiteralString, nil}, {`"(\\\\|\\"|[^"])*"`, LiteralString, nil},
{`(<<=|>>=|<<|>>|<=|>=|&\^=|&\^|\+=|-=|\*=|/=|%=|&=|\|=|&&|\|\||<-|\+\+|--|==|!=|:=|\.\.\.|[+\-*/%&])`, Operator, nil}, {`(<<=|>>=|<<|>>|<=|>=|&\^=|&\^|\+=|-=|\*=|/=|%=|&=|\|=|&&|\|\||<-|\+\+|--|==|!=|:=|\.\.\.|[+\-*/%&])`, Operator, nil},
{`([a-zA-Z_]\w*)(\s*)(\()`, ByGroups(NameFunction, UsingSelf("root"), Punctuation), nil},
{`[|^<>=!()\[\]{}.,;:]`, Punctuation, nil}, {`[|^<>=!()\[\]{}.,;:]`, Punctuation, nil},
{`[^\W\d]\w*`, NameOther, nil}, {`[^\W\d]\w*`, NameOther, nil},
}, },

View File

@ -34,7 +34,7 @@ var HTTP = internal.Register(httpBodyContentTypeLexer(MustNewLexer(
))) )))
func httpContentBlock(groups []string, lexer Lexer) Iterator { func httpContentBlock(groups []string, lexer Lexer) Iterator {
tokens := []*Token{ tokens := []Token{
{Generic, groups[0]}, {Generic, groups[0]},
} }
return Literator(tokens...) return Literator(tokens...)
@ -42,7 +42,7 @@ func httpContentBlock(groups []string, lexer Lexer) Iterator {
} }
func httpHeaderBlock(groups []string, lexer Lexer) Iterator { func httpHeaderBlock(groups []string, lexer Lexer) Iterator {
tokens := []*Token{ tokens := []Token{
{Name, groups[1]}, {Name, groups[1]},
{Text, groups[2]}, {Text, groups[2]},
{Operator, groups[3]}, {Operator, groups[3]},
@ -54,7 +54,7 @@ func httpHeaderBlock(groups []string, lexer Lexer) Iterator {
} }
func httpContinuousHeaderBlock(groups []string, lexer Lexer) Iterator { func httpContinuousHeaderBlock(groups []string, lexer Lexer) Iterator {
tokens := []*Token{ tokens := []Token{
{Text, groups[1]}, {Text, groups[1]},
{Literal, groups[2]}, {Literal, groups[2]},
{Text, groups[3]}, {Text, groups[3]},
@ -76,8 +76,8 @@ func (d *httpBodyContentTyper) Tokenise(options *TokeniseOptions, text string) (
return nil, err return nil, err
} }
return func() *Token { return func() Token {
for token := it(); token != nil; token = it() { for token := it(); token != EOF; token = it() {
switch { switch {
case token.Type == Name && strings.ToLower(token.Value) == "content-type": case token.Type == Name && strings.ToLower(token.Value) == "content-type":
{ {
@ -85,6 +85,7 @@ func (d *httpBodyContentTyper) Tokenise(options *TokeniseOptions, text string) (
} }
case token.Type == Literal && isContentType: case token.Type == Literal && isContentType:
{ {
isContentType = false
contentType = strings.TrimSpace(token.Value) contentType = strings.TrimSpace(token.Value)
pos := strings.Index(contentType, ";") pos := strings.Index(contentType, ";")
if pos > 0 { if pos > 0 {
@ -111,7 +112,7 @@ func (d *httpBodyContentTyper) Tokenise(options *TokeniseOptions, text string) (
if err != nil { if err != nil {
panic(err) panic(err)
} }
return nil return EOF
} }
} }
@ -121,11 +122,11 @@ func (d *httpBodyContentTyper) Tokenise(options *TokeniseOptions, text string) (
} }
if subIterator != nil { if subIterator != nil {
for token := subIterator(); token != nil; token = subIterator() { for token := subIterator(); token != EOF; token = subIterator() {
return token return token
} }
} }
return nil return EOF
}, nil }, nil
} }

View File

@ -61,7 +61,7 @@ var Restructuredtext = internal.Register(MustNewLexer(
func rstCodeBlock(groups []string, lexer Lexer) Iterator { func rstCodeBlock(groups []string, lexer Lexer) Iterator {
iterators := []Iterator{} iterators := []Iterator{}
tokens := []*Token{ tokens := []Token{
{Punctuation, groups[1]}, {Punctuation, groups[1]},
{Text, groups[2]}, {Text, groups[2]},
{OperatorWord, groups[3]}, {OperatorWord, groups[3]},
@ -73,7 +73,7 @@ func rstCodeBlock(groups []string, lexer Lexer) Iterator {
code := strings.Join(groups[8:], "") code := strings.Join(groups[8:], "")
lexer = internal.Get(groups[6]) lexer = internal.Get(groups[6])
if lexer == nil { if lexer == nil {
tokens = append(tokens, &Token{String, code}) tokens = append(tokens, Token{String, code})
iterators = append(iterators, Literator(tokens...)) iterators = append(iterators, Literator(tokens...))
} else { } else {
sub, err := lexer.Tokenise(nil, code) sub, err := lexer.Tokenise(nil, code)

View File

@ -15,13 +15,13 @@ var Sass = internal.Register(MustNewLexer(
CaseInsensitive: true, CaseInsensitive: true,
}, },
Rules{ Rules{
// "root": {
// },
"root": { "root": {
{`[ \t]*\n`, Text, nil}, {`[ \t]*\n`, Text, nil},
// { `[ \t]*`, ?? <function _indentation at 0x10fcaf1e0> ??, nil }, // { `[ \t]*`, ?? <function _indentation at 0x106932e18> ??, nil },
}, // { `//[^\n]*`, ?? <function _starts_block.<locals>.callback at 0x106936048> ??, Push("root") },
"content": { // { `/\*[^\n]*`, ?? <function _starts_block.<locals>.callback at 0x1069360d0> ??, Push("root") },
// { `//[^\n]*`, ?? <function _starts_block.<locals>.callback at 0x10fcaf378> ??, Push("root") },
// { `/\*[^\n]*`, ?? <function _starts_block.<locals>.callback at 0x10fcaf400> ??, Push("root") },
{`@import`, Keyword, Push("import")}, {`@import`, Keyword, Push("import")},
{`@for`, Keyword, Push("for")}, {`@for`, Keyword, Push("for")},
{`@(debug|warn|if|while)`, Keyword, Push("value")}, {`@(debug|warn|if|while)`, Keyword, Push("value")},
@ -112,9 +112,9 @@ var Sass = internal.Register(MustNewLexer(
{`"`, LiteralStringDouble, Pop(1)}, {`"`, LiteralStringDouble, Pop(1)},
}, },
"string-single": { "string-single": {
{`(\\.|#(?=[^\n{])|[^\n'#])+`, LiteralStringDouble, nil}, {`(\\.|#(?=[^\n{])|[^\n'#])+`, LiteralStringSingle, nil},
{`#\{`, LiteralStringInterpol, Push("interpolation")}, {`#\{`, LiteralStringInterpol, Push("interpolation")},
{`'`, LiteralStringDouble, Pop(1)}, {`'`, LiteralStringSingle, Pop(1)},
}, },
"string-url": { "string-url": {
{`(\\#|#(?=[^\n{])|[^\n#)])+`, LiteralStringOther, nil}, {`(\\#|#(?=[^\n{])|[^\n#)])+`, LiteralStringOther, nil},

View File

@ -0,0 +1,28 @@
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)},
},
},
))

View File

@ -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},
},
},
))

73
vendor/github.com/alecthomas/chroma/lexers/v/vb.go generated vendored Normal file
View File

@ -0,0 +1,73 @@
package v
import (
. "github.com/alecthomas/chroma" // nolint
"github.com/alecthomas/chroma/lexers/internal"
)
const vbName = `[_\w][\w]*`
// VB.Net lexer.
var VBNet = internal.Register(MustNewLexer(
&Config{
Name: "VB.net",
Aliases: []string{"vb.net", "vbnet"},
Filenames: []string{"*.vb", "*.bas"},
MimeTypes: []string{"text/x-vbnet", "text/x-vba"},
CaseInsensitive: true,
},
Rules{
"root": {
{`^\s*<.*?>`, NameAttribute, nil},
{`\s+`, Text, nil},
{`\n`, Text, nil},
{`rem\b.*?\n`, Comment, nil},
{`'.*?\n`, Comment, nil},
{`#If\s.*?\sThen|#ElseIf\s.*?\sThen|#Else|#End\s+If|#Const|#ExternalSource.*?\n|#End\s+ExternalSource|#Region.*?\n|#End\s+Region|#ExternalChecksum`, CommentPreproc, nil},
{`[(){}!#,.:]`, Punctuation, nil},
{`Option\s+(Strict|Explicit|Compare)\s+(On|Off|Binary|Text)`, KeywordDeclaration, nil},
{Words(`(?<!\.)`, `\b`, `AddHandler`, `Alias`, `ByRef`, `ByVal`, `Call`, `Case`, `Catch`, `CBool`, `CByte`, `CChar`, `CDate`, `CDec`, `CDbl`, `CInt`, `CLng`, `CObj`, `Continue`, `CSByte`, `CShort`, `CSng`, `CStr`, `CType`, `CUInt`, `CULng`, `CUShort`, `Declare`, `Default`, `Delegate`, `DirectCast`, `Do`, `Each`, `Else`, `ElseIf`, `EndIf`, `Erase`, `Error`, `Event`, `Exit`, `False`, `Finally`, `For`, `Friend`, `Get`, `Global`, `GoSub`, `GoTo`, `Handles`, `If`, `Implements`, `Inherits`, `Interface`, `Let`, `Lib`, `Loop`, `Me`, `MustInherit`, `MustOverride`, `MyBase`, `MyClass`, `Narrowing`, `New`, `Next`, `Not`, `Nothing`, `NotInheritable`, `NotOverridable`, `Of`, `On`, `Operator`, `Option`, `Optional`, `Overloads`, `Overridable`, `Overrides`, `ParamArray`, `Partial`, `Private`, `Protected`, `Public`, `RaiseEvent`, `ReadOnly`, `ReDim`, `RemoveHandler`, `Resume`, `Return`, `Select`, `Set`, `Shadows`, `Shared`, `Single`, `Static`, `Step`, `Stop`, `SyncLock`, `Then`, `Throw`, `To`, `True`, `Try`, `TryCast`, `Wend`, `Using`, `When`, `While`, `Widening`, `With`, `WithEvents`, `WriteOnly`), Keyword, nil},
{`(?<!\.)End\b`, Keyword, Push("end")},
{`(?<!\.)(Dim|Const)\b`, Keyword, Push("dim")},
{`(?<!\.)(Function|Sub|Property)(\s+)`, ByGroups(Keyword, Text), Push("funcname")},
{`(?<!\.)(Class|Structure|Enum)(\s+)`, ByGroups(Keyword, Text), Push("classname")},
{`(?<!\.)(Module|Namespace|Imports)(\s+)`, ByGroups(Keyword, Text), Push("namespace")},
{`(?<!\.)(Boolean|Byte|Char|Date|Decimal|Double|Integer|Long|Object|SByte|Short|Single|String|Variant|UInteger|ULong|UShort)\b`, KeywordType, nil},
{`(?<!\.)(AddressOf|And|AndAlso|As|GetType|In|Is|IsNot|Like|Mod|Or|OrElse|TypeOf|Xor)\b`, OperatorWord, nil},
{`&=|[*]=|/=|\\=|\^=|\+=|-=|<<=|>>=|<<|>>|:=|<=|>=|<>|[-&*/\\^+=<>\[\]]`, Operator, nil},
{`"`, LiteralString, Push("string")},
{`_\n`, Text, nil},
{vbName, Name, nil},
{`#.*?#`, LiteralDate, nil},
{`(\d+\.\d*|\d*\.\d+)(F[+-]?[0-9]+)?`, LiteralNumberFloat, nil},
{`\d+([SILDFR]|US|UI|UL)?`, LiteralNumberInteger, nil},
{`&H[0-9a-f]+([SILDFR]|US|UI|UL)?`, LiteralNumberInteger, nil},
{`&O[0-7]+([SILDFR]|US|UI|UL)?`, LiteralNumberInteger, nil},
},
"string": {
{`""`, LiteralString, nil},
{`"C?`, LiteralString, Pop(1)},
{`[^"]+`, LiteralString, nil},
},
"dim": {
{vbName, NameVariable, Pop(1)},
Default(Pop(1)),
},
"funcname": {
{vbName, NameFunction, Pop(1)},
},
"classname": {
{vbName, NameClass, Pop(1)},
},
"namespace": {
{vbName, NameNamespace, nil},
{`\.`, NameNamespace, nil},
Default(Pop(1)),
},
"end": {
{`\s+`, Text, nil},
{`(Function|Sub|Property|Class|Structure|Enum|Module|Namespace)\b`, Keyword, Pop(1)},
Default(Pop(1)),
},
},
))

View File

@ -20,7 +20,7 @@ var YAML = internal.Register(MustNewLexer(
{`&[^\s]+`, CommentPreproc, nil}, {`&[^\s]+`, CommentPreproc, nil},
{`\*[^\s]+`, CommentPreproc, nil}, {`\*[^\s]+`, CommentPreproc, nil},
{`^%include\s+[^\n\r]+`, CommentPreproc, nil}, {`^%include\s+[^\n\r]+`, CommentPreproc, nil},
{`([>|])(\s+)((?:(?:.*?$)(?:[\n\r]*?\2)?)*)`, ByGroups(StringDoc, StringDoc, StringDoc), nil}, {`([>|+-]\s+)(\s+)((?:(?:.*?$)(?:[\n\r]*?)?)*)`, ByGroups(StringDoc, StringDoc, StringDoc), nil},
Include("value"), Include("value"),
{`[?:,\[\]]`, Punctuation, nil}, {`[?:,\[\]]`, Punctuation, nil},
{`.`, Text, nil}, {`.`, Text, nil},

View File

@ -122,7 +122,7 @@ func Default(mutators ...Mutator) Rule {
} }
// Stringify returns the raw string for a set of tokens. // Stringify returns the raw string for a set of tokens.
func Stringify(tokens ...*Token) string { func Stringify(tokens ...Token) string {
out := []string{} out := []string{}
for _, t := range tokens { for _, t := range tokens {
out = append(out, t.Value) out = append(out, t.Value)

View File

@ -140,13 +140,13 @@ func Words(prefix, suffix string, words ...string) string {
} }
// Tokenise text using lexer, returning tokens as a slice. // Tokenise text using lexer, returning tokens as a slice.
func Tokenise(lexer Lexer, options *TokeniseOptions, text string) ([]*Token, error) { func Tokenise(lexer Lexer, options *TokeniseOptions, text string) ([]Token, error) {
out := []*Token{} var out []Token
it, err := lexer.Tokenise(options, text) it, err := lexer.Tokenise(options, text)
if err != nil { if err != nil {
return nil, err return nil, err
} }
for t := it(); t != nil; t = it() { for t := it(); t != EOF; t = it() {
out = append(out, t) out = append(out, t)
} }
return out, nil return out, nil
@ -246,13 +246,13 @@ func (l *LexerState) Get(key interface{}) interface{} {
return l.MutatorContext[key] return l.MutatorContext[key]
} }
func (l *LexerState) Iterator() *Token { func (l *LexerState) Iterator() Token {
for l.Pos < len(l.Text) && len(l.Stack) > 0 { for l.Pos < len(l.Text) && len(l.Stack) > 0 {
// Exhaust the iterator stack, if any. // Exhaust the iterator stack, if any.
for len(l.iteratorStack) > 0 { for len(l.iteratorStack) > 0 {
n := len(l.iteratorStack) - 1 n := len(l.iteratorStack) - 1
t := l.iteratorStack[n]() t := l.iteratorStack[n]()
if t == nil { if t == EOF {
l.iteratorStack = l.iteratorStack[:n] l.iteratorStack = l.iteratorStack[:n]
continue continue
} }
@ -271,7 +271,7 @@ func (l *LexerState) Iterator() *Token {
// No match. // No match.
if groups == nil { if groups == nil {
l.Pos++ l.Pos++
return &Token{Error, string(l.Text[l.Pos-1 : l.Pos])} return Token{Error, string(l.Text[l.Pos-1 : l.Pos])}
} }
l.Rule = ruleIndex l.Rule = ruleIndex
l.Groups = groups l.Groups = groups
@ -290,7 +290,7 @@ func (l *LexerState) Iterator() *Token {
for len(l.iteratorStack) > 0 { for len(l.iteratorStack) > 0 {
n := len(l.iteratorStack) - 1 n := len(l.iteratorStack) - 1
t := l.iteratorStack[n]() t := l.iteratorStack[n]()
if t == nil { if t == EOF {
l.iteratorStack = l.iteratorStack[:n] l.iteratorStack = l.iteratorStack[:n]
continue continue
} }
@ -301,9 +301,9 @@ func (l *LexerState) Iterator() *Token {
if l.Pos != len(l.Text) && len(l.Stack) == 0 { if l.Pos != len(l.Text) && len(l.Stack) == 0 {
value := string(l.Text[l.Pos:]) value := string(l.Text[l.Pos:])
l.Pos = len(l.Text) l.Pos = len(l.Text)
return &Token{Type: Error, Value: value} return Token{Type: Error, Value: value}
} }
return nil return EOF
} }
type RegexLexer struct { type RegexLexer struct {

View File

@ -2,11 +2,11 @@ package chroma
type remappingLexer struct { type remappingLexer struct {
lexer Lexer lexer Lexer
mapper func(*Token) []*Token mapper func(Token) []Token
} }
// RemappingLexer remaps a token to a set of, potentially empty, tokens. // RemappingLexer remaps a token to a set of, potentially empty, tokens.
func RemappingLexer(lexer Lexer, mapper func(*Token) []*Token) Lexer { func RemappingLexer(lexer Lexer, mapper func(Token) []Token) Lexer {
return &remappingLexer{lexer, mapper} return &remappingLexer{lexer, mapper}
} }
@ -19,8 +19,8 @@ func (r *remappingLexer) Tokenise(options *TokeniseOptions, text string) (Iterat
if err != nil { if err != nil {
return nil, err return nil, err
} }
buffer := []*Token{} var buffer []Token
return func() *Token { return func() Token {
for { for {
if len(buffer) > 0 { if len(buffer) > 0 {
t := buffer[0] t := buffer[0]
@ -28,7 +28,7 @@ func (r *remappingLexer) Tokenise(options *TokeniseOptions, text string) (Iterat
return t return t
} }
t := it() t := it()
if t == nil { if t == EOF {
return t return t
} }
buffer = r.mapper(t) buffer = r.mapper(t)
@ -67,7 +67,7 @@ func TypeRemappingLexer(lexer Lexer, mapping TypeMapping) Lexer {
} }
} }
return RemappingLexer(lexer, func(t *Token) []*Token { return RemappingLexer(lexer, func(t Token) []Token {
if k, ok := lut[t.Type]; ok { if k, ok := lut[t.Type]; ok {
if tt, ok := k[t.Value]; ok { if tt, ok := k[t.Value]; ok {
t.Type = tt t.Type = tt
@ -75,6 +75,6 @@ func TypeRemappingLexer(lexer Lexer, mapping TypeMapping) Lexer {
t.Type = tt t.Type = tt
} }
} }
return []*Token{t} return []Token{t}
}) })
} }

View File

@ -2,9 +2,9 @@
package chroma package chroma
import "fmt" import "strconv"
const _TokenType_name = "NoneOtherErrorLineTableTDLineTableLineHighlightLineNumbersTableLineNumbersBackgroundKeywordKeywordConstantKeywordDeclarationKeywordNamespaceKeywordPseudoKeywordReservedKeywordTypeNameNameAttributeNameBuiltinNameBuiltinPseudoNameClassNameConstantNameDecoratorNameEntityNameExceptionNameFunctionNameFunctionMagicNameKeywordNameLabelNameNamespaceNameOperatorNameOtherNamePseudoNamePropertyNameTagNameVariableNameVariableAnonymousNameVariableClassNameVariableGlobalNameVariableInstanceNameVariableMagicLiteralLiteralDateLiteralOtherLiteralStringLiteralStringAffixLiteralStringAtomLiteralStringBacktickLiteralStringBooleanLiteralStringCharLiteralStringDelimiterLiteralStringDocLiteralStringDoubleLiteralStringEscapeLiteralStringHeredocLiteralStringInterpolLiteralStringNameLiteralStringOtherLiteralStringRegexLiteralStringSingleLiteralStringSymbolLiteralNumberLiteralNumberBinLiteralNumberFloatLiteralNumberHexLiteralNumberIntegerLiteralNumberIntegerLongLiteralNumberOctOperatorOperatorWordPunctuationCommentCommentHashbangCommentMultilineCommentSingleCommentSpecialCommentPreprocCommentPreprocFileGenericGenericDeletedGenericEmphGenericErrorGenericHeadingGenericInsertedGenericOutputGenericPromptGenericStrongGenericSubheadingGenericTracebackGenericUnderlineTextTextWhitespaceTextSymbolTextPunctuation" const _TokenType_name = "NoneOtherErrorLineTableTDLineTableLineHighlightLineNumbersTableLineNumbersBackgroundEOFTypeKeywordKeywordConstantKeywordDeclarationKeywordNamespaceKeywordPseudoKeywordReservedKeywordTypeNameNameAttributeNameBuiltinNameBuiltinPseudoNameClassNameConstantNameDecoratorNameEntityNameExceptionNameFunctionNameFunctionMagicNameKeywordNameLabelNameNamespaceNameOperatorNameOtherNamePseudoNamePropertyNameTagNameVariableNameVariableAnonymousNameVariableClassNameVariableGlobalNameVariableInstanceNameVariableMagicLiteralLiteralDateLiteralOtherLiteralStringLiteralStringAffixLiteralStringAtomLiteralStringBacktickLiteralStringBooleanLiteralStringCharLiteralStringDelimiterLiteralStringDocLiteralStringDoubleLiteralStringEscapeLiteralStringHeredocLiteralStringInterpolLiteralStringNameLiteralStringOtherLiteralStringRegexLiteralStringSingleLiteralStringSymbolLiteralNumberLiteralNumberBinLiteralNumberFloatLiteralNumberHexLiteralNumberIntegerLiteralNumberIntegerLongLiteralNumberOctOperatorOperatorWordPunctuationCommentCommentHashbangCommentMultilineCommentSingleCommentSpecialCommentPreprocCommentPreprocFileGenericGenericDeletedGenericEmphGenericErrorGenericHeadingGenericInsertedGenericOutputGenericPromptGenericStrongGenericSubheadingGenericTracebackGenericUnderlineTextTextWhitespaceTextSymbolTextPunctuation"
var _TokenType_map = map[TokenType]string{ var _TokenType_map = map[TokenType]string{
-9: _TokenType_name[0:4], -9: _TokenType_name[0:4],
@ -16,96 +16,97 @@ var _TokenType_map = map[TokenType]string{
-3: _TokenType_name[47:63], -3: _TokenType_name[47:63],
-2: _TokenType_name[63:74], -2: _TokenType_name[63:74],
-1: _TokenType_name[74:84], -1: _TokenType_name[74:84],
1000: _TokenType_name[84:91], 0: _TokenType_name[84:91],
1001: _TokenType_name[91:106], 1000: _TokenType_name[91:98],
1002: _TokenType_name[106:124], 1001: _TokenType_name[98:113],
1003: _TokenType_name[124:140], 1002: _TokenType_name[113:131],
1004: _TokenType_name[140:153], 1003: _TokenType_name[131:147],
1005: _TokenType_name[153:168], 1004: _TokenType_name[147:160],
1006: _TokenType_name[168:179], 1005: _TokenType_name[160:175],
2000: _TokenType_name[179:183], 1006: _TokenType_name[175:186],
2001: _TokenType_name[183:196], 2000: _TokenType_name[186:190],
2002: _TokenType_name[196:207], 2001: _TokenType_name[190:203],
2003: _TokenType_name[207:224], 2002: _TokenType_name[203:214],
2004: _TokenType_name[224:233], 2003: _TokenType_name[214:231],
2005: _TokenType_name[233:245], 2004: _TokenType_name[231:240],
2006: _TokenType_name[245:258], 2005: _TokenType_name[240:252],
2007: _TokenType_name[258:268], 2006: _TokenType_name[252:265],
2008: _TokenType_name[268:281], 2007: _TokenType_name[265:275],
2009: _TokenType_name[281:293], 2008: _TokenType_name[275:288],
2010: _TokenType_name[293:310], 2009: _TokenType_name[288:300],
2011: _TokenType_name[310:321], 2010: _TokenType_name[300:317],
2012: _TokenType_name[321:330], 2011: _TokenType_name[317:328],
2013: _TokenType_name[330:343], 2012: _TokenType_name[328:337],
2014: _TokenType_name[343:355], 2013: _TokenType_name[337:350],
2015: _TokenType_name[355:364], 2014: _TokenType_name[350:362],
2016: _TokenType_name[364:374], 2015: _TokenType_name[362:371],
2017: _TokenType_name[374:386], 2016: _TokenType_name[371:381],
2018: _TokenType_name[386:393], 2017: _TokenType_name[381:393],
2019: _TokenType_name[393:405], 2018: _TokenType_name[393:400],
2020: _TokenType_name[405:426], 2019: _TokenType_name[400:412],
2021: _TokenType_name[426:443], 2020: _TokenType_name[412:433],
2022: _TokenType_name[443:461], 2021: _TokenType_name[433:450],
2023: _TokenType_name[461:481], 2022: _TokenType_name[450:468],
2024: _TokenType_name[481:498], 2023: _TokenType_name[468:488],
3000: _TokenType_name[498:505], 2024: _TokenType_name[488:505],
3001: _TokenType_name[505:516], 3000: _TokenType_name[505:512],
3002: _TokenType_name[516:528], 3001: _TokenType_name[512:523],
3100: _TokenType_name[528:541], 3002: _TokenType_name[523:535],
3101: _TokenType_name[541:559], 3100: _TokenType_name[535:548],
3102: _TokenType_name[559:576], 3101: _TokenType_name[548:566],
3103: _TokenType_name[576:597], 3102: _TokenType_name[566:583],
3104: _TokenType_name[597:617], 3103: _TokenType_name[583:604],
3105: _TokenType_name[617:634], 3104: _TokenType_name[604:624],
3106: _TokenType_name[634:656], 3105: _TokenType_name[624:641],
3107: _TokenType_name[656:672], 3106: _TokenType_name[641:663],
3108: _TokenType_name[672:691], 3107: _TokenType_name[663:679],
3109: _TokenType_name[691:710], 3108: _TokenType_name[679:698],
3110: _TokenType_name[710:730], 3109: _TokenType_name[698:717],
3111: _TokenType_name[730:751], 3110: _TokenType_name[717:737],
3112: _TokenType_name[751:768], 3111: _TokenType_name[737:758],
3113: _TokenType_name[768:786], 3112: _TokenType_name[758:775],
3114: _TokenType_name[786:804], 3113: _TokenType_name[775:793],
3115: _TokenType_name[804:823], 3114: _TokenType_name[793:811],
3116: _TokenType_name[823:842], 3115: _TokenType_name[811:830],
3200: _TokenType_name[842:855], 3116: _TokenType_name[830:849],
3201: _TokenType_name[855:871], 3200: _TokenType_name[849:862],
3202: _TokenType_name[871:889], 3201: _TokenType_name[862:878],
3203: _TokenType_name[889:905], 3202: _TokenType_name[878:896],
3204: _TokenType_name[905:925], 3203: _TokenType_name[896:912],
3205: _TokenType_name[925:949], 3204: _TokenType_name[912:932],
3206: _TokenType_name[949:965], 3205: _TokenType_name[932:956],
4000: _TokenType_name[965:973], 3206: _TokenType_name[956:972],
4001: _TokenType_name[973:985], 4000: _TokenType_name[972:980],
5000: _TokenType_name[985:996], 4001: _TokenType_name[980:992],
6000: _TokenType_name[996:1003], 5000: _TokenType_name[992:1003],
6001: _TokenType_name[1003:1018], 6000: _TokenType_name[1003:1010],
6002: _TokenType_name[1018:1034], 6001: _TokenType_name[1010:1025],
6003: _TokenType_name[1034:1047], 6002: _TokenType_name[1025:1041],
6004: _TokenType_name[1047:1061], 6003: _TokenType_name[1041:1054],
6100: _TokenType_name[1061:1075], 6004: _TokenType_name[1054:1068],
6101: _TokenType_name[1075:1093], 6100: _TokenType_name[1068:1082],
7000: _TokenType_name[1093:1100], 6101: _TokenType_name[1082:1100],
7001: _TokenType_name[1100:1114], 7000: _TokenType_name[1100:1107],
7002: _TokenType_name[1114:1125], 7001: _TokenType_name[1107:1121],
7003: _TokenType_name[1125:1137], 7002: _TokenType_name[1121:1132],
7004: _TokenType_name[1137:1151], 7003: _TokenType_name[1132:1144],
7005: _TokenType_name[1151:1166], 7004: _TokenType_name[1144:1158],
7006: _TokenType_name[1166:1179], 7005: _TokenType_name[1158:1173],
7007: _TokenType_name[1179:1192], 7006: _TokenType_name[1173:1186],
7008: _TokenType_name[1192:1205], 7007: _TokenType_name[1186:1199],
7009: _TokenType_name[1205:1222], 7008: _TokenType_name[1199:1212],
7010: _TokenType_name[1222:1238], 7009: _TokenType_name[1212:1229],
7011: _TokenType_name[1238:1254], 7010: _TokenType_name[1229:1245],
8000: _TokenType_name[1254:1258], 7011: _TokenType_name[1245:1261],
8001: _TokenType_name[1258:1272], 8000: _TokenType_name[1261:1265],
8002: _TokenType_name[1272:1282], 8001: _TokenType_name[1265:1279],
8003: _TokenType_name[1282:1297], 8002: _TokenType_name[1279:1289],
8003: _TokenType_name[1289:1304],
} }
func (i TokenType) String() string { func (i TokenType) String() string {
if str, ok := _TokenType_map[i]; ok { if str, ok := _TokenType_map[i]; ok {
return str return str
} }
return fmt.Sprintf("TokenType(%d)", i) return "TokenType(" + strconv.FormatInt(int64(i), 10) + ")"
} }

View File

@ -12,7 +12,7 @@ import (
// It is also an Emitter, emitting a single token of itself // It is also an Emitter, emitting a single token of itself
type TokenType int type TokenType int
func (t *TokenType) MarshalJSON() ([]byte, error) { return json.Marshal(t.String()) } func (t TokenType) MarshalJSON() ([]byte, error) { return json.Marshal(t.String()) }
func (t *TokenType) UnmarshalJSON(data []byte) error { func (t *TokenType) UnmarshalJSON(data []byte) error {
key := "" key := ""
err := json.Unmarshal(data, &key) err := json.Unmarshal(data, &key)
@ -54,6 +54,8 @@ const (
Other Other
// No highlighting. // No highlighting.
None None
// Used as an EOF marker / nil token
EOFType TokenType = 0
) )
// Keywords. // Keywords.
@ -341,5 +343,5 @@ func (t TokenType) InSubCategory(other TokenType) bool {
} }
func (t TokenType) Emit(groups []string, lexer Lexer) Iterator { func (t TokenType) Emit(groups []string, lexer Lexer) Iterator {
return Literator(&Token{Type: t, Value: groups[0]}) return Literator(Token{Type: t, Value: groups[0]})
} }

View File

@ -6,7 +6,6 @@ go:
- "1.11.x" - "1.11.x"
- "1.10.x" - "1.10.x"
- "1.9.x" - "1.9.x"
- "1.8.x"
before_install: before_install:
- make deps - make deps

View File

@ -72,7 +72,7 @@ func (s *ProjectsService) ListBranches(projectName string, opt *BranchOptions) (
// //
// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#get-branch // Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#get-branch
func (s *ProjectsService) GetBranch(projectName, branchID string) (*BranchInfo, *Response, error) { func (s *ProjectsService) GetBranch(projectName, branchID string) (*BranchInfo, *Response, error) {
u := fmt.Sprintf("projects/%s/branches/%s", url.QueryEscape(projectName), branchID) u := fmt.Sprintf("projects/%s/branches/%s", url.QueryEscape(projectName), url.QueryEscape(branchID))
req, err := s.client.NewRequest("GET", u, nil) req, err := s.client.NewRequest("GET", u, nil)
if err != nil { if err != nil {
@ -93,7 +93,7 @@ func (s *ProjectsService) GetBranch(projectName, branchID string) (*BranchInfo,
// //
// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#get-reflog // Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#get-reflog
func (s *ProjectsService) GetReflog(projectName, branchID string) (*[]ReflogEntryInfo, *Response, error) { func (s *ProjectsService) GetReflog(projectName, branchID string) (*[]ReflogEntryInfo, *Response, error) {
u := fmt.Sprintf("projects/%s/branches/%s/reflog", url.QueryEscape(projectName), branchID) u := fmt.Sprintf("projects/%s/branches/%s/reflog", url.QueryEscape(projectName), url.QueryEscape(branchID))
req, err := s.client.NewRequest("GET", u, nil) req, err := s.client.NewRequest("GET", u, nil)
if err != nil { if err != nil {
@ -114,7 +114,7 @@ func (s *ProjectsService) GetReflog(projectName, branchID string) (*[]ReflogEntr
// //
// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#create-branch // Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#create-branch
func (s *ProjectsService) CreateBranch(projectName, branchID string, input *BranchInput) (*BranchInfo, *Response, error) { func (s *ProjectsService) CreateBranch(projectName, branchID string, input *BranchInput) (*BranchInfo, *Response, error) {
u := fmt.Sprintf("projects/%s/branches/%s", url.QueryEscape(projectName), branchID) u := fmt.Sprintf("projects/%s/branches/%s", url.QueryEscape(projectName), url.QueryEscape(branchID))
req, err := s.client.NewRequest("PUT", u, input) req, err := s.client.NewRequest("PUT", u, input)
if err != nil { if err != nil {
@ -134,7 +134,7 @@ func (s *ProjectsService) CreateBranch(projectName, branchID string, input *Bran
// //
// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#delete-branch // Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#delete-branch
func (s *ProjectsService) DeleteBranch(projectName, branchID string) (*Response, error) { func (s *ProjectsService) DeleteBranch(projectName, branchID string) (*Response, error) {
u := fmt.Sprintf("projects/%s/branches/%s", url.QueryEscape(projectName), branchID) u := fmt.Sprintf("projects/%s/branches/%s", url.QueryEscape(projectName), url.QueryEscape(branchID))
return s.client.DeleteRequest(u, nil) return s.client.DeleteRequest(u, nil)
} }
@ -152,6 +152,6 @@ func (s *ProjectsService) DeleteBranches(projectName string, input *DeleteBranch
// //
// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#get-content // Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#get-content
func (s *ProjectsService) GetBranchContent(projectName, branchID, fileID string) (string, *Response, error) { func (s *ProjectsService) GetBranchContent(projectName, branchID, fileID string) (string, *Response, error) {
u := fmt.Sprintf("projects/%s/branches/%s/files/%s/content", url.QueryEscape(projectName), branchID, fileID) u := fmt.Sprintf("projects/%s/branches/%s/files/%s/content", url.QueryEscape(projectName), url.QueryEscape(branchID), fileID)
return getStringResponseWithoutOptions(s.client, u) return getStringResponseWithoutOptions(s.client, u)
} }

View File

@ -26,11 +26,11 @@ func (s *ProjectsService) GetCommit(projectName, commitID string) (*CommitInfo,
return v, resp, err 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. // The content is returned as base64 encoded string.
// //
// Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#get-content // Gerrit API docs: https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html##get-content-from-commit
func (s *ProjectsService) GetCommitContent(projectName, branchID, fileID string) (string, *Response, error) { func (s *ProjectsService) GetCommitContent(projectName, commitID, fileID string) (string, *Response, error) {
u := fmt.Sprintf("projects/%s/branches/%s/files/%s/content", url.QueryEscape(projectName), branchID, fileID) u := fmt.Sprintf("projects/%s/commits/%s/files/%s/content", url.QueryEscape(projectName), commitID, fileID)
return getStringResponseWithoutOptions(s.client, u) return getStringResponseWithoutOptions(s.client, u)
} }

View File

@ -1,6 +1,6 @@
language: go language: go
go: go:
- 1.3.3 - 1.7
- 1.x - 1.x
- tip - tip
before_install: before_install:

View File

@ -24,7 +24,7 @@ See https://godoc.org/github.com/cenkalti/backoff#pkg-examples
[coveralls]: https://coveralls.io/github/cenkalti/backoff?branch=master [coveralls]: https://coveralls.io/github/cenkalti/backoff?branch=master
[coveralls image]: https://coveralls.io/repos/github/cenkalti/backoff/badge.svg?branch=master [coveralls image]: https://coveralls.io/repos/github/cenkalti/backoff/badge.svg?branch=master
[google-http-java-client]: https://github.com/google/google-http-java-client [google-http-java-client]: https://github.com/google/google-http-java-client/blob/da1aa993e90285ec18579f1553339b00e19b3ab5/google-http-client/src/main/java/com/google/api/client/util/ExponentialBackOff.java
[exponential backoff wiki]: http://en.wikipedia.org/wiki/Exponential_backoff [exponential backoff wiki]: http://en.wikipedia.org/wiki/Exponential_backoff
[advanced example]: https://godoc.org/github.com/cenkalti/backoff#example_ [advanced example]: https://godoc.org/github.com/cenkalti/backoff#example_

View File

@ -1,9 +1,8 @@
package backoff package backoff
import ( import (
"context"
"time" "time"
"golang.org/x/net/context"
) )
// BackOffContext is a backoff policy that stops retrying after the context // BackOffContext is a backoff policy that stops retrying after the context
@ -52,9 +51,13 @@ func (b *backOffContext) Context() context.Context {
func (b *backOffContext) NextBackOff() time.Duration { func (b *backOffContext) NextBackOff() time.Duration {
select { select {
case <-b.Context().Done(): case <-b.ctx.Done():
return Stop return Stop
default: default:
return b.BackOff.NextBackOff()
} }
next := b.BackOff.NextBackOff()
if deadline, ok := b.ctx.Deadline(); ok && deadline.Sub(time.Now()) < next {
return Stop
}
return next
} }

View File

@ -63,7 +63,6 @@ type ExponentialBackOff struct {
currentInterval time.Duration currentInterval time.Duration
startTime time.Time startTime time.Time
random *rand.Rand
} }
// Clock is an interface that returns current time for BackOff. // Clock is an interface that returns current time for BackOff.
@ -89,7 +88,6 @@ func NewExponentialBackOff() *ExponentialBackOff {
MaxInterval: DefaultMaxInterval, MaxInterval: DefaultMaxInterval,
MaxElapsedTime: DefaultMaxElapsedTime, MaxElapsedTime: DefaultMaxElapsedTime,
Clock: SystemClock, Clock: SystemClock,
random: rand.New(rand.NewSource(time.Now().UnixNano())),
} }
b.Reset() b.Reset()
return b return b
@ -118,10 +116,7 @@ func (b *ExponentialBackOff) NextBackOff() time.Duration {
return Stop return Stop
} }
defer b.incrementCurrentInterval() defer b.incrementCurrentInterval()
if b.random == nil { return getRandomValueFromInterval(b.RandomizationFactor, rand.Float64(), b.currentInterval)
b.random = rand.New(rand.NewSource(time.Now().UnixNano()))
}
return getRandomValueFromInterval(b.RandomizationFactor, b.random.Float64(), b.currentInterval)
} }
// GetElapsedTime returns the elapsed time since an ExponentialBackOff instance // GetElapsedTime returns the elapsed time since an ExponentialBackOff instance

View File

@ -15,7 +15,6 @@ type Notify func(error, time.Duration)
// Retry the operation o until it does not return error or BackOff stops. // Retry the operation o until it does not return error or BackOff stops.
// o is guaranteed to be run at least once. // o is guaranteed to be run at least once.
// It is the caller's responsibility to reset b after Retry returns.
// //
// If o returns a *PermanentError, the operation is not retried, and the // If o returns a *PermanentError, the operation is not retried, and the
// wrapped error is returned. // wrapped error is returned.
@ -29,6 +28,7 @@ func Retry(o Operation, b BackOff) error { return RetryNotify(o, b, nil) }
func RetryNotify(operation Operation, b BackOff, notify Notify) error { func RetryNotify(operation Operation, b BackOff, notify Notify) error {
var err error var err error
var next time.Duration var next time.Duration
var t *time.Timer
cb := ensureContext(b) cb := ensureContext(b)
@ -42,7 +42,7 @@ func RetryNotify(operation Operation, b BackOff, notify Notify) error {
return permanent.Err return permanent.Err
} }
if next = b.NextBackOff(); next == Stop { if next = cb.NextBackOff(); next == Stop {
return err return err
} }
@ -50,11 +50,15 @@ func RetryNotify(operation Operation, b BackOff, notify Notify) error {
notify(err, next) notify(err, next)
} }
t := time.NewTimer(next) if t == nil {
t = time.NewTimer(next)
defer t.Stop()
} else {
t.Reset(next)
}
select { select {
case <-cb.Context().Done(): case <-cb.Context().Done():
t.Stop()
return err return err
case <-t.C: case <-t.C:
} }

View File

@ -1,7 +1,6 @@
package backoff package backoff
import ( import (
"runtime"
"sync" "sync"
"time" "time"
) )
@ -34,7 +33,6 @@ func NewTicker(b BackOff) *Ticker {
} }
t.b.Reset() t.b.Reset()
go t.run() go t.run()
runtime.SetFinalizer(t, (*Ticker).Stop)
return t return t
} }

View File

@ -1,6 +1,7 @@
language: go language: go
go: go:
- 1.3 - 1.9.x
- 1.5 - 1.10.x
- 1.11.x
- tip - tip

View File

@ -18,8 +18,8 @@ import (
"sync" "sync"
"unicode/utf8" "unicode/utf8"
"golang.org/x/text/transform"
"golang.org/x/text/encoding" "golang.org/x/text/encoding"
"golang.org/x/text/transform"
) )
const ( const (
@ -135,8 +135,12 @@ func (c *Charmap) NewDecoder() *encoding.Decoder {
// 8-bit character set. Unknown mappings are mapped to 0x1A. // 8-bit character set. Unknown mappings are mapped to 0x1A.
func (c *Charmap) NewEncoder() *encoding.Encoder { func (c *Charmap) NewEncoder() *encoding.Encoder {
c.Init() c.Init()
return &encoding.Encoder{Transformer: return &encoding.Encoder{
&cmapEncoder{bytes: c.bytes, replace: c.ReplacementChar}} Transformer: &cmapEncoder{
bytes: c.bytes,
replace: c.ReplacementChar,
},
}
} }
func (d *cmapDecoder) Transform(dst, src []byte, atEOF bool) (int, int, error) { func (d *cmapDecoder) Transform(dst, src []byte, atEOF bool) (int, int, error) {

5
vendor/github.com/gdamore/encoding/go.mod generated vendored Normal file
View File

@ -0,0 +1,5 @@
module github.com/gdamore/encoding
go 1.9
require golang.org/x/text v0.3.0

2
vendor/github.com/gdamore/encoding/go.sum generated vendored Normal file
View File

@ -0,0 +1,2 @@
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View File

@ -1,12 +1,8 @@
language: go language: go
go: go:
- 1.5.x
- 1.6.x
- 1.7.x
- 1.8.x
- 1.9.x
- 1.10.x - 1.10.x
- 1.11.x
- master - master
before_install: before_install:

270
vendor/github.com/gdamore/tcell/README.adoc generated vendored Normal file
View File

@ -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.
|===

View File

@ -1,255 +0,0 @@
## tcell <img src=tcell.png align=right>
[![Linux Status](https://img.shields.io/travis/gdamore/tcell.svg?label=linux)](https://travis-ci.org/gdamore/tcell)
[![Windows Status](https://img.shields.io/appveyor/ci/gdamore/tcell.svg?label=windows)](https://ci.appveyor.com/project/gdamore/tcell)
[![Apache License](https://img.shields.io/badge/license-APACHE2-blue.svg)](https://github.com/gdamore/tcell/blob/master/LICENSE)
[![Gitter](https://img.shields.io/badge/gitter-join-brightgreen.svg)](https://gitter.im/gdamore/tcell)
[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://godoc.org/github.com/gdamore/tcell)
[![Go Report Card](http://goreportcard.com/badge/gdamore/tcell)](http://goreportcard.com/report/gdamore/tcell)
[![codecov](https://codecov.io/gh/gdamore/tcell/branch/master/graph/badge.svg)](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/wtfutil/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

11
vendor/github.com/gdamore/tcell/go.mod generated vendored Normal file
View File

@ -0,0 +1,11 @@
module github.com/gdamore/tcell
go 1.9
require (
github.com/gdamore/encoding v1.0.0
github.com/lucasb-eyer/go-colorful v0.0.0-20181028223441-12d3b2882a08
github.com/mattn/go-runewidth v0.0.4
golang.org/x/text v0.3.0
gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0 // indirect
)

10
vendor/github.com/gdamore/tcell/go.sum generated vendored Normal file
View File

@ -0,0 +1,10 @@
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
github.com/lucasb-eyer/go-colorful v0.0.0-20181028223441-12d3b2882a08 h1:5MnxBC15uMxFv5FY/J/8vzyaBiArCOkMdFT9Jsw78iY=
github.com/lucasb-eyer/go-colorful v0.0.0-20181028223441-12d3b2882a08/go.mod h1:NXg0ArsFk0Y01623LgUqoqcouGDB+PwCCQlrwrG6xJ4=
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0 h1:FVCohIoYO7IJoDDVpV2pdq7SgrMH6wHnuTyrdrxJNoY=
gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0/go.mod h1:OdE7CF6DbADk7lN8LIKRzRJTTZXIjtWgA5THM5lhBAw=

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

View File

@ -1,93 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
id="svg8"
version="1.1"
viewBox="0 0 210 297"
height="297mm"
width="210mm">
<defs
id="defs2">
<linearGradient
id="linearGradient2680">
<stop
id="stop2676"
offset="0"
style="stop-color:#ababab;stop-opacity:1;" />
<stop
id="stop2678"
offset="1"
style="stop-color:#ababab;stop-opacity:0;" />
</linearGradient>
<marker
style="overflow:visible"
id="Arrow1Lstart"
refX="0.0"
refY="0.0"
orient="auto">
<path
transform="scale(0.8) translate(12.5,0)"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
id="path848" />
</marker>
<radialGradient
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.28804762,0,94.764912)"
r="19.622099"
fy="133.10568"
fx="111.58373"
cy="133.10568"
cx="111.58373"
id="radialGradient2684"
xlink:href="#linearGradient2680" />
</defs>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1">
<rect
y="99.44445"
x="31.750006"
height="86.430557"
width="129.64584"
id="rect1130"
style="opacity:1;fill:#5d6c53;fill-opacity:1;stroke:#244f24;stroke-width:10;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<text
transform="scale(0.99941234,1.000588)"
id="text1128"
y="160.47581"
x="44.689861"
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:46.0962944px;line-height:1.25;font-family:'Glass TTY VT220';-inkscape-font-specification:'Glass TTY VT220, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#5ef86d;fill-opacity:1;stroke:#59ff32;stroke-width:0.80994618;stroke-opacity:0.94520545;"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:46.0962944px;font-family:'Glass TTY VT220';-inkscape-font-specification:'Glass TTY VT220, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#5ef86d;fill-opacity:1;stroke:#59ff32;stroke-width:0.80994618;stroke-opacity:0.94520545;"
y="160.47581"
x="44.689861"
id="tspan1126">tcell</tspan></text>
<flowRoot
style="fill:black;fill-opacity:1;stroke:none;font-family:sans-serif;font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;letter-spacing:0px;word-spacing:0px"
id="flowRoot1132"
xml:space="preserve"><flowRegion
id="flowRegion1134"><rect
y="432.51968"
x="290"
height="160"
width="330"
id="rect1136" /></flowRegion><flowPara
id="flowPara1138"></flowPara></flowRoot> </g>
</svg>

Before

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -3,9 +3,7 @@
package ole package ole
import ( import (
"errors"
"syscall" "syscall"
"time"
"unicode/utf16" "unicode/utf16"
"unsafe" "unsafe"
) )
@ -21,6 +19,7 @@ var (
procStringFromCLSID, _ = modole32.FindProc("StringFromCLSID") procStringFromCLSID, _ = modole32.FindProc("StringFromCLSID")
procStringFromIID, _ = modole32.FindProc("StringFromIID") procStringFromIID, _ = modole32.FindProc("StringFromIID")
procIIDFromString, _ = modole32.FindProc("IIDFromString") procIIDFromString, _ = modole32.FindProc("IIDFromString")
procCoGetObject, _ = modole32.FindProc("CoGetObject")
procGetUserDefaultLCID, _ = modkernel32.FindProc("GetUserDefaultLCID") procGetUserDefaultLCID, _ = modkernel32.FindProc("GetUserDefaultLCID")
procCopyMemory, _ = modkernel32.FindProc("RtlMoveMemory") procCopyMemory, _ = modkernel32.FindProc("RtlMoveMemory")
procVariantInit, _ = modoleaut32.FindProc("VariantInit") procVariantInit, _ = modoleaut32.FindProc("VariantInit")
@ -209,6 +208,32 @@ func GetActiveObject(clsid *GUID, iid *GUID) (unk *IUnknown, err error) {
return return
} }
type BindOpts struct {
CbStruct uint32
GrfFlags uint32
GrfMode uint32
TickCountDeadline uint32
}
// GetObject retrieves pointer to active object.
func GetObject(programID string, bindOpts *BindOpts, iid *GUID) (unk *IUnknown, err error) {
if bindOpts != nil {
bindOpts.CbStruct = uint32(unsafe.Sizeof(BindOpts{}))
}
if iid == nil {
iid = IID_IUnknown
}
hr, _, _ := procCoGetObject.Call(
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(programID))),
uintptr(unsafe.Pointer(bindOpts)),
uintptr(unsafe.Pointer(iid)),
uintptr(unsafe.Pointer(&unk)))
if hr != 0 {
err = NewError(hr)
}
return
}
// VariantInit initializes variant. // VariantInit initializes variant.
func VariantInit(v *VARIANT) (err error) { func VariantInit(v *VARIANT) (err error) {
hr, _, _ := procVariantInit.Call(uintptr(unsafe.Pointer(v))) hr, _, _ := procVariantInit.Call(uintptr(unsafe.Pointer(v)))
@ -317,13 +342,3 @@ func DispatchMessage(msg *Msg) (ret int32) {
ret = int32(r0) ret = int32(r0)
return return
} }
// GetVariantDate converts COM Variant Time value to Go time.Time.
func GetVariantDate(value float64) (time.Time, error) {
var st syscall.Systemtime
r, _, _ := procVariantTimeToSystemTime.Call(uintptr(value), uintptr(unsafe.Pointer(&st)))
if r != 0 {
return time.Date(int(st.Year), time.Month(st.Month), int(st.Day), int(st.Hour), int(st.Minute), int(st.Second), int(st.Milliseconds/1000), time.UTC), nil
}
return time.Now(), errors.New("Could not convert to time, passing current time.")
}

View File

@ -169,6 +169,6 @@ func DispatchMessage(msg *Msg) int32 {
return int32(0) return int32(0)
} }
func GetVariantDate(value float64) (time.Time, error) { func GetVariantDate(value uint64) (time.Time, error) {
return time.Now(), NewError(E_NOTIMPL) return time.Now(), NewError(E_NOTIMPL)
} }

View File

@ -3,6 +3,7 @@
package ole package ole
import ( import (
"math/big"
"syscall" "syscall"
"time" "time"
"unsafe" "unsafe"
@ -132,6 +133,8 @@ func invoke(disp *IDispatch, dispid int32, dispatch int16, params ...interface{}
vargs[n] = NewVariant(VT_R8, *(*int64)(unsafe.Pointer(&vv))) vargs[n] = NewVariant(VT_R8, *(*int64)(unsafe.Pointer(&vv)))
case *float64: case *float64:
vargs[n] = NewVariant(VT_R8|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*float64))))) vargs[n] = NewVariant(VT_R8|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*float64)))))
case *big.Int:
vargs[n] = NewVariant(VT_DECIMAL, v.(*big.Int).Int64())
case string: case string:
vargs[n] = NewVariant(VT_BSTR, int64(uintptr(unsafe.Pointer(SysAllocStringLen(v.(string)))))) vargs[n] = NewVariant(VT_BSTR, int64(uintptr(unsafe.Pointer(SysAllocStringLen(v.(string))))))
case *string: case *string:

View File

@ -124,12 +124,12 @@ func safeArrayGetElementSize(safearray *SafeArray) (*uint32, error) {
} }
// safeArrayGetElement retrieves element at given index. // safeArrayGetElement retrieves element at given index.
func safeArrayGetElement(safearray *SafeArray, index int64, pv unsafe.Pointer) error { func safeArrayGetElement(safearray *SafeArray, index int32, pv unsafe.Pointer) error {
return NewError(E_NOTIMPL) return NewError(E_NOTIMPL)
} }
// safeArrayGetElement retrieves element at given index and converts to string. // safeArrayGetElement retrieves element at given index and converts to string.
func safeArrayGetElementString(safearray *SafeArray, index int64) (string, error) { func safeArrayGetElementString(safearray *SafeArray, index int32) (string, error) {
return "", NewError(E_NOTIMPL) return "", NewError(E_NOTIMPL)
} }
@ -146,8 +146,8 @@ func safeArrayGetIID(safearray *SafeArray) (*GUID, error) {
// multidimensional array. // multidimensional array.
// //
// AKA: SafeArrayGetLBound in Windows API. // AKA: SafeArrayGetLBound in Windows API.
func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (int64, error) { func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (int32, error) {
return int64(0), NewError(E_NOTIMPL) return int32(0), NewError(E_NOTIMPL)
} }
// safeArrayGetUBound returns upper bounds of SafeArray. // safeArrayGetUBound returns upper bounds of SafeArray.
@ -156,8 +156,8 @@ func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (int64, error) {
// multidimensional array. // multidimensional array.
// //
// AKA: SafeArrayGetUBound in Windows API. // AKA: SafeArrayGetUBound in Windows API.
func safeArrayGetUBound(safearray *SafeArray, dimension uint32) (int64, error) { func safeArrayGetUBound(safearray *SafeArray, dimension uint32) (int32, error) {
return int64(0), NewError(E_NOTIMPL) return int32(0), NewError(E_NOTIMPL)
} }
// safeArrayGetVartype returns data type of SafeArray. // safeArrayGetVartype returns data type of SafeArray.

View File

@ -205,7 +205,7 @@ func safeArrayGetElementSize(safearray *SafeArray) (length *uint32, err error) {
} }
// safeArrayGetElement retrieves element at given index. // safeArrayGetElement retrieves element at given index.
func safeArrayGetElement(safearray *SafeArray, index int64, pv unsafe.Pointer) error { func safeArrayGetElement(safearray *SafeArray, index int32, pv unsafe.Pointer) error {
return convertHresultToError( return convertHresultToError(
procSafeArrayGetElement.Call( procSafeArrayGetElement.Call(
uintptr(unsafe.Pointer(safearray)), uintptr(unsafe.Pointer(safearray)),
@ -214,7 +214,7 @@ func safeArrayGetElement(safearray *SafeArray, index int64, pv unsafe.Pointer) e
} }
// safeArrayGetElementString retrieves element at given index and converts to string. // safeArrayGetElementString retrieves element at given index and converts to string.
func safeArrayGetElementString(safearray *SafeArray, index int64) (str string, err error) { func safeArrayGetElementString(safearray *SafeArray, index int32) (str string, err error) {
var element *int16 var element *int16
err = convertHresultToError( err = convertHresultToError(
procSafeArrayGetElement.Call( procSafeArrayGetElement.Call(
@ -243,7 +243,7 @@ func safeArrayGetIID(safearray *SafeArray) (guid *GUID, err error) {
// multidimensional array. // multidimensional array.
// //
// AKA: SafeArrayGetLBound in Windows API. // AKA: SafeArrayGetLBound in Windows API.
func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (lowerBound int64, err error) { func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (lowerBound int32, err error) {
err = convertHresultToError( err = convertHresultToError(
procSafeArrayGetLBound.Call( procSafeArrayGetLBound.Call(
uintptr(unsafe.Pointer(safearray)), uintptr(unsafe.Pointer(safearray)),
@ -258,7 +258,7 @@ func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (lowerBound int6
// multidimensional array. // multidimensional array.
// //
// AKA: SafeArrayGetUBound in Windows API. // AKA: SafeArrayGetUBound in Windows API.
func safeArrayGetUBound(safearray *SafeArray, dimension uint32) (upperBound int64, err error) { func safeArrayGetUBound(safearray *SafeArray, dimension uint32) (upperBound int32, err error) {
err = convertHresultToError( err = convertHresultToError(
procSafeArrayGetUBound.Call( procSafeArrayGetUBound.Call(
uintptr(unsafe.Pointer(safearray)), uintptr(unsafe.Pointer(safearray)),

View File

@ -14,7 +14,7 @@ func (sac *SafeArrayConversion) ToStringArray() (strings []string) {
totalElements, _ := sac.TotalElements(0) totalElements, _ := sac.TotalElements(0)
strings = make([]string, totalElements) strings = make([]string, totalElements)
for i := int64(0); i < totalElements; i++ { for i := int32(0); i < totalElements; i++ {
strings[int32(i)], _ = safeArrayGetElementString(sac.Array, i) strings[int32(i)], _ = safeArrayGetElementString(sac.Array, i)
} }
@ -25,7 +25,7 @@ func (sac *SafeArrayConversion) ToByteArray() (bytes []byte) {
totalElements, _ := sac.TotalElements(0) totalElements, _ := sac.TotalElements(0)
bytes = make([]byte, totalElements) bytes = make([]byte, totalElements)
for i := int64(0); i < totalElements; i++ { for i := int32(0); i < totalElements; i++ {
safeArrayGetElement(sac.Array, i, unsafe.Pointer(&bytes[int32(i)])) safeArrayGetElement(sac.Array, i, unsafe.Pointer(&bytes[int32(i)]))
} }
@ -37,59 +37,59 @@ func (sac *SafeArrayConversion) ToValueArray() (values []interface{}) {
values = make([]interface{}, totalElements) values = make([]interface{}, totalElements)
vt, _ := safeArrayGetVartype(sac.Array) vt, _ := safeArrayGetVartype(sac.Array)
for i := 0; i < int(totalElements); i++ { for i := int32(0); i < totalElements; i++ {
switch VT(vt) { switch VT(vt) {
case VT_BOOL: case VT_BOOL:
var v bool var v bool
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
values[i] = v values[i] = v
case VT_I1: case VT_I1:
var v int8 var v int8
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
values[i] = v values[i] = v
case VT_I2: case VT_I2:
var v int16 var v int16
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
values[i] = v values[i] = v
case VT_I4: case VT_I4:
var v int32 var v int32
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
values[i] = v values[i] = v
case VT_I8: case VT_I8:
var v int64 var v int64
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
values[i] = v values[i] = v
case VT_UI1: case VT_UI1:
var v uint8 var v uint8
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
values[i] = v values[i] = v
case VT_UI2: case VT_UI2:
var v uint16 var v uint16
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
values[i] = v values[i] = v
case VT_UI4: case VT_UI4:
var v uint32 var v uint32
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
values[i] = v values[i] = v
case VT_UI8: case VT_UI8:
var v uint64 var v uint64
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
values[i] = v values[i] = v
case VT_R4: case VT_R4:
var v float32 var v float32
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
values[i] = v values[i] = v
case VT_R8: case VT_R8:
var v float64 var v float64
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
values[i] = v values[i] = v
case VT_BSTR: case VT_BSTR:
var v string var v string
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
values[i] = v values[i] = v
case VT_VARIANT: case VT_VARIANT:
var v VARIANT var v VARIANT
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
values[i] = v.Value() values[i] = v.Value()
default: default:
// TODO // TODO
@ -111,14 +111,14 @@ func (sac *SafeArrayConversion) GetSize() (length *uint32, err error) {
return safeArrayGetElementSize(sac.Array) return safeArrayGetElementSize(sac.Array)
} }
func (sac *SafeArrayConversion) TotalElements(index uint32) (totalElements int64, err error) { func (sac *SafeArrayConversion) TotalElements(index uint32) (totalElements int32, err error) {
if index < 1 { if index < 1 {
index = 1 index = 1
} }
// Get array bounds // Get array bounds
var LowerBounds int64 var LowerBounds int32
var UpperBounds int64 var UpperBounds int32
LowerBounds, err = safeArrayGetLBound(sac.Array, index) LowerBounds, err = safeArrayGetLBound(sac.Array, index)
if err != nil { if err != nil {

View File

@ -88,10 +88,10 @@ func (v *VARIANT) Value() interface{} {
return v.ToString() return v.ToString()
case VT_DATE: case VT_DATE:
// VT_DATE type will either return float64 or time.Time. // VT_DATE type will either return float64 or time.Time.
d := float64(v.Val) d := uint64(v.Val)
date, err := GetVariantDate(d) date, err := GetVariantDate(d)
if err != nil { if err != nil {
return d return float64(v.Val)
} }
return date return date
case VT_UNKNOWN: case VT_UNKNOWN:

22
vendor/github.com/go-ole/go-ole/variant_date_386.go generated vendored Normal file
View File

@ -0,0 +1,22 @@
// +build windows,386
package ole
import (
"errors"
"syscall"
"time"
"unsafe"
)
// GetVariantDate converts COM Variant Time value to Go time.Time.
func GetVariantDate(value uint64) (time.Time, error) {
var st syscall.Systemtime
v1 := uint32(value)
v2 := uint32(value >> 32)
r, _, _ := procVariantTimeToSystemTime.Call(uintptr(v1), uintptr(v2), uintptr(unsafe.Pointer(&st)))
if r != 0 {
return time.Date(int(st.Year), time.Month(st.Month), int(st.Day), int(st.Hour), int(st.Minute), int(st.Second), int(st.Milliseconds/1000), time.UTC), nil
}
return time.Now(), errors.New("Could not convert to time, passing current time.")
}

20
vendor/github.com/go-ole/go-ole/variant_date_amd64.go generated vendored Normal file
View File

@ -0,0 +1,20 @@
// +build windows,amd64
package ole
import (
"errors"
"syscall"
"time"
"unsafe"
)
// GetVariantDate converts COM Variant Time value to Go time.Time.
func GetVariantDate(value uint64) (time.Time, error) {
var st syscall.Systemtime
r, _, _ := procVariantTimeToSystemTime.Call(uintptr(value), uintptr(unsafe.Pointer(&st)))
if r != 0 {
return time.Date(int(st.Year), time.Month(st.Month), int(st.Day), int(st.Hour), int(st.Minute), int(st.Second), int(st.Milliseconds/1000), time.UTC), nil
}
return time.Now(), errors.New("Could not convert to time, passing current time.")
}

12
vendor/github.com/go-ole/go-ole/variant_ppc64le.go generated vendored Normal file
View File

@ -0,0 +1,12 @@
// +build ppc64le
package ole
type VARIANT struct {
VT VT // 2
wReserved1 uint16 // 4
wReserved2 uint16 // 6
wReserved3 uint16 // 8
Val int64 // 16
_ [8]byte // 24
}

View File

@ -4,8 +4,10 @@ go_import_path: github.com/godbus/dbus
sudo: true sudo: true
go: go:
- 1.6.3
- 1.7.3 - 1.7.3
- 1.8.7
- 1.9.5
- 1.10.1
- tip - tip
env: env:
@ -38,3 +40,7 @@ addons:
- dbus-x11 - dbus-x11
before_install: 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

View File

@ -14,7 +14,7 @@ D-Bus message bus system.
### Installation ### 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 go get github.com/godbus/dbus

View File

@ -116,7 +116,6 @@ func (conn *Conn) Auth(methods []Auth) error {
return err return err
} }
go conn.inWorker() go conn.inWorker()
go conn.outWorker()
return nil return nil
} }
} }

16
vendor/github.com/godbus/dbus/auth_anonymous.go generated vendored Normal file
View File

@ -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
}

View File

@ -1,9 +1,12 @@
package dbus package dbus
import ( import (
"context"
"errors" "errors"
) )
var errSignature = errors.New("dbus: mismatched signature")
// Call represents a pending or completed method call. // Call represents a pending or completed method call.
type Call struct { type Call struct {
Destination string Destination string
@ -20,9 +23,25 @@ type Call struct {
// Holds the response once the call is done. // Holds the response once the call is done.
Body []interface{} 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 // 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 // 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...) return Store(c.Body, retvalues...)
} }
func (c *Call) done() {
c.Done <- c
c.ContextCancel()
}

554
vendor/github.com/godbus/dbus/conn.go generated vendored
View File

@ -1,6 +1,7 @@
package dbus package dbus
import ( import (
"context"
"errors" "errors"
"io" "io"
"os" "os"
@ -14,7 +15,6 @@ var (
systemBusLck sync.Mutex systemBusLck sync.Mutex
sessionBus *Conn sessionBus *Conn
sessionBusLck sync.Mutex sessionBusLck sync.Mutex
sessionEnvLck sync.Mutex
) )
// ErrClosed is the error returned by calls on a closed connection. // ErrClosed is the error returned by calls on a closed connection.
@ -35,23 +35,13 @@ type Conn struct {
unixFD bool unixFD bool
uuid string 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 handler Handler
out chan *Message
closed bool
outLck sync.RWMutex
signalHandler SignalHandler signalHandler SignalHandler
serialGen SerialGenerator
names *nameTracker
calls *callTracker
outHandler *outputHandler
eavesdropped chan<- *Message eavesdropped chan<- *Message
eavesdroppedLck sync.Mutex eavesdroppedLck sync.Mutex
@ -87,32 +77,31 @@ func SessionBus() (conn *Conn, err error) {
} }
func getSessionBusAddress() (string, error) { func getSessionBusAddress() (string, error) {
sessionEnvLck.Lock() if address := os.Getenv("DBUS_SESSION_BUS_ADDRESS"); address != "" && address != "autolaunch:" {
defer sessionEnvLck.Unlock() return address, nil
address := os.Getenv("DBUS_SESSION_BUS_ADDRESS")
if address != "" && address != "autolaunch:" { } else if address := tryDiscoverDbusSessionBusAddress(); address != "" {
os.Setenv("DBUS_SESSION_BUS_ADDRESS", address)
return address, nil return address, nil
} }
return getSessionBusPlatformAddress() return getSessionBusPlatformAddress()
} }
// SessionBusPrivate returns a new private connection to the session bus. // SessionBusPrivate returns a new private connection to the session bus.
func SessionBusPrivate() (*Conn, error) { func SessionBusPrivate(opts ...ConnOption) (*Conn, error) {
address, err := getSessionBusAddress() address, err := getSessionBusAddress()
if err != nil { if err != nil {
return nil, err return nil, err
} }
return Dial(address) return Dial(address, opts...)
} }
// SessionBusPrivate returns a new private connection to the session bus. // SessionBusPrivate returns a new private connection to the session bus.
//
// Deprecated: use SessionBusPrivate with options instead.
func SessionBusPrivateHandler(handler Handler, signalHandler SignalHandler) (*Conn, error) { func SessionBusPrivateHandler(handler Handler, signalHandler SignalHandler) (*Conn, error) {
address, err := getSessionBusAddress() return SessionBusPrivate(WithHandler(handler), WithSignalHandler(signalHandler))
if err != nil {
return nil, err
}
return DialHandler(address, handler, signalHandler)
} }
// SystemBus returns a shared connection to the system bus, connecting to it if // 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. // SystemBusPrivate returns a new private connection to the system bus.
func SystemBusPrivate() (*Conn, error) { func SystemBusPrivate(opts ...ConnOption) (*Conn, error) {
return Dial(getSystemBusPlatformAddress()) return Dial(getSystemBusPlatformAddress(), opts...)
} }
// SystemBusPrivateHandler returns a new private connection to the system bus, using the provided handlers. // 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) { 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. // 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) tr, err := getTransport(address)
if err != nil { if err != nil {
return nil, err 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. // 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) { func DialHandler(address string, handler Handler, signalHandler SignalHandler) (*Conn, error) {
tr, err := getTransport(address) return Dial(address, WithSignalHandler(signalHandler))
if err != nil { }
return nil, err
// 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. // NewConn creates a new private *Conn from an already established connection.
func NewConn(conn io.ReadWriteCloser) (*Conn, error) { func NewConn(conn io.ReadWriteCloser, opts ...ConnOption) (*Conn, error) {
return NewConnHandler(conn, NewDefaultHandler(), NewDefaultSignalHandler()) return newConn(genericTransport{conn}, opts...)
} }
// NewConnHandler creates a new private *Conn from an already established connection, using the supplied handlers. // 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) { 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. // 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 := new(Conn)
conn.transport = tr conn.transport = tr
conn.calls = make(map[uint32]*Call) for _, opt := range opts {
conn.out = make(chan *Message, 10) if err := opt(conn); err != nil {
conn.handler = handler return nil, err
conn.signalHandler = signalHandler }
conn.nextSerial = 1 }
conn.serialUsed = map[uint32]bool{0: true} 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") conn.busObj = conn.Object("org.freedesktop.DBus", "/org/freedesktop/DBus")
return conn, nil 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 // and the channels passed to Eavesdrop and Signal are closed. This method must
// not be called on shared connections. // not be called on shared connections.
func (conn *Conn) Close() error { func (conn *Conn) Close() error {
conn.outLck.Lock() conn.outHandler.close()
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()
if term, ok := conn.signalHandler.(Terminator); ok { if term, ok := conn.signalHandler.(Terminator); ok {
term.Terminate() term.Terminate()
} }
@ -249,17 +267,9 @@ func (conn *Conn) Eavesdrop(ch chan<- *Message) {
conn.eavesdroppedLck.Unlock() conn.eavesdroppedLck.Unlock()
} }
// getSerial returns an unused serial. // GetSerial returns an unused serial.
func (conn *Conn) getSerial() uint32 { func (conn *Conn) getSerial() uint32 {
conn.serialLck.Lock() return conn.serialGen.GetSerial()
defer conn.serialLck.Unlock()
n := conn.nextSerial
for conn.serialUsed[n] {
n++
}
conn.serialUsed[n] = true
conn.nextSerial = n + 1
return n
} }
// Hello sends the initial org.freedesktop.DBus.Hello call. This method must be // 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 { if err != nil {
return err return err
} }
conn.namesLck.Lock() conn.names.acquireUniqueConnectionName(s)
conn.names = make([]string, 1)
conn.names[0] = s
conn.namesLck.Unlock()
return nil return nil
} }
@ -283,7 +290,18 @@ func (conn *Conn) Hello() error {
func (conn *Conn) inWorker() { func (conn *Conn) inWorker() {
for { for {
msg, err := conn.ReadMessage() msg, err := conn.ReadMessage()
if err == nil { 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() conn.eavesdroppedLck.Lock()
if conn.eavesdropped != nil { if conn.eavesdropped != nil {
select { select {
@ -295,46 +313,29 @@ func (conn *Conn) inWorker() {
} }
conn.eavesdroppedLck.Unlock() conn.eavesdroppedLck.Unlock()
dest, _ := msg.Headers[FieldDestination].value.(string) dest, _ := msg.Headers[FieldDestination].value.(string)
found := false found := dest == "" ||
if dest == "" { !conn.names.uniqueNameIsKnown() ||
found = true conn.names.isKnownName(dest)
} 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 { if !found {
// Eavesdropped a message, but no channel for it is registered. // Eavesdropped a message, but no channel for it is registered.
// Ignore it. // Ignore it.
continue continue
} }
switch msg.Type { switch msg.Type {
case TypeMethodReply, TypeError: case TypeError:
serial := msg.Headers[FieldReplySerial].value.(uint32) conn.serialGen.RetireSerial(conn.calls.handleDBusError(msg))
conn.callsLck.Lock() case TypeMethodReply:
if c, ok := conn.calls[serial]; ok { conn.serialGen.RetireSerial(conn.calls.handleReply(msg))
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: case TypeSignal:
conn.handleSignal(msg)
case TypeMethodCall:
go conn.handleCall(msg)
}
}
}
func (conn *Conn) handleSignal(msg *Message) {
iface := msg.Headers[FieldInterface].value.(string) iface := msg.Headers[FieldInterface].value.(string)
member := msg.Headers[FieldMember].value.(string) member := msg.Headers[FieldMember].value.(string)
// as per http://dbus.freedesktop.org/doc/dbus-specification.html , // as per http://dbus.freedesktop.org/doc/dbus-specification.html ,
@ -348,14 +349,7 @@ func (conn *Conn) inWorker() {
if !ok { if !ok {
panic("Unable to read the lost name") panic("Unable to read the lost name")
} }
conn.namesLck.Lock() conn.names.loseName(name)
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" { } else if member == "NameAcquired" {
// If we acquired the name on the bus, add it to our // If we acquired the name on the bus, add it to our
// tracking list. // tracking list.
@ -363,38 +357,9 @@ func (conn *Conn) inWorker() {
if !ok { if !ok {
panic("Unable to read the acquired name") panic("Unable to read the acquired name")
} }
conn.namesLck.Lock() conn.names.acquireName(name)
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
}
// invalid messages are ignored
}
}
func (conn *Conn) handleSignal(msg *Message) {
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)
signal := &Signal{ signal := &Signal{
Sender: sender, Sender: sender,
Path: msg.Headers[FieldPath].value.(ObjectPath), 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 // connection. The slice is always at least one element long, the first element
// being the unique name of the connection. // being the unique name of the connection.
func (conn *Conn) Names() []string { func (conn *Conn) Names() []string {
conn.namesLck.RLock() return conn.names.listKnownNames()
// copy the slice so it can't be modified
s := make([]string, len(conn.names))
copy(s, conn.names)
conn.namesLck.RUnlock()
return s
} }
// Object returns the object identified by the given destination name and path. // 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 // outWorker runs in an own goroutine, encoding and sending messages that are
// sent to conn.out. // sent to conn.out.
func (conn *Conn) outWorker() { func (conn *Conn) sendMessage(msg *Message) {
for msg := range conn.out { conn.sendMessageAndIfClosed(msg, func() {})
err := conn.SendMessage(msg) }
conn.callsLck.RLock()
func (conn *Conn) sendMessageAndIfClosed(msg *Message, ifClosed func()) {
err := conn.outHandler.sendAndIfClosed(msg, ifClosed)
conn.calls.handleSendError(msg, err)
if err != nil { if err != nil {
if c := conn.calls[msg.serial]; c != nil { conn.serialGen.RetireSerial(msg.serial)
c.Err = err
c.Done <- c
}
conn.serialLck.Lock()
delete(conn.serialUsed, msg.serial)
conn.serialLck.Unlock()
} else if msg.Type != TypeMethodCall { } else if msg.Type != TypeMethodCall {
conn.serialLck.Lock() conn.serialGen.RetireSerial(msg.serial)
delete(conn.serialUsed, msg.serial)
conn.serialLck.Unlock()
}
conn.callsLck.RUnlock()
} }
} }
@ -451,8 +404,21 @@ func (conn *Conn) outWorker() {
// once the call is complete. Otherwise, ch is ignored and a Call structure is // once the call is complete. Otherwise, ch is ignored and a Call structure is
// returned of which only the Err member is valid. // returned of which only the Err member is valid.
func (conn *Conn) Send(msg *Message, ch chan *Call) *Call { 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() msg.serial = conn.getSerial()
if msg.Type == TypeMethodCall && msg.Flags&FlagNoReplyExpected == 0 { if msg.Type == TypeMethodCall && msg.Flags&FlagNoReplyExpected == 0 {
if ch == nil { if ch == nil {
@ -468,26 +434,23 @@ func (conn *Conn) Send(msg *Message, ch chan *Call) *Call {
call.Method = iface + "." + member call.Method = iface + "." + member
call.Args = msg.Body call.Args = msg.Body
call.Done = ch call.Done = ch
conn.callsLck.Lock() call.ctx = ctx
conn.calls[msg.serial] = call call.ctxCanceler = canceler
conn.callsLck.Unlock() conn.calls.track(msg.serial, call)
conn.outLck.RLock() go func() {
if conn.closed { <-ctx.Done()
call.Err = ErrClosed conn.calls.handleSendError(msg, ctx.Err())
call.Done <- call }()
conn.sendMessageAndIfClosed(msg, func() {
conn.calls.handleSendError(msg, ErrClosed)
canceler()
})
} else { } else {
conn.out <- msg canceler()
}
conn.outLck.RUnlock()
} else {
conn.outLck.RLock()
if conn.closed {
call = &Call{Err: ErrClosed}
} else {
conn.out <- msg
call = &Call{Err: nil} call = &Call{Err: nil}
} conn.sendMessageAndIfClosed(msg, func() {
conn.outLck.RUnlock() call = &Call{Err: ErrClosed}
})
} }
return call return call
} }
@ -520,11 +483,7 @@ func (conn *Conn) sendError(err error, dest string, serial uint32) {
if len(e.Body) > 0 { if len(e.Body) > 0 {
msg.Headers[FieldSignature] = MakeVariant(SignatureOf(e.Body...)) msg.Headers[FieldSignature] = MakeVariant(SignatureOf(e.Body...))
} }
conn.outLck.RLock() conn.sendMessage(msg)
if !conn.closed {
conn.out <- msg
}
conn.outLck.RUnlock()
} }
// sendReply creates a method reply message corresponding to the parameters and // 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 { if len(values) > 0 {
msg.Headers[FieldSignature] = MakeVariant(SignatureOf(values...)) msg.Headers[FieldSignature] = MakeVariant(SignatureOf(values...))
} }
conn.outLck.RLock() conn.sendMessage(msg)
if !conn.closed {
conn.out <- msg
}
conn.outLck.RUnlock()
} }
func (conn *Conn) defaultSignalAction(fn func(h *defaultSignalHandler, ch chan<- *Signal), ch chan<- *Signal) { 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 "" 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()
}
}

View File

@ -31,3 +31,7 @@ func getSystemBusPlatformAddress() string {
} }
return defaultSystemBusAddress return defaultSystemBusAddress
} }
func tryDiscoverDbusSessionBusAddress() string {
return ""
}

View File

@ -6,12 +6,14 @@ import (
"bytes" "bytes"
"errors" "errors"
"fmt" "fmt"
"io/ioutil"
"os" "os"
"os/exec" "os/exec"
"os/user"
"path"
"strings"
) )
const defaultSystemBusAddress = "unix:path=/var/run/dbus/system_bus_socket"
func getSessionBusPlatformAddress() (string, error) { func getSessionBusPlatformAddress() (string, error) {
cmd := exec.Command("dbus-launch") cmd := exec.Command("dbus-launch")
b, err := cmd.CombinedOutput() b, err := cmd.CombinedOutput()
@ -33,10 +35,57 @@ func getSessionBusPlatformAddress() (string, error) {
return addr, nil return addr, nil
} }
func getSystemBusPlatformAddress() string { // tryDiscoverDbusSessionBusAddress tries to discover an existing dbus session
address := os.Getenv("DBUS_SYSTEM_BUS_ADDRESS") // and return the value of its DBUS_SESSION_BUS_ADDRESS.
if address != "" { // It tries different techniques employed by different operating systems,
return fmt.Sprintf("unix:path=%s", address) // returning the first valid address it finds, or an empty string.
//
// * /run/user/<uid>/bus if this exists, it *is* the bus socket. present on
// Ubuntu 18.04
// * /run/user/<uid>/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/<uid>/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/<uid>/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
} }

18
vendor/github.com/godbus/dbus/conn_unix.go generated vendored Normal file
View File

@ -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
}

15
vendor/github.com/godbus/dbus/conn_windows.go generated vendored Normal file
View File

@ -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
}

View File

@ -191,7 +191,14 @@ func (dec *decoder) decode(s string, depth int) interface{} {
length := dec.decode("u", depth).(uint32) length := dec.decode("u", depth).(uint32)
v := reflect.MakeSlice(reflect.SliceOf(typeFor(s[1:])), 0, int(length)) v := reflect.MakeSlice(reflect.SliceOf(typeFor(s[1:])), 0, int(length))
// Even for empty arrays, the correct padding must be included // 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 spos := dec.pos
for dec.pos < spos+int(length) { for dec.pos < spos+int(length) {
ev := dec.decode(s[1:], depth+1) ev := dec.decode(s[1:], depth+1)

View File

@ -21,6 +21,8 @@ func newIntrospectIntf(h *defaultHandler) *exportedIntf {
//NewDefaultHandler returns an instance of the default //NewDefaultHandler returns an instance of the default
//call handler. This is useful if you want to implement only //call handler. This is useful if you want to implement only
//one of the two handlers but not both. //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 { func NewDefaultHandler() *defaultHandler {
h := &defaultHandler{ h := &defaultHandler{
objects: make(map[ObjectPath]*exportedObj), objects: make(map[ObjectPath]*exportedObj),
@ -161,6 +163,7 @@ func newExportedObject() *exportedObj {
} }
type exportedObj struct { type exportedObj struct {
mu sync.RWMutex
interfaces map[string]*exportedIntf interfaces map[string]*exportedIntf
} }
@ -168,19 +171,27 @@ func (obj *exportedObj) LookupInterface(name string) (Interface, bool) {
if name == "" { if name == "" {
return obj, true return obj, true
} }
obj.mu.RLock()
defer obj.mu.RUnlock()
intf, exists := obj.interfaces[name] intf, exists := obj.interfaces[name]
return intf, exists return intf, exists
} }
func (obj *exportedObj) AddInterface(name string, iface *exportedIntf) { func (obj *exportedObj) AddInterface(name string, iface *exportedIntf) {
obj.mu.Lock()
defer obj.mu.Unlock()
obj.interfaces[name] = iface obj.interfaces[name] = iface
} }
func (obj *exportedObj) DeleteInterface(name string) { func (obj *exportedObj) DeleteInterface(name string) {
obj.mu.Lock()
defer obj.mu.Unlock()
delete(obj.interfaces, name) delete(obj.interfaces, name)
} }
func (obj *exportedObj) LookupMethod(name string) (Method, bool) { func (obj *exportedObj) LookupMethod(name string) (Method, bool) {
obj.mu.RLock()
defer obj.mu.RUnlock()
for _, intf := range obj.interfaces { for _, intf := range obj.interfaces {
method, exists := intf.LookupMethod(name) method, exists := intf.LookupMethod(name)
if exists { if exists {
@ -220,8 +231,12 @@ func (obj *exportedIntf) isFallbackInterface() bool {
//NewDefaultSignalHandler returns an instance of the default //NewDefaultSignalHandler returns an instance of the default
//signal handler. This is useful if you want to implement only //signal handler. This is useful if you want to implement only
//one of the two handlers but not both. //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 { func NewDefaultSignalHandler() *defaultSignalHandler {
return &defaultSignalHandler{} return &defaultSignalHandler{
closeChan: make(chan struct{}),
}
} }
func isDefaultSignalHandler(handler SignalHandler) bool { func isDefaultSignalHandler(handler SignalHandler) bool {
@ -233,30 +248,45 @@ type defaultSignalHandler struct {
sync.RWMutex sync.RWMutex
closed bool closed bool
signals []chan<- *Signal signals []chan<- *Signal
closeChan chan struct{}
} }
func (sh *defaultSignalHandler) DeliverSignal(intf, name string, signal *Signal) { func (sh *defaultSignalHandler) DeliverSignal(intf, name string, signal *Signal) {
go func() {
sh.RLock() sh.RLock()
defer sh.RUnlock() defer sh.RUnlock()
if sh.closed { if sh.closed {
return return
} }
for _, ch := range sh.signals { for _, ch := range sh.signals {
ch <- signal select {
case ch <- signal:
case <-sh.closeChan:
return
default:
go func() {
select {
case ch <- signal:
case <-sh.closeChan:
return
} }
}() }()
} }
}
}
func (sh *defaultSignalHandler) Init() error { func (sh *defaultSignalHandler) Init() error {
sh.Lock() sh.Lock()
sh.signals = make([]chan<- *Signal, 0) sh.signals = make([]chan<- *Signal, 0)
sh.closeChan = make(chan struct{})
sh.Unlock() sh.Unlock()
return nil return nil
} }
func (sh *defaultSignalHandler) Terminate() { func (sh *defaultSignalHandler) Terminate() {
sh.Lock() sh.Lock()
if !sh.closed {
close(sh.closeChan)
}
sh.closed = true sh.closed = true
for _, ch := range sh.signals { for _, ch := range sh.signals {
close(ch) close(ch)

View File

@ -170,11 +170,8 @@ func (conn *Conn) handleCall(msg *Message) {
reply.Body[i] = ret[i] reply.Body[i] = ret[i]
} }
reply.Headers[FieldSignature] = MakeVariant(SignatureOf(reply.Body...)) reply.Headers[FieldSignature] = MakeVariant(SignatureOf(reply.Body...))
conn.outLck.RLock()
if !conn.closed { conn.sendMessage(reply)
conn.out <- reply
}
conn.outLck.RUnlock()
} }
} }
@ -207,12 +204,14 @@ func (conn *Conn) Emit(path ObjectPath, name string, values ...interface{}) erro
if len(values) > 0 { if len(values) > 0 {
msg.Headers[FieldSignature] = MakeVariant(SignatureOf(values...)) msg.Headers[FieldSignature] = MakeVariant(SignatureOf(values...))
} }
conn.outLck.RLock()
defer conn.outLck.RUnlock() var closed bool
if conn.closed { conn.sendMessageAndIfClosed(msg, func() {
closed = true
})
if closed {
return ErrClosed return ErrClosed
} }
conn.out <- msg
return nil return nil
} }

1
vendor/github.com/godbus/dbus/go.mod generated vendored Normal file
View File

@ -0,0 +1 @@
module github.com/godbus/dbus

View File

@ -1,6 +1,7 @@
package dbus package dbus
import ( import (
"context"
"errors" "errors"
"strings" "strings"
) )
@ -9,7 +10,11 @@ import (
// invoked. // invoked.
type BusObject interface { type BusObject interface {
Call(method string, flags Flags, args ...interface{}) *Call 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 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) GetProperty(p string) (Variant, error)
Destination() string Destination() string
Path() ObjectPath Path() ObjectPath
@ -24,16 +29,73 @@ type Object struct {
// Call calls a method with (*Object).Go and waits for its reply. // Call calls a method with (*Object).Go and waits for its reply.
func (o *Object) Call(method string, flags Flags, args ...interface{}) *Call { 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 // CallWithContext acts like Call but takes a context
// method (member). func (o *Object) CallWithContext(ctx context.Context, method string, flags Flags, args ...interface{}) *Call {
func (o *Object) AddMatchSignal(iface, member string) *Call { return <-o.createCall(ctx, method, flags, make(chan *Call, 1), args...).Done
return o.Call( }
// 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", "org.freedesktop.DBus.AddMatch",
0, 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 // If the method parameter contains a dot ('.'), the part before the last dot
// specifies the interface on which the method is called. // specifies the interface on which the method is called.
func (o *Object) Go(method string, flags Flags, ch chan *Call, args ...interface{}) *Call { 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 := "" iface := ""
i := strings.LastIndex(method, ".") i := strings.LastIndex(method, ".")
if i != -1 { 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 { } else if cap(ch) == 0 {
panic("dbus: unbuffered channel passed to (*Object).Go") panic("dbus: unbuffered channel passed to (*Object).Go")
} }
ctx, cancel := context.WithCancel(ctx)
call := &Call{ call := &Call{
Destination: o.dest, Destination: o.dest,
Path: o.path, Path: o.path,
Method: method, Method: method,
Args: args, Args: args,
Done: ch, Done: ch,
ctxCanceler: cancel,
ctx: ctx,
} }
o.conn.callsLck.Lock() o.conn.calls.track(msg.serial, call)
o.conn.calls[msg.serial] = call o.conn.sendMessageAndIfClosed(msg, func() {
o.conn.callsLck.Unlock() o.conn.calls.handleSendError(msg, ErrClosed)
o.conn.outLck.RLock() cancel()
if o.conn.closed { })
call.Err = ErrClosed go func() {
call.Done <- call <-ctx.Done()
} else { o.conn.calls.handleSendError(msg, ctx.Err())
o.conn.out <- msg }()
}
o.conn.outLck.RUnlock()
return call return call
} }
o.conn.outLck.RLock()
defer o.conn.outLck.RUnlock()
done := make(chan *Call, 1) done := make(chan *Call, 1)
call := &Call{ call := &Call{
Err: nil, Err: nil,
@ -107,11 +181,9 @@ func (o *Object) Go(method string, flags Flags, ch chan *Call, args ...interface
call.Done <- call call.Done <- call
close(done) close(done)
}() }()
if o.conn.closed { o.conn.sendMessageAndIfClosed(msg, func() {
call.Err = ErrClosed call.Err = ErrClosed
return call })
}
o.conn.out <- msg
return call return call
} }

View File

@ -87,3 +87,13 @@ type SignalHandler interface {
type DBusError interface { type DBusError interface {
DBusError() (string, []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)
}

39
vendor/github.com/godbus/dbus/transport_nonce_tcp.go generated vendored Normal file
View File

@ -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)
}

View File

@ -31,6 +31,7 @@ func (o *oobReader) Read(b []byte) (n int, err error) {
type unixTransport struct { type unixTransport struct {
*net.UnixConn *net.UnixConn
rdr *oobReader
hasUnixFDs bool 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 // 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 // reader that uses ReadUnix on the underlying connection instead of Read
// and gathers the out-of-band data in a buffer. // 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), // 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 // 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 return nil, err
} }
switch csheader[0] { switch csheader[0] {
@ -104,7 +110,7 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
// decode headers and look for unix fds // decode headers and look for unix fds
headerdata := make([]byte, hlen+4) headerdata := make([]byte, hlen+4)
copy(headerdata, csheader[12:]) 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 return nil, err
} }
dec := newDecoder(bytes.NewBuffer(headerdata), order) dec := newDecoder(bytes.NewBuffer(headerdata), order)
@ -122,7 +128,7 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
all := make([]byte, 16+hlen+blen) all := make([]byte, 16+hlen+blen)
copy(all, csheader[:]) copy(all, csheader[:])
copy(all[16:], headerdata[4:]) 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 return nil, err
} }
if unixfds != 0 { if unixfds != 0 {
@ -130,7 +136,7 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
return nil, errors.New("dbus: got unix fds on unsupported transport") return nil, errors.New("dbus: got unix fds on unsupported transport")
} }
// read the fds from the OOB data // read the fds from the OOB data
scms, err := syscall.ParseSocketControlMessage(rd.oob) scms, err := syscall.ParseSocketControlMessage(t.rdr.oob)
if err != nil { if err != nil {
return nil, err 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 // substitute the values in the message body (which are indices for the
// array receiver via OOB) with the actual values // array receiver via OOB) with the actual values
for i, v := range msg.Body { for i, v := range msg.Body {
if j, ok := v.(UnixFDIndex); ok { switch v.(type) {
case UnixFDIndex:
j := v.(UnixFDIndex)
if uint32(j) >= unixfds { if uint32(j) >= unixfds {
return nil, InvalidMessageError("invalid index for unix fd") return nil, InvalidMessageError("invalid index for unix fd")
} }
msg.Body[i] = UnixFD(fds[j]) 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 return msg, nil

View File

@ -22,9 +22,11 @@ Allen Sun <shlallen1990@gmail.com>
Amey Sakhadeo <me@ameyms.com> Amey Sakhadeo <me@ameyms.com>
Andreas Garnæs <https://github.com/andreas> Andreas Garnæs <https://github.com/andreas>
Andrew Ryabchun <aryabchun@mail.ua> Andrew Ryabchun <aryabchun@mail.ua>
Andy Grunwald <andygrunwald@gmail.com>
Andy Hume <andyhume@gmail.com> Andy Hume <andyhume@gmail.com>
Andy Lindeman <andy@lindeman.io> Andy Lindeman <andy@lindeman.io>
Anshuman Bhartiya <anshuman.bhartiya@gmail.com> Anshuman Bhartiya <anshuman.bhartiya@gmail.com>
Antoine <antoine.tu@mail.mcgill.ca>
Antoine Pelisse <apelisse@gmail.com> Antoine Pelisse <apelisse@gmail.com>
Anubha Kushwaha <anubha_bt2k14@dtu.ac.in> Anubha Kushwaha <anubha_bt2k14@dtu.ac.in>
appilon <apilon@hashicorp.com> appilon <apilon@hashicorp.com>
@ -56,6 +58,7 @@ Craig Peterson <cpeterson@stackoverflow.com>
Cristian Maglie <c.maglie@bug.st> Cristian Maglie <c.maglie@bug.st>
Daehyeok Mun <daehyeok@gmail.com> Daehyeok Mun <daehyeok@gmail.com>
Daniel Leavitt <daniel.leavitt@gmail.com> Daniel Leavitt <daniel.leavitt@gmail.com>
Daniel Nilsson <daniel.nilsson1989@gmail.com>
Dave Du Cros <davidducros@gmail.com> Dave Du Cros <davidducros@gmail.com>
Dave Henderson <dhenderson@gmail.com> Dave Henderson <dhenderson@gmail.com>
David Deng <daviddengcn@gmail.com> David Deng <daviddengcn@gmail.com>
@ -73,6 +76,7 @@ Eli Uriegas <seemethere101@gmail.com>
Elliott Beach <elliott2.71828@gmail.com> Elliott Beach <elliott2.71828@gmail.com>
Emerson Wood <emersonwood94@gmail.com> Emerson Wood <emersonwood94@gmail.com>
eperm <staffordworrell@gmail.com> eperm <staffordworrell@gmail.com>
Erick Fejta <erick@fejta.com>
erwinvaneyk <erwinvaneyk@gmail.com> erwinvaneyk <erwinvaneyk@gmail.com>
Fabrice <fabrice.vaillant@student.ecp.fr> Fabrice <fabrice.vaillant@student.ecp.fr>
Filippo Valsorda <hi@filippo.io> Filippo Valsorda <hi@filippo.io>
@ -85,6 +89,7 @@ George Kontridze <george.kontridze@gmail.com>
Georgy Buranov <gburanov@gmail.com> Georgy Buranov <gburanov@gmail.com>
Gnahz <p@oath.pl> Gnahz <p@oath.pl>
Google Inc. Google Inc.
Grachev Mikhail <work@mgrachev.com>
griffin_stewie <panterathefamilyguy@gmail.com> griffin_stewie <panterathefamilyguy@gmail.com>
Guillaume Jacquet <guillaume.jacquet@gmail.com> Guillaume Jacquet <guillaume.jacquet@gmail.com>
Guz Alexander <kalimatas@gmail.com> Guz Alexander <kalimatas@gmail.com>
@ -117,6 +122,8 @@ Justin Abrahms <justin@abrah.ms>
Jusung Lee <e.jusunglee@gmail.com> Jusung Lee <e.jusunglee@gmail.com>
jzhoucliqr <jzhou@cliqr.com> jzhoucliqr <jzhou@cliqr.com>
Katrina Owen <kytrinyx@github.com> Katrina Owen <kytrinyx@github.com>
Kautilya Tripathi < tripathi.kautilya@gmail.com>
Kautilya Tripathi <tripathi.kautilya@gmail.com>
Keita Urashima <ursm@ursm.jp> Keita Urashima <ursm@ursm.jp>
Kevin Burke <kev@inburke.com> Kevin Burke <kev@inburke.com>
Konrad Malawski <konrad.malawski@project13.pl> Konrad Malawski <konrad.malawski@project13.pl>
@ -124,6 +131,7 @@ Kookheon Kwon <kucuny@gmail.com>
Krzysztof Kowalczyk <kkowalczyk@gmail.com> Krzysztof Kowalczyk <kkowalczyk@gmail.com>
Kshitij Saraogi <KshitijSaraogi@gmail.com> Kshitij Saraogi <KshitijSaraogi@gmail.com>
kyokomi <kyoko1220adword@gmail.com> kyokomi <kyoko1220adword@gmail.com>
Lovro Mažgon <lovro.mazgon@gmail.com>
Lucas Alcantara <lucasalcantaraf@gmail.com> Lucas Alcantara <lucasalcantaraf@gmail.com>
Luke Evers <me@lukevers.com> Luke Evers <me@lukevers.com>
Luke Kysow <lkysow@gmail.com> Luke Kysow <lkysow@gmail.com>
@ -142,6 +150,7 @@ Michael Spiegel <michael.m.spiegel@gmail.com>
Michael Tiller <michael.tiller@gmail.com> Michael Tiller <michael.tiller@gmail.com>
Michał Glapa <michal.glapa@gmail.com> Michał Glapa <michal.glapa@gmail.com>
Nathan VanBenschoten <nvanbenschoten@gmail.com> Nathan VanBenschoten <nvanbenschoten@gmail.com>
Navaneeth Suresh <navaneeths1998@gmail.com>
Neil O'Toole <neilotoole@apache.org> Neil O'Toole <neilotoole@apache.org>
Nick Miyake <nmiyake@palantir.com> Nick Miyake <nmiyake@palantir.com>
Nick Spragg <nick.spragg@bbc.co.uk> Nick Spragg <nick.spragg@bbc.co.uk>
@ -150,6 +159,7 @@ Noah Zoschke <noah+sso2@convox.com>
ns-cweber <cweber@narrativescience.com> ns-cweber <cweber@narrativescience.com>
Oleg Kovalov <iamolegkovalov@gmail.com> Oleg Kovalov <iamolegkovalov@gmail.com>
Ondřej Kupka <ondra.cap@gmail.com> Ondřej Kupka <ondra.cap@gmail.com>
Palash Nigam <npalash25@gmail.com>
Panagiotis Moustafellos <pmoust@gmail.com> Panagiotis Moustafellos <pmoust@gmail.com>
Parham Alvani <parham.alvani@gmail.com> Parham Alvani <parham.alvani@gmail.com>
Parker Moore <parkrmoore@gmail.com> Parker Moore <parkrmoore@gmail.com>
@ -171,6 +181,7 @@ Rob Figueiredo <robfig@yext.com>
Rohit Upadhyay <urohit011@gmail.com> Rohit Upadhyay <urohit011@gmail.com>
Ronak Jain <ronakjain@outlook.in> Ronak Jain <ronakjain@outlook.in>
Ruben Vereecken <rubenvereecken@gmail.com> Ruben Vereecken <rubenvereecken@gmail.com>
Ryan Leung <rleungx@gmail.com>
Ryan Lower <rpjlower@gmail.com> Ryan Lower <rpjlower@gmail.com>
Sahil Dua <sahildua2305@gmail.com> Sahil Dua <sahildua2305@gmail.com>
saisi <saisi@users.noreply.github.com> saisi <saisi@users.noreply.github.com>
@ -184,10 +195,12 @@ Sebastian Mandrean <sebastian.mandrean@gmail.com>
Sebastian Mæland Pedersen <sem.pedersen@stud.uis.no> Sebastian Mæland Pedersen <sem.pedersen@stud.uis.no>
Sevki <s@sevki.org> Sevki <s@sevki.org>
Shagun Khemka <shagun.khemka60@gmail.com> Shagun Khemka <shagun.khemka60@gmail.com>
shakeelrao <shakeelrao79@gmail.com>
Shawn Catanzarite <me@shawncatz.com> Shawn Catanzarite <me@shawncatz.com>
Shawn Smith <shawnpsmith@gmail.com> Shawn Smith <shawnpsmith@gmail.com>
sona-tar <sona.zip@gmail.com> sona-tar <sona.zip@gmail.com>
SoundCloud, Ltd. SoundCloud, Ltd.
Sridhar Mocherla <srmocher@microsoft.com>
Stian Eikeland <stian@eikeland.se> Stian Eikeland <stian@eikeland.se>
Tasya Aditya Rukmana <tadityar@gmail.com> Tasya Aditya Rukmana <tadityar@gmail.com>
Thomas Bruyelle <thomas.bruyelle@gmail.com> Thomas Bruyelle <thomas.bruyelle@gmail.com>
@ -198,6 +211,7 @@ Varadarajan Aravamudhan <varadaraajan@gmail.com>
Victor Castell <victor@victorcastell.com> Victor Castell <victor@victorcastell.com>
Victor Vrantchan <vrancean+github@gmail.com> Victor Vrantchan <vrancean+github@gmail.com>
Vlad Ungureanu <vladu@palantir.com> Vlad Ungureanu <vladu@palantir.com>
Wasim Thabraze <wasim@thabraze.me>
Will Maier <wcmaier@gmail.com> Will Maier <wcmaier@gmail.com>
William Bailey <mail@williambailey.org.uk> William Bailey <mail@williambailey.org.uk>
xibz <impactbchang@gmail.com> xibz <impactbchang@gmail.com>

View File

@ -7,124 +7,9 @@ package github
import ( import (
"context" "context"
"encoding/json"
"fmt" "fmt"
"time"
) )
// Event represents a GitHub event.
type Event struct {
Type *string `json:"type,omitempty"`
Public *bool `json:"public,omitempty"`
RawPayload *json.RawMessage `json:"payload,omitempty"`
Repo *Repository `json:"repo,omitempty"`
Actor *User `json:"actor,omitempty"`
Org *Organization `json:"org,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
ID *string `json:"id,omitempty"`
}
func (e Event) String() string {
return Stringify(e)
}
// ParsePayload parses the event payload. For recognized event types,
// a value of the corresponding struct type will be returned.
func (e *Event) ParsePayload() (payload interface{}, err error) {
switch *e.Type {
case "CheckRunEvent":
payload = &CheckRunEvent{}
case "CheckSuiteEvent":
payload = &CheckSuiteEvent{}
case "CommitCommentEvent":
payload = &CommitCommentEvent{}
case "CreateEvent":
payload = &CreateEvent{}
case "DeleteEvent":
payload = &DeleteEvent{}
case "DeploymentEvent":
payload = &DeploymentEvent{}
case "DeploymentStatusEvent":
payload = &DeploymentStatusEvent{}
case "ForkEvent":
payload = &ForkEvent{}
case "GollumEvent":
payload = &GollumEvent{}
case "InstallationEvent":
payload = &InstallationEvent{}
case "InstallationRepositoriesEvent":
payload = &InstallationRepositoriesEvent{}
case "IssueCommentEvent":
payload = &IssueCommentEvent{}
case "IssuesEvent":
payload = &IssuesEvent{}
case "LabelEvent":
payload = &LabelEvent{}
case "MarketplacePurchaseEvent":
payload = &MarketplacePurchaseEvent{}
case "MemberEvent":
payload = &MemberEvent{}
case "MembershipEvent":
payload = &MembershipEvent{}
case "MilestoneEvent":
payload = &MilestoneEvent{}
case "OrganizationEvent":
payload = &OrganizationEvent{}
case "OrgBlockEvent":
payload = &OrgBlockEvent{}
case "PageBuildEvent":
payload = &PageBuildEvent{}
case "PingEvent":
payload = &PingEvent{}
case "ProjectEvent":
payload = &ProjectEvent{}
case "ProjectCardEvent":
payload = &ProjectCardEvent{}
case "ProjectColumnEvent":
payload = &ProjectColumnEvent{}
case "PublicEvent":
payload = &PublicEvent{}
case "PullRequestEvent":
payload = &PullRequestEvent{}
case "PullRequestReviewEvent":
payload = &PullRequestReviewEvent{}
case "PullRequestReviewCommentEvent":
payload = &PullRequestReviewCommentEvent{}
case "PushEvent":
payload = &PushEvent{}
case "ReleaseEvent":
payload = &ReleaseEvent{}
case "RepositoryEvent":
payload = &RepositoryEvent{}
case "RepositoryVulnerabilityAlertEvent":
payload = &RepositoryVulnerabilityAlertEvent{}
case "StatusEvent":
payload = &StatusEvent{}
case "TeamEvent":
payload = &TeamEvent{}
case "TeamAddEvent":
payload = &TeamAddEvent{}
case "WatchEvent":
payload = &WatchEvent{}
}
err = json.Unmarshal(*e.RawPayload, &payload)
return payload, err
}
// Payload returns the parsed event payload. For recognized event types,
// a value of the corresponding struct type will be returned.
//
// Deprecated: Use ParsePayload instead, which returns an error
// rather than panics if JSON unmarshaling raw payload fails.
func (e *Event) Payload() (payload interface{}) {
var err error
payload, err = e.ParsePayload()
if err != nil {
panic(err)
}
return payload
}
// ListEvents drinks from the firehose of all public events across GitHub. // ListEvents drinks from the firehose of all public events across GitHub.
// //
// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events // GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events

View File

@ -34,18 +34,33 @@ type MarketplacePlan struct {
Description *string `json:"description,omitempty"` Description *string `json:"description,omitempty"`
MonthlyPriceInCents *int `json:"monthly_price_in_cents,omitempty"` MonthlyPriceInCents *int `json:"monthly_price_in_cents,omitempty"`
YearlyPriceInCents *int `json:"yearly_price_in_cents,omitempty"` YearlyPriceInCents *int `json:"yearly_price_in_cents,omitempty"`
// The pricing model for this listing. Can be one of "flat-rate", "per-unit", or "free".
PriceModel *string `json:"price_model,omitempty"` PriceModel *string `json:"price_model,omitempty"`
UnitName *string `json:"unit_name,omitempty"` UnitName *string `json:"unit_name,omitempty"`
Bullets *[]string `json:"bullets,omitempty"` Bullets *[]string `json:"bullets,omitempty"`
// State can be one of the values "draft" or "published".
State *string `json:"state,omitempty"`
HasFreeTrial *bool `json:"has_free_trial,omitempty"`
} }
// MarketplacePurchase represents a GitHub Apps Marketplace Purchase. // MarketplacePurchase represents a GitHub Apps Marketplace Purchase.
type MarketplacePurchase struct { type MarketplacePurchase struct {
// BillingCycle can be one of the values "yearly", "monthly" or nil.
BillingCycle *string `json:"billing_cycle,omitempty"` BillingCycle *string `json:"billing_cycle,omitempty"`
NextBillingDate *string `json:"next_billing_date,omitempty"` NextBillingDate *Timestamp `json:"next_billing_date,omitempty"`
UnitCount *int `json:"unit_count,omitempty"` UnitCount *int `json:"unit_count,omitempty"`
Plan *MarketplacePlan `json:"plan,omitempty"` Plan *MarketplacePlan `json:"plan,omitempty"`
Account *MarketplacePlanAccount `json:"account,omitempty"` Account *MarketplacePlanAccount `json:"account,omitempty"`
OnFreeTrial *bool `json:"on_free_trial,omitempty"`
FreeTrialEndsOn *Timestamp `json:"free_trial_ends_on,omitempty"`
}
// MarketplacePendingChange represents a pending change to a GitHub Apps Marketplace Plan.
type MarketplacePendingChange struct {
EffectiveDate *Timestamp `json:"effective_date,omitempty"`
UnitCount *int `json:"unit_count,omitempty"`
ID *int64 `json:"id,omitempty"`
Plan *MarketplacePlan `json:"plan,omitempty"`
} }
// MarketplacePlanAccount represents a GitHub Account (user or organization) on a specific plan. // MarketplacePlanAccount represents a GitHub Account (user or organization) on a specific plan.
@ -57,6 +72,7 @@ type MarketplacePlanAccount struct {
Email *string `json:"email,omitempty"` Email *string `json:"email,omitempty"`
OrganizationBillingEmail *string `json:"organization_billing_email,omitempty"` OrganizationBillingEmail *string `json:"organization_billing_email,omitempty"`
MarketplacePurchase *MarketplacePurchase `json:"marketplace_purchase,omitempty"` MarketplacePurchase *MarketplacePurchase `json:"marketplace_purchase,omitempty"`
MarketplacePendingChange *MarketplacePendingChange `json:"marketplace_pending_change,omitempty"`
} }
// ListPlans lists all plans for your Marketplace listing. // ListPlans lists all plans for your Marketplace listing.
@ -155,7 +171,6 @@ func (s *MarketplaceService) ListMarketplacePurchasesForUser(ctx context.Context
if err != nil { if err != nil {
return nil, resp, err return nil, resp, err
} }
return purchases, resp, nil return purchases, resp, nil
} }

View File

@ -24,6 +24,7 @@ type CheckRun struct {
ExternalID *string `json:"external_id,omitempty"` ExternalID *string `json:"external_id,omitempty"`
URL *string `json:"url,omitempty"` URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"` HTMLURL *string `json:"html_url,omitempty"`
DetailsURL *string `json:"details_url,omitempty"`
Status *string `json:"status,omitempty"` Status *string `json:"status,omitempty"`
Conclusion *string `json:"conclusion,omitempty"` Conclusion *string `json:"conclusion,omitempty"`
StartedAt *Timestamp `json:"started_at,omitempty"` StartedAt *Timestamp `json:"started_at,omitempty"`
@ -143,6 +144,14 @@ type CreateCheckRunOptions struct {
StartedAt *Timestamp `json:"started_at,omitempty"` // The time that the check run began. (Optional.) StartedAt *Timestamp `json:"started_at,omitempty"` // The time that the check run began. (Optional.)
CompletedAt *Timestamp `json:"completed_at,omitempty"` // The time the check completed. (Optional. Required if you provide conclusion.) CompletedAt *Timestamp `json:"completed_at,omitempty"` // The time the check completed. (Optional. Required if you provide conclusion.)
Output *CheckRunOutput `json:"output,omitempty"` // Provide descriptive details about the run. (Optional) Output *CheckRunOutput `json:"output,omitempty"` // Provide descriptive details about the run. (Optional)
Actions []*CheckRunAction `json:"actions,omitempty"` // Possible further actions the integrator can perform, which a user may trigger. (Optional.)
}
// CheckRunAction exposes further actions the integrator can perform, which a user may trigger.
type CheckRunAction struct {
Label string `json:"label"` // The text to be displayed on a button in the web UI. The maximum size is 20 characters. (Required.)
Description string `json:"description"` // A short explanation of what this action would do. The maximum size is 40 characters. (Required.)
Identifier string `json:"identifier"` // A reference for the action on the integrator's system. The maximum size is 20 characters. (Required.)
} }
// CreateCheckRun creates a check run for repository. // CreateCheckRun creates a check run for repository.
@ -177,6 +186,7 @@ type UpdateCheckRunOptions struct {
Conclusion *string `json:"conclusion,omitempty"` // Can be one of "success", "failure", "neutral", "cancelled", "timed_out", or "action_required". (Optional. Required if you provide a status of "completed".) Conclusion *string `json:"conclusion,omitempty"` // Can be one of "success", "failure", "neutral", "cancelled", "timed_out", or "action_required". (Optional. Required if you provide a status of "completed".)
CompletedAt *Timestamp `json:"completed_at,omitempty"` // The time the check completed. (Optional. Required if you provide conclusion.) CompletedAt *Timestamp `json:"completed_at,omitempty"` // The time the check completed. (Optional. Required if you provide conclusion.)
Output *CheckRunOutput `json:"output,omitempty"` // Provide descriptive details about the run. (Optional) Output *CheckRunOutput `json:"output,omitempty"` // Provide descriptive details about the run. (Optional)
Actions []*CheckRunAction `json:"actions,omitempty"` // Possible further actions the integrator can perform, which a user may trigger. (Optional.)
} }
// UpdateCheckRun updates a check run for a specific commit in a repository. // UpdateCheckRun updates a check run for a specific commit in a repository.

126
vendor/github.com/google/go-github/github/event.go generated vendored Normal file
View File

@ -0,0 +1,126 @@
// Copyright 2018 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"time"
)
// Event represents a GitHub event.
type Event struct {
Type *string `json:"type,omitempty"`
Public *bool `json:"public,omitempty"`
RawPayload *json.RawMessage `json:"payload,omitempty"`
Repo *Repository `json:"repo,omitempty"`
Actor *User `json:"actor,omitempty"`
Org *Organization `json:"org,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
ID *string `json:"id,omitempty"`
}
func (e Event) String() string {
return Stringify(e)
}
// ParsePayload parses the event payload. For recognized event types,
// a value of the corresponding struct type will be returned.
func (e *Event) ParsePayload() (payload interface{}, err error) {
switch *e.Type {
case "CheckRunEvent":
payload = &CheckRunEvent{}
case "CheckSuiteEvent":
payload = &CheckSuiteEvent{}
case "CommitCommentEvent":
payload = &CommitCommentEvent{}
case "CreateEvent":
payload = &CreateEvent{}
case "DeleteEvent":
payload = &DeleteEvent{}
case "DeploymentEvent":
payload = &DeploymentEvent{}
case "DeploymentStatusEvent":
payload = &DeploymentStatusEvent{}
case "ForkEvent":
payload = &ForkEvent{}
case "GitHubAppAuthorizationEvent":
payload = &GitHubAppAuthorizationEvent{}
case "GollumEvent":
payload = &GollumEvent{}
case "InstallationEvent":
payload = &InstallationEvent{}
case "InstallationRepositoriesEvent":
payload = &InstallationRepositoriesEvent{}
case "IssueCommentEvent":
payload = &IssueCommentEvent{}
case "IssuesEvent":
payload = &IssuesEvent{}
case "LabelEvent":
payload = &LabelEvent{}
case "MarketplacePurchaseEvent":
payload = &MarketplacePurchaseEvent{}
case "MemberEvent":
payload = &MemberEvent{}
case "MembershipEvent":
payload = &MembershipEvent{}
case "MilestoneEvent":
payload = &MilestoneEvent{}
case "OrganizationEvent":
payload = &OrganizationEvent{}
case "OrgBlockEvent":
payload = &OrgBlockEvent{}
case "PageBuildEvent":
payload = &PageBuildEvent{}
case "PingEvent":
payload = &PingEvent{}
case "ProjectEvent":
payload = &ProjectEvent{}
case "ProjectCardEvent":
payload = &ProjectCardEvent{}
case "ProjectColumnEvent":
payload = &ProjectColumnEvent{}
case "PublicEvent":
payload = &PublicEvent{}
case "PullRequestEvent":
payload = &PullRequestEvent{}
case "PullRequestReviewEvent":
payload = &PullRequestReviewEvent{}
case "PullRequestReviewCommentEvent":
payload = &PullRequestReviewCommentEvent{}
case "PushEvent":
payload = &PushEvent{}
case "ReleaseEvent":
payload = &ReleaseEvent{}
case "RepositoryEvent":
payload = &RepositoryEvent{}
case "RepositoryVulnerabilityAlertEvent":
payload = &RepositoryVulnerabilityAlertEvent{}
case "StatusEvent":
payload = &StatusEvent{}
case "TeamEvent":
payload = &TeamEvent{}
case "TeamAddEvent":
payload = &TeamAddEvent{}
case "WatchEvent":
payload = &WatchEvent{}
}
err = json.Unmarshal(*e.RawPayload, &payload)
return payload, err
}
// Payload returns the parsed event payload. For recognized event types,
// a value of the corresponding struct type will be returned.
//
// Deprecated: Use ParsePayload instead, which returns an error
// rather than panics if JSON unmarshaling raw payload fails.
func (e *Event) Payload() (payload interface{}) {
var err error
payload, err = e.ParsePayload()
if err != nil {
panic(err)
}
return payload
}

View File

@ -7,13 +7,19 @@
package github package github
// RequestedAction is included in a CheckRunEvent when a user has invoked an action,
// i.e. when the CheckRunEvent's Action field is "requested_action".
type RequestedAction struct {
Identifier string `json:"identifier"` // The integrator reference of the action requested by the user.
}
// CheckRunEvent is triggered when a check run is "created", "updated", or "re-requested". // CheckRunEvent is triggered when a check run is "created", "updated", or "re-requested".
// The Webhook event name is "check_run". // The Webhook event name is "check_run".
// //
// GitHub API docs: https://developer.github.com/v3/activity/events/types/#checkrunevent // GitHub API docs: https://developer.github.com/v3/activity/events/types/#checkrunevent
type CheckRunEvent struct { type CheckRunEvent struct {
CheckRun *CheckRun `json:"check_run,omitempty"` CheckRun *CheckRun `json:"check_run,omitempty"`
// The action performed. Can be "created", "updated" or "re-requested". // The action performed. Can be "created", "updated", "rerequested" or "requested_action".
Action *string `json:"action,omitempty"` Action *string `json:"action,omitempty"`
// The following fields are only populated by Webhook events. // The following fields are only populated by Webhook events.
@ -21,6 +27,9 @@ type CheckRunEvent struct {
Org *Organization `json:"organization,omitempty"` Org *Organization `json:"organization,omitempty"`
Sender *User `json:"sender,omitempty"` Sender *User `json:"sender,omitempty"`
Installation *Installation `json:"installation,omitempty"` Installation *Installation `json:"installation,omitempty"`
// The action requested by the user. Populated when the Action is "requested_action".
RequestedAction *RequestedAction `json:"requested_action,omitempty"` //
} }
// CheckSuiteEvent is triggered when a check suite is "completed", "requested", or "re-requested". // CheckSuiteEvent is triggered when a check suite is "completed", "requested", or "re-requested".
@ -139,6 +148,18 @@ type ForkEvent struct {
Installation *Installation `json:"installation,omitempty"` Installation *Installation `json:"installation,omitempty"`
} }
// GitHubAppAuthorizationEvent is triggered when a user's authorization for a
// GitHub Application is revoked.
//
// GitHub API docs: https://developer.github.com/v3/activity/events/types/#githubappauthorizationevent
type GitHubAppAuthorizationEvent struct {
// The action performed. Can be "revoked".
Action *string `json:"action,omitempty"`
// The following fields are only populated by Webhook events.
Sender *User `json:"sender,omitempty"`
}
// Page represents a single Wiki page. // Page represents a single Wiki page.
type Page struct { type Page struct {
PageName *string `json:"page_name,omitempty"` PageName *string `json:"page_name,omitempty"`
@ -308,7 +329,7 @@ type LabelEvent struct {
// Github API docs: https://developer.github.com/v3/activity/events/types/#marketplacepurchaseevent // Github API docs: https://developer.github.com/v3/activity/events/types/#marketplacepurchaseevent
type MarketplacePurchaseEvent struct { type MarketplacePurchaseEvent struct {
// Action is the action that was performed. Possible values are: // Action is the action that was performed. Possible values are:
// "purchased", "cancelled", "changed". // "purchased", "cancelled", "pending_change", "pending_change_cancelled", "changed".
Action *string `json:"action,omitempty"` Action *string `json:"action,omitempty"`
// The following fields are only populated by Webhook events. // The following fields are only populated by Webhook events.

View File

@ -68,9 +68,6 @@ func (s *GitService) GetCommit(ctx context.Context, owner string, repo string, s
return nil, nil, err return nil, nil, err
} }
// TODO: remove custom Accept headers when APIs fully launch.
req.Header.Set("Accept", mediaTypeGitSigningPreview)
c := new(Commit) c := new(Commit)
resp, err := s.client.Do(ctx, req, c) resp, err := s.client.Do(ctx, req, c)
if err != nil { if err != nil {

View File

@ -43,9 +43,6 @@ func (s *GitService) GetTag(ctx context.Context, owner string, repo string, sha
return nil, nil, err return nil, nil, err
} }
// TODO: remove custom Accept headers when APIs fully launch.
req.Header.Set("Accept", mediaTypeGitSigningPreview)
tag := new(Tag) tag := new(Tag)
resp, err := s.client.Do(ctx, req, tag) resp, err := s.client.Do(ctx, req, tag)
return tag, resp, err return tag, resp, err

View File

@ -492,6 +492,14 @@ func (c *CheckRun) GetConclusion() string {
return *c.Conclusion return *c.Conclusion
} }
// GetDetailsURL returns the DetailsURL field if it's non-nil, zero value otherwise.
func (c *CheckRun) GetDetailsURL() string {
if c == nil || c.DetailsURL == nil {
return ""
}
return *c.DetailsURL
}
// GetExternalID returns the ExternalID field if it's non-nil, zero value otherwise. // GetExternalID returns the ExternalID field if it's non-nil, zero value otherwise.
func (c *CheckRun) GetExternalID() string { func (c *CheckRun) GetExternalID() string {
if c == nil || c.ExternalID == nil { if c == nil || c.ExternalID == nil {
@ -676,6 +684,14 @@ func (c *CheckRunEvent) GetRepo() *Repository {
return c.Repo return c.Repo
} }
// GetRequestedAction returns the RequestedAction field.
func (c *CheckRunEvent) GetRequestedAction() *RequestedAction {
if c == nil {
return nil
}
return c.RequestedAction
}
// GetSender returns the Sender field. // GetSender returns the Sender field.
func (c *CheckRunEvent) GetSender() *User { func (c *CheckRunEvent) GetSender() *User {
if c == nil { if c == nil {
@ -1292,6 +1308,14 @@ func (c *CommitFile) GetPatch() string {
return *c.Patch 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. // GetRawURL returns the RawURL field if it's non-nil, zero value otherwise.
func (c *CommitFile) GetRawURL() string { func (c *CommitFile) GetRawURL() string {
if c == nil || c.RawURL == nil { if c == nil || c.RawURL == nil {
@ -2292,6 +2316,14 @@ func (d *DeploymentStatusRequest) GetDescription() string {
return *d.Description 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. // GetEnvironmentURL returns the EnvironmentURL field if it's non-nil, zero value otherwise.
func (d *DeploymentStatusRequest) GetEnvironmentURL() string { func (d *DeploymentStatusRequest) GetEnvironmentURL() string {
if d == nil || d.EnvironmentURL == nil { if d == nil || d.EnvironmentURL == nil {
@ -2916,6 +2948,22 @@ func (g *GistStats) GetTotalGists() int {
return *g.TotalGists return *g.TotalGists
} }
// GetAction returns the Action field if it's non-nil, zero value otherwise.
func (g *GitHubAppAuthorizationEvent) GetAction() string {
if g == nil || g.Action == nil {
return ""
}
return *g.Action
}
// GetSender returns the Sender field.
func (g *GitHubAppAuthorizationEvent) GetSender() *User {
if g == nil {
return nil
}
return g.Sender
}
// GetName returns the Name field if it's non-nil, zero value otherwise. // GetName returns the Name field if it's non-nil, zero value otherwise.
func (g *Gitignore) GetName() string { func (g *Gitignore) GetName() string {
if g == nil || g.Name == nil { if g == nil || g.Name == nil {
@ -3564,6 +3612,30 @@ func (i *InstallationToken) GetToken() string {
return *i.Token return *i.Token
} }
// GetExpiresAt returns the ExpiresAt field if it's non-nil, zero value otherwise.
func (i *InteractionRestriction) GetExpiresAt() Timestamp {
if i == nil || i.ExpiresAt == nil {
return Timestamp{}
}
return *i.ExpiresAt
}
// GetLimit returns the Limit field if it's non-nil, zero value otherwise.
func (i *InteractionRestriction) GetLimit() string {
if i == nil || i.Limit == nil {
return ""
}
return *i.Limit
}
// GetOrigin returns the Origin field if it's non-nil, zero value otherwise.
func (i *InteractionRestriction) GetOrigin() string {
if i == nil || i.Origin == nil {
return ""
}
return *i.Origin
}
// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. // GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
func (i *Invitation) GetCreatedAt() time.Time { func (i *Invitation) GetCreatedAt() time.Time {
if i == nil || i.CreatedAt == nil { if i == nil || i.CreatedAt == nil {
@ -4060,6 +4132,14 @@ func (i *IssueEvent) GetMilestone() *Milestone {
return i.Milestone return i.Milestone
} }
// GetProjectCard returns the ProjectCard field.
func (i *IssueEvent) GetProjectCard() *ProjectCard {
if i == nil {
return nil
}
return i.ProjectCard
}
// GetRename returns the Rename field. // GetRename returns the Rename field.
func (i *IssueEvent) GetRename() *Rename { func (i *IssueEvent) GetRename() *Rename {
if i == nil { if i == nil {
@ -4636,6 +4716,46 @@ func (l *ListCheckSuiteResults) GetTotal() int {
return *l.Total return *l.Total
} }
// GetAffiliation returns the Affiliation field if it's non-nil, zero value otherwise.
func (l *ListCollaboratorOptions) GetAffiliation() string {
if l == nil || l.Affiliation == nil {
return ""
}
return *l.Affiliation
}
// GetEffectiveDate returns the EffectiveDate field if it's non-nil, zero value otherwise.
func (m *MarketplacePendingChange) GetEffectiveDate() Timestamp {
if m == nil || m.EffectiveDate == nil {
return Timestamp{}
}
return *m.EffectiveDate
}
// GetID returns the ID field if it's non-nil, zero value otherwise.
func (m *MarketplacePendingChange) GetID() int64 {
if m == nil || m.ID == nil {
return 0
}
return *m.ID
}
// GetPlan returns the Plan field.
func (m *MarketplacePendingChange) GetPlan() *MarketplacePlan {
if m == nil {
return nil
}
return m.Plan
}
// GetUnitCount returns the UnitCount field if it's non-nil, zero value otherwise.
func (m *MarketplacePendingChange) GetUnitCount() int {
if m == nil || m.UnitCount == nil {
return 0
}
return *m.UnitCount
}
// GetAccountsURL returns the AccountsURL field if it's non-nil, zero value otherwise. // GetAccountsURL returns the AccountsURL field if it's non-nil, zero value otherwise.
func (m *MarketplacePlan) GetAccountsURL() string { func (m *MarketplacePlan) GetAccountsURL() string {
if m == nil || m.AccountsURL == nil { if m == nil || m.AccountsURL == nil {
@ -4660,6 +4780,14 @@ func (m *MarketplacePlan) GetDescription() string {
return *m.Description return *m.Description
} }
// GetHasFreeTrial returns the HasFreeTrial field if it's non-nil, zero value otherwise.
func (m *MarketplacePlan) GetHasFreeTrial() bool {
if m == nil || m.HasFreeTrial == nil {
return false
}
return *m.HasFreeTrial
}
// GetID returns the ID field if it's non-nil, zero value otherwise. // GetID returns the ID field if it's non-nil, zero value otherwise.
func (m *MarketplacePlan) GetID() int64 { func (m *MarketplacePlan) GetID() int64 {
if m == nil || m.ID == nil { if m == nil || m.ID == nil {
@ -4692,6 +4820,14 @@ func (m *MarketplacePlan) GetPriceModel() string {
return *m.PriceModel return *m.PriceModel
} }
// GetState returns the State field if it's non-nil, zero value otherwise.
func (m *MarketplacePlan) GetState() string {
if m == nil || m.State == nil {
return ""
}
return *m.State
}
// GetUnitName returns the UnitName field if it's non-nil, zero value otherwise. // GetUnitName returns the UnitName field if it's non-nil, zero value otherwise.
func (m *MarketplacePlan) GetUnitName() string { func (m *MarketplacePlan) GetUnitName() string {
if m == nil || m.UnitName == nil { if m == nil || m.UnitName == nil {
@ -4740,6 +4876,14 @@ func (m *MarketplacePlanAccount) GetLogin() string {
return *m.Login return *m.Login
} }
// GetMarketplacePendingChange returns the MarketplacePendingChange field.
func (m *MarketplacePlanAccount) GetMarketplacePendingChange() *MarketplacePendingChange {
if m == nil {
return nil
}
return m.MarketplacePendingChange
}
// GetMarketplacePurchase returns the MarketplacePurchase field. // GetMarketplacePurchase returns the MarketplacePurchase field.
func (m *MarketplacePlanAccount) GetMarketplacePurchase() *MarketplacePurchase { func (m *MarketplacePlanAccount) GetMarketplacePurchase() *MarketplacePurchase {
if m == nil { if m == nil {
@ -4788,14 +4932,30 @@ func (m *MarketplacePurchase) GetBillingCycle() string {
return *m.BillingCycle return *m.BillingCycle
} }
// GetFreeTrialEndsOn returns the FreeTrialEndsOn field if it's non-nil, zero value otherwise.
func (m *MarketplacePurchase) GetFreeTrialEndsOn() Timestamp {
if m == nil || m.FreeTrialEndsOn == nil {
return Timestamp{}
}
return *m.FreeTrialEndsOn
}
// GetNextBillingDate returns the NextBillingDate field if it's non-nil, zero value otherwise. // GetNextBillingDate returns the NextBillingDate field if it's non-nil, zero value otherwise.
func (m *MarketplacePurchase) GetNextBillingDate() string { func (m *MarketplacePurchase) GetNextBillingDate() Timestamp {
if m == nil || m.NextBillingDate == nil { if m == nil || m.NextBillingDate == nil {
return "" return Timestamp{}
} }
return *m.NextBillingDate return *m.NextBillingDate
} }
// GetOnFreeTrial returns the OnFreeTrial field if it's non-nil, zero value otherwise.
func (m *MarketplacePurchase) GetOnFreeTrial() bool {
if m == nil || m.OnFreeTrial == nil {
return false
}
return *m.OnFreeTrial
}
// GetPlan returns the Plan field. // GetPlan returns the Plan field.
func (m *MarketplacePurchase) GetPlan() *MarketplacePlan { func (m *MarketplacePurchase) GetPlan() *MarketplacePlan {
if m == nil { if m == nil {
@ -6404,6 +6564,14 @@ func (p *ProjectCard) GetColumnID() int64 {
return *p.ColumnID return *p.ColumnID
} }
// GetColumnName returns the ColumnName field if it's non-nil, zero value otherwise.
func (p *ProjectCard) GetColumnName() string {
if p == nil || p.ColumnName == nil {
return ""
}
return *p.ColumnName
}
// GetColumnURL returns the ColumnURL field if it's non-nil, zero value otherwise. // GetColumnURL returns the ColumnURL field if it's non-nil, zero value otherwise.
func (p *ProjectCard) GetColumnURL() string { func (p *ProjectCard) GetColumnURL() string {
if p == nil || p.ColumnURL == nil { if p == nil || p.ColumnURL == nil {
@ -6460,6 +6628,30 @@ func (p *ProjectCard) GetNote() string {
return *p.Note return *p.Note
} }
// GetPreviousColumnName returns the PreviousColumnName field if it's non-nil, zero value otherwise.
func (p *ProjectCard) GetPreviousColumnName() string {
if p == nil || p.PreviousColumnName == nil {
return ""
}
return *p.PreviousColumnName
}
// GetProjectID returns the ProjectID field if it's non-nil, zero value otherwise.
func (p *ProjectCard) GetProjectID() int64 {
if p == nil || p.ProjectID == nil {
return 0
}
return *p.ProjectID
}
// GetProjectURL returns the ProjectURL field if it's non-nil, zero value otherwise.
func (p *ProjectCard) GetProjectURL() string {
if p == nil || p.ProjectURL == nil {
return ""
}
return *p.ProjectURL
}
// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise. // GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
func (p *ProjectCard) GetUpdatedAt() Timestamp { func (p *ProjectCard) GetUpdatedAt() Timestamp {
if p == nil || p.UpdatedAt == nil { if p == nil || p.UpdatedAt == nil {
@ -6556,6 +6748,14 @@ func (p *ProjectCardOptions) GetArchived() bool {
return *p.Archived return *p.Archived
} }
// GetPermission returns the Permission field if it's non-nil, zero value otherwise.
func (p *ProjectCollaboratorOptions) GetPermission() string {
if p == nil || p.Permission == nil {
return ""
}
return *p.Permission
}
// GetCardsURL returns the CardsURL field if it's non-nil, zero value otherwise. // GetCardsURL returns the CardsURL field if it's non-nil, zero value otherwise.
func (p *ProjectColumn) GetCardsURL() string { func (p *ProjectColumn) GetCardsURL() string {
if p == nil || p.CardsURL == nil { if p == nil || p.CardsURL == nil {
@ -6780,6 +6980,22 @@ func (p *ProjectOptions) GetState() string {
return *p.State return *p.State
} }
// GetPermission returns the Permission field if it's non-nil, zero value otherwise.
func (p *ProjectPermissionLevel) GetPermission() string {
if p == nil || p.Permission == nil {
return ""
}
return *p.Permission
}
// GetUser returns the User field.
func (p *ProjectPermissionLevel) GetUser() *User {
if p == nil {
return nil
}
return p.User
}
// GetEnforceAdmins returns the EnforceAdmins field. // GetEnforceAdmins returns the EnforceAdmins field.
func (p *Protection) GetEnforceAdmins() *AdminEnforcement { func (p *Protection) GetEnforceAdmins() *AdminEnforcement {
if p == nil { if p == nil {
@ -10100,6 +10316,22 @@ func (s *ServiceHook) GetName() string {
return *s.Name 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. // GetPayload returns the Payload field if it's non-nil, zero value otherwise.
func (s *SignatureVerification) GetPayload() string { func (s *SignatureVerification) GetPayload() string {
if s == nil || s.Payload == nil { if s == nil || s.Payload == nil {
@ -10900,6 +11132,14 @@ func (t *TeamLDAPMapping) GetURL() string {
return *t.URL return *t.URL
} }
// GetPermission returns the Permission field if it's non-nil, zero value otherwise.
func (t *TeamProjectOptions) GetPermission() string {
if t == nil || t.Permission == nil {
return ""
}
return *t.Permission
}
// GetFragment returns the Fragment field if it's non-nil, zero value otherwise. // GetFragment returns the Fragment field if it's non-nil, zero value otherwise.
func (t *TextMatch) GetFragment() string { func (t *TextMatch) GetFragment() string {
if t == nil || t.Fragment == nil { if t == nil || t.Fragment == nil {
@ -11004,6 +11244,14 @@ func (t *Timeline) GetMilestone() *Milestone {
return t.Milestone return t.Milestone
} }
// GetProjectCard returns the ProjectCard field.
func (t *Timeline) GetProjectCard() *ProjectCard {
if t == nil {
return nil
}
return t.ProjectCard
}
// GetRename returns the Rename field. // GetRename returns the Rename field.
func (t *Timeline) GetRename() *Rename { func (t *Timeline) GetRename() *Rename {
if t == nil { if t == nil {
@ -11564,6 +11812,14 @@ func (u *User) GetTotalPrivateRepos() int {
return *u.TotalPrivateRepos return *u.TotalPrivateRepos
} }
// GetTwoFactorAuthentication returns the TwoFactorAuthentication field if it's non-nil, zero value otherwise.
func (u *User) GetTwoFactorAuthentication() bool {
if u == nil || u.TwoFactorAuthentication == nil {
return false
}
return *u.TwoFactorAuthentication
}
// GetType returns the Type field if it's non-nil, zero value otherwise. // GetType returns the Type field if it's non-nil, zero value otherwise.
func (u *User) GetType() string { func (u *User) GetType() string {
if u == nil || u.Type == nil { if u == nil || u.Type == nil {

View File

@ -54,21 +54,18 @@ const (
// https://developer.github.com/changes/2016-04-06-deployment-and-deployment-status-enhancements/ // https://developer.github.com/changes/2016-04-06-deployment-and-deployment-status-enhancements/
mediaTypeDeploymentStatusPreview = "application/vnd.github.ant-man-preview+json" 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/ // https://developer.github.com/changes/2016-02-19-source-import-preview-api/
mediaTypeImportPreview = "application/vnd.github.barred-rock-preview" mediaTypeImportPreview = "application/vnd.github.barred-rock-preview"
// https://developer.github.com/changes/2016-05-12-reactions-api-preview/ // https://developer.github.com/changes/2016-05-12-reactions-api-preview/
mediaTypeReactionsPreview = "application/vnd.github.squirrel-girl-preview" mediaTypeReactionsPreview = "application/vnd.github.squirrel-girl-preview"
// https://developer.github.com/changes/2016-04-04-git-signing-api-preview/
mediaTypeGitSigningPreview = "application/vnd.github.cryptographer-preview+json"
// https://developer.github.com/changes/2016-05-23-timeline-preview-api/ // https://developer.github.com/changes/2016-05-23-timeline-preview-api/
mediaTypeTimelinePreview = "application/vnd.github.mockingbird-preview+json" mediaTypeTimelinePreview = "application/vnd.github.mockingbird-preview+json"
// https://developer.github.com/changes/2016-06-14-repository-invitations/
mediaTypeRepositoryInvitationsPreview = "application/vnd.github.swamp-thing-preview+json"
// https://developer.github.com/changes/2016-07-06-github-pages-preiew-api/ // https://developer.github.com/changes/2016-07-06-github-pages-preiew-api/
mediaTypePagesPreview = "application/vnd.github.mister-fantastic-preview+json" mediaTypePagesPreview = "application/vnd.github.mister-fantastic-preview+json"
@ -122,6 +119,15 @@ const (
// https://developer.github.com/enterprise/2.13/v3/repos/pre_receive_hooks/ // https://developer.github.com/enterprise/2.13/v3/repos/pre_receive_hooks/
mediaTypePreReceiveHooksPreview = "application/vnd.github.eye-scream-preview" 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"
// https://developer.github.com/changes/2018-09-05-project-card-events/
mediaTypeProjectCardDetailsPreview = "application/vnd.github.starfox-preview+json"
// https://developer.github.com/changes/2018-12-18-interactions-preview/
mediaTypeInteractionRestrictionsPreview = "application/vnd.github.sombra-preview+json"
) )
// A Client manages communication with the GitHub API. // A Client manages communication with the GitHub API.
@ -154,6 +160,7 @@ type Client struct {
Gists *GistsService Gists *GistsService
Git *GitService Git *GitService
Gitignores *GitignoresService Gitignores *GitignoresService
Interactions *InteractionsService
Issues *IssuesService Issues *IssuesService
Licenses *LicensesService Licenses *LicensesService
Marketplace *MarketplaceService Marketplace *MarketplaceService
@ -246,6 +253,7 @@ func NewClient(httpClient *http.Client) *Client {
c.Gists = (*GistsService)(&c.common) c.Gists = (*GistsService)(&c.common)
c.Git = (*GitService)(&c.common) c.Git = (*GitService)(&c.common)
c.Gitignores = (*GitignoresService)(&c.common) c.Gitignores = (*GitignoresService)(&c.common)
c.Interactions = (*InteractionsService)(&c.common)
c.Issues = (*IssuesService)(&c.common) c.Issues = (*IssuesService)(&c.common)
c.Licenses = (*LicensesService)(&c.common) c.Licenses = (*LicensesService)(&c.common)
c.Marketplace = &MarketplaceService{client: c} c.Marketplace = &MarketplaceService{client: c}

View File

@ -0,0 +1,28 @@
// Copyright 2018 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
// InteractionsService handles communication with the repository and organization related
// methods of the GitHub API.
//
// GitHub API docs: https://developer.github.com/v3/interactions/
type InteractionsService service
// InteractionRestriction represents the interaction restrictions for repository and organization.
type InteractionRestriction struct {
// Specifies the group of GitHub users who can
// comment, open issues, or create pull requests for the given repository.
// Possible values are: "existing_users", "contributors_only" and "collaborators_only".
Limit *string `json:"limit,omitempty"`
// Origin specifies the type of the resource to interact with.
// Possible values are: "repository" and "organization".
Origin *string `json:"origin,omitempty"`
// ExpiresAt specifies the time after which the interaction restrictions expire.
// The default expiry time is 24 hours from the time restriction is created.
ExpiresAt *Timestamp `json:"expires_at,omitempty"`
}

View File

@ -0,0 +1,80 @@
// Copyright 2019 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"context"
"fmt"
)
// GetRestrictionsForOrg fetches the interaction restrictions for an organization.
//
// GitHub API docs: https://developer.github.com/v3/interactions/orgs/#get-interaction-restrictions-for-an-organization
func (s *InteractionsService) GetRestrictionsForOrg(ctx context.Context, organization string) (*InteractionRestriction, *Response, error) {
u := fmt.Sprintf("orgs/%v/interaction-limits", organization)
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", mediaTypeInteractionRestrictionsPreview)
organizationInteractions := new(InteractionRestriction)
resp, err := s.client.Do(ctx, req, organizationInteractions)
if err != nil {
return nil, resp, err
}
return organizationInteractions, resp, nil
}
// UpdateRestrictionsForOrg adds or updates the interaction restrictions for an organization.
//
// limit specifies the group of GitHub users who can comment, open issues, or create pull requests
// in public repositories for the given organization.
// Possible values are: "existing_users", "contributors_only", "collaborators_only".
//
// GitHub API docs: https://developer.github.com/v3/interactions/orgs/#add-or-update-interaction-restrictions-for-an-organization
func (s *InteractionsService) UpdateRestrictionsForOrg(ctx context.Context, organization, limit string) (*InteractionRestriction, *Response, error) {
u := fmt.Sprintf("orgs/%v/interaction-limits", organization)
interaction := &InteractionRestriction{Limit: String(limit)}
req, err := s.client.NewRequest("PUT", u, interaction)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeInteractionRestrictionsPreview)
organizationInteractions := new(InteractionRestriction)
resp, err := s.client.Do(ctx, req, organizationInteractions)
if err != nil {
return nil, resp, err
}
return organizationInteractions, resp, nil
}
// RemoveRestrictionsFromOrg removes the interaction restrictions for an organization.
//
// GitHub API docs: https://developer.github.com/v3/interactions/orgs/#remove-interaction-restrictions-for-an-organization
func (s *InteractionsService) RemoveRestrictionsFromOrg(ctx context.Context, organization string) (*Response, error) {
u := fmt.Sprintf("orgs/%v/interaction-limits", organization)
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", mediaTypeInteractionRestrictionsPreview)
return s.client.Do(ctx, req, nil)
}

View File

@ -0,0 +1,80 @@
// Copyright 2018 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"context"
"fmt"
)
// GetRestrictionsForRepo fetches the interaction restrictions for a repository.
//
// GitHub API docs: https://developer.github.com/v3/interactions/repos/#get-interaction-restrictions-for-a-repository
func (s *InteractionsService) GetRestrictionsForRepo(ctx context.Context, owner, repo string) (*InteractionRestriction, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/interaction-limits", owner, repo)
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", mediaTypeInteractionRestrictionsPreview)
repositoryInteractions := new(InteractionRestriction)
resp, err := s.client.Do(ctx, req, repositoryInteractions)
if err != nil {
return nil, resp, err
}
return repositoryInteractions, resp, nil
}
// UpdateRestrictionsForRepo adds or updates the interaction restrictions for a repository.
//
// limit specifies the group of GitHub users who can comment, open issues, or create pull requests
// for the given repository.
// Possible values are: "existing_users", "contributors_only", "collaborators_only".
//
// GitHub API docs: https://developer.github.com/v3/interactions/repos/#add-or-update-interaction-restrictions-for-a-repository
func (s *InteractionsService) UpdateRestrictionsForRepo(ctx context.Context, owner, repo, limit string) (*InteractionRestriction, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/interaction-limits", owner, repo)
interaction := &InteractionRestriction{Limit: String(limit)}
req, err := s.client.NewRequest("PUT", u, interaction)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeInteractionRestrictionsPreview)
repositoryInteractions := new(InteractionRestriction)
resp, err := s.client.Do(ctx, req, repositoryInteractions)
if err != nil {
return nil, resp, err
}
return repositoryInteractions, resp, nil
}
// RemoveRestrictionsFromRepo removes the interaction restrictions for a repository.
//
// GitHub API docs: https://developer.github.com/v3/interactions/repos/#remove-interaction-restrictions-for-a-repository
func (s *InteractionsService) RemoveRestrictionsFromRepo(ctx context.Context, owner, repo string) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/interaction-limits", owner, repo)
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", mediaTypeInteractionRestrictionsPreview)
return s.client.Do(ctx, req, nil)
}

View File

@ -8,6 +8,7 @@ package github
import ( import (
"context" "context"
"fmt" "fmt"
"strings"
"time" "time"
) )
@ -75,6 +76,7 @@ type IssueEvent struct {
Label *Label `json:"label,omitempty"` Label *Label `json:"label,omitempty"`
Rename *Rename `json:"rename,omitempty"` Rename *Rename `json:"rename,omitempty"`
LockReason *string `json:"lock_reason,omitempty"` LockReason *string `json:"lock_reason,omitempty"`
ProjectCard *ProjectCard `json:"project_card,omitempty"`
} }
// ListIssueEvents lists events for the specified issue. // ListIssueEvents lists events for the specified issue.
@ -92,7 +94,8 @@ func (s *IssuesService) ListIssueEvents(ctx context.Context, owner, repo string,
return nil, nil, err return nil, nil, err
} }
req.Header.Set("Accept", mediaTypeLockReasonPreview) acceptHeaders := []string{mediaTypeLockReasonPreview, mediaTypeProjectCardDetailsPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
var events []*IssueEvent var events []*IssueEvent
resp, err := s.client.Do(ctx, req, &events) resp, err := s.client.Do(ctx, req, &events)

View File

@ -8,6 +8,7 @@ package github
import ( import (
"context" "context"
"fmt" "fmt"
"strings"
"time" "time"
) )
@ -116,6 +117,7 @@ type Timeline struct {
// An object containing rename details including 'from' and 'to' attributes. // An object containing rename details including 'from' and 'to' attributes.
// Only provided for 'renamed' events. // Only provided for 'renamed' events.
Rename *Rename `json:"rename,omitempty"` Rename *Rename `json:"rename,omitempty"`
ProjectCard *ProjectCard `json:"project_card,omitempty"`
} }
// Source represents a reference's source. // Source represents a reference's source.
@ -141,7 +143,8 @@ func (s *IssuesService) ListIssueTimeline(ctx context.Context, owner, repo strin
} }
// TODO: remove custom Accept header when this API fully launches. // TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeTimelinePreview) acceptHeaders := []string{mediaTypeTimelinePreview, mediaTypeProjectCardDetailsPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
var events []*Timeline var events []*Timeline
resp, err := s.client.Do(ctx, req, &events) resp, err := s.client.Do(ctx, req, &events)

View File

@ -193,7 +193,7 @@ func (s *MigrationService) DeleteUserMigration(ctx context.Context, id int64) (*
return s.client.Do(ctx, req, nil) return s.client.Do(ctx, req, nil)
} }
// UnlockUserRepository will unlock a repo that was locked for migration. // UnlockUserRepo will unlock a repo that was locked for migration.
// id is migration ID. // id is migration ID.
// You should unlock each migrated repository and delete them when the migration // You should unlock each migrated repository and delete them when the migration
// is complete and you no longer need the source data. // is complete and you no longer need the source data.

View File

@ -296,6 +296,12 @@ type ProjectCard struct {
// The following fields are only populated by Webhook events. // The following fields are only populated by Webhook events.
ColumnID *int64 `json:"column_id,omitempty"` ColumnID *int64 `json:"column_id,omitempty"`
// The following fields are only populated by Events API.
ProjectID *int64 `json:"project_id,omitempty"`
ProjectURL *string `json:"project_url,omitempty"`
ColumnName *string `json:"column_name,omitempty"`
PreviousColumnName *string `json:"previous_column_name,omitempty"` // Populated in "moved_columns_in_project" event deliveries.
} }
// ProjectCardListOptions specifies the optional parameters to the // ProjectCardListOptions specifies the optional parameters to the
@ -366,7 +372,7 @@ type ProjectCardOptions struct {
// The ID (not Number) of the Issue to associate with this card. // The ID (not Number) of the Issue to associate with this card.
// Note and ContentID are mutually exclusive. // Note and ContentID are mutually exclusive.
ContentID int64 `json:"content_id,omitempty"` ContentID int64 `json:"content_id,omitempty"`
// The type of content to associate with this card. Possible values are: "Issue". // The type of content to associate with this card. Possible values are: "Issue" and "PullRequest".
ContentType string `json:"content_type,omitempty"` ContentType string `json:"content_type,omitempty"`
// Use true to archive a project card. // Use true to archive a project card.
// Specify false if you need to restore a previously archived project card. // Specify false if you need to restore a previously archived project card.
@ -460,3 +466,129 @@ func (s *ProjectsService) MoveProjectCard(ctx context.Context, cardID int64, opt
return s.client.Do(ctx, req, nil) return s.client.Do(ctx, req, nil)
} }
// ProjectCollaboratorOptions specifies the optional parameters to the
// ProjectsService.AddProjectCollaborator method.
type ProjectCollaboratorOptions struct {
// Permission specifies the permission to grant to the collaborator.
// Possible values are:
// "read" - can read, but not write to or administer this project.
// "write" - can read and write, but not administer this project.
// "admin" - can read, write and administer this project.
//
// Default value is "write"
Permission *string `json:"permission,omitempty"`
}
// AddProjectCollaborator adds a collaborator to an organization project and sets
// their permission level. You must be an organization owner or a project admin to add a collaborator.
//
// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#add-user-as-a-collaborator
func (s *ProjectsService) AddProjectCollaborator(ctx context.Context, id int64, username string, opt *ProjectCollaboratorOptions) (*Response, error) {
u := fmt.Sprintf("projects/%v/collaborators/%v", id, username)
req, err := s.client.NewRequest("PUT", u, opt)
if err != nil {
return nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeProjectsPreview)
return s.client.Do(ctx, req, nil)
}
// RemoveProjectCollaborator removes a collaborator from an organization project.
// You must be an organization owner or a project admin to remove a collaborator.
//
// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#remove-user-as-a-collaborator
func (s *ProjectsService) RemoveProjectCollaborator(ctx context.Context, id int64, username string) (*Response, error) {
u := fmt.Sprintf("projects/%v/collaborators/%v", id, username)
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", mediaTypeProjectsPreview)
return s.client.Do(ctx, req, nil)
}
// ListCollaboratorOptions specifies the optional parameters to the
// ProjectsService.ListProjectCollaborators method.
type ListCollaboratorOptions struct {
// Affiliation specifies how collaborators should be filtered by their affiliation.
// Possible values are:
// "outside" - All outside collaborators of an organization-owned repository
// "direct" - All collaborators with permissions to an organization-owned repository,
// regardless of organization membership status
// "all" - All collaborators the authenticated user can see
//
// Default value is "all".
Affiliation *string `url:"affiliation,omitempty"`
ListOptions
}
// ListProjectCollaborators lists the collaborators for an organization project. For a project,
// the list of collaborators includes outside collaborators, organization members that are direct
// collaborators, organization members with access through team memberships, organization members
// with access through default organization permissions, and organization owners. You must be an
// organization owner or a project admin to list collaborators.
//
// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#list-collaborators
func (s *ProjectsService) ListProjectCollaborators(ctx context.Context, id int64, opt *ListCollaboratorOptions) ([]*User, *Response, error) {
u := fmt.Sprintf("projects/%v/collaborators", id)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
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", mediaTypeProjectsPreview)
var users []*User
resp, err := s.client.Do(ctx, req, &users)
if err != nil {
return nil, resp, err
}
return users, resp, nil
}
// ProjectPermissionLevel represents the permission level an organization
// member has for a given project.
type ProjectPermissionLevel struct {
// Possible values: "admin", "write", "read", "none"
Permission *string `json:"permission,omitempty"`
User *User `json:"user,omitempty"`
}
// ReviewProjectCollaboratorPermission returns the collaborator's permission level for an organization
// project. Possible values for the permission key: "admin", "write", "read", "none".
// You must be an organization owner or a project admin to review a user's permission level.
//
// GitHub API docs: https://developer.github.com/v3/projects/collaborators/#review-a-users-permission-level
func (s *ProjectsService) ReviewProjectCollaboratorPermission(ctx context.Context, id int64, username string) (*ProjectPermissionLevel, *Response, error) {
u := fmt.Sprintf("projects/%v/collaborators/%v/permission", id, username)
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", mediaTypeProjectsPreview)
ppl := new(ProjectPermissionLevel)
resp, err := s.client.Do(ctx, req, ppl)
if err != nil {
return nil, resp, err
}
return ppl, resp, nil
}

View File

@ -107,7 +107,7 @@ type PullRequestBranch struct {
// PullRequestsService.List method. // PullRequestsService.List method.
type PullRequestListOptions struct { type PullRequestListOptions struct {
// State filters pull requests based on their state. Possible values are: // 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"` State string `url:"state,omitempty"`
// Head filters pull requests by head user and branch name in the format of: // Head filters pull requests by head user and branch name in the format of:
@ -303,9 +303,6 @@ func (s *PullRequestsService) ListCommits(ctx context.Context, owner string, rep
return nil, nil, err return nil, nil, err
} }
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeGitSigningPreview)
var commits []*RepositoryCommit var commits []*RepositoryCommit
resp, err := s.client.Do(ctx, req, &commits) resp, err := s.client.Do(ctx, req, &commits)
if err != nil { if err != nil {

View File

@ -329,7 +329,9 @@ func (s *ReactionsService) ListTeamDiscussionCommentReactions(ctx context.Contex
var m []*Reaction var m []*Reaction
resp, err := s.client.Do(ctx, req, &m) resp, err := s.client.Do(ctx, req, &m)
if err != nil {
return nil, nil, err
}
return m, resp, nil return m, resp, nil
} }

View File

@ -179,7 +179,7 @@ func (s *RepositoriesService) List(ctx context.Context, user string, opt *Reposi
} }
// TODO: remove custom Accept headers when APIs fully launch. // TODO: remove custom Accept headers when APIs fully launch.
acceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview} acceptHeaders := []string{mediaTypeTopicsPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
var repos []*Repository var repos []*Repository
@ -217,7 +217,7 @@ func (s *RepositoriesService) ListByOrg(ctx context.Context, org string, opt *Re
} }
// TODO: remove custom Accept headers when APIs fully launch. // TODO: remove custom Accept headers when APIs fully launch.
acceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview} acceptHeaders := []string{mediaTypeTopicsPreview}
req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
var repos []*Repository var repos []*Repository
@ -698,6 +698,13 @@ type DismissalRestrictionsRequest struct {
Teams *[]string `json:"teams,omitempty"` 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. // ListBranches lists branches for the specified repository.
// //
// GitHub API docs: https://developer.github.com/v3/repos/#list-branches // 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) 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. // 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 // GitHub API docs: https://developer.github.com/v3/repos/branches/#update-required-status-checks-of-protected-branch

View File

@ -120,9 +120,6 @@ func (s *RepositoriesService) AddCollaborator(ctx context.Context, owner, repo,
return nil, err return nil, err
} }
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeRepositoryInvitationsPreview)
return s.client.Do(ctx, req, nil) return s.client.Do(ctx, req, nil)
} }

View File

@ -58,6 +58,7 @@ type CommitFile struct {
BlobURL *string `json:"blob_url,omitempty"` BlobURL *string `json:"blob_url,omitempty"`
RawURL *string `json:"raw_url,omitempty"` RawURL *string `json:"raw_url,omitempty"`
ContentsURL *string `json:"contents_url,omitempty"` ContentsURL *string `json:"contents_url,omitempty"`
PreviousFilename *string `json:"previous_filename,omitempty"`
} }
func (c CommitFile) String() string { func (c CommitFile) String() string {
@ -127,9 +128,6 @@ func (s *RepositoriesService) ListCommits(ctx context.Context, owner, repo strin
return nil, nil, err return nil, nil, err
} }
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeGitSigningPreview)
var commits []*RepositoryCommit var commits []*RepositoryCommit
resp, err := s.client.Do(ctx, req, &commits) resp, err := s.client.Do(ctx, req, &commits)
if err != nil { if err != nil {
@ -151,9 +149,6 @@ func (s *RepositoriesService) GetCommit(ctx context.Context, owner, repo, sha st
return nil, nil, err return nil, nil, err
} }
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeGitSigningPreview)
commit := new(RepositoryCommit) commit := new(RepositoryCommit)
resp, err := s.client.Do(ctx, req, commit) resp, err := s.client.Do(ctx, req, commit)
if err != nil { if err != nil {

Some files were not shown because too many files have changed in this diff Show More