diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..be6c1b0 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,23 @@ +name: test + +on: + push: {} + pull_request: { branches: [master] } + +jobs: + test: + runs-on: ubuntu-latest + steps: + - id: goversion + run: | + echo ::set-output name=version::$(curl -s https://raw.githubusercontent.com/actions/go-versions/main/versions-manifest.json | sed -rn 's/.*"version": "([0-9]\.[0-9]+(\.[0-9]+)?)".*/\1/p' | head -1) + - uses: actions/setup-go@v2 + with: { go-version: "${{ steps.goversion.outputs.version }}" } + - uses: actions/checkout@v2 + - run: | + go install golang.org/x/lint/golint@latest + - run: $(go env GOPATH)/bin/golint -min_confidence 0.9 -set_exit_status + - run: | + GORACE="exitcode=1 halt_on_error=1" go test -v -coverprofile=coverage.txt -race -timeout 3m -count 3 -cpu 1,4 + bash <(curl -s https://codecov.io/bash) + - run: go vet -v . diff --git a/README.md b/README.md index 9355433..69bcfa7 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,10 @@ [Click here to see the changes in girc-atomic vs girc](https://github.com/lrstanley/girc/compare/master...yunginnanet:master) ## Status - -### ₜₕₑ ₛₖy ᵢₛ 𝆑ₐₗₗᵢₙg ʇɥǝ sʞʎ ᴉs ⅎɐʅʅᴉuƃ + +### ₜₕₑ ₛₖy ᵢₛ 𝆑ₐₗₗᵢₙg ʇɥǝ sʞʎ ᴉs ⅎɐʅʅᴉuƃ ### 𝚝𝚑𝚎𝚢 𝚜𝚑𝚘𝚞𝚕𝚍 𝚑𝚊𝚟𝚎 𝚕𝚒𝚜𝚝𝚎𝚗𝚎𝚍 -### ʇɥǝ sʞʎ ᴉs ⅎɐʅʅᴉuƃ ₜₕₑ ₛₖy ᵢₛ 𝆑ₐₗₗᵢₙg +### ʇɥǝ sʞʎ ᴉs ⅎɐʅʅᴉuƃ ₜₕₑ ₛₖy ᵢₛ 𝆑ₐₗₗᵢₙg ## Features @@ -24,23 +24,23 @@ - Event based triggering/responses ([example](https://godoc.org/github.com/yunginnanet/girc-atomic#ex-package--Commands), and [CTCP too](https://godoc.org/github.com/yunginnanet/girc-atomic#Commands.SendCTCP)!) - [Documentation](https://godoc.org/github.com/yunginnanet/girc-atomic) is _mostly_ complete. - Support for almost all of the [IRCv3 spec](http://ircv3.net/software/libraries.html). - - SASL Auth (currently only `PLAIN` and `EXTERNAL` is support by default, +- SASL Auth (currently only `PLAIN` and `EXTERNAL` is support by default, however you can simply implement `SASLMech` yourself to support additional mechanisms.) - - Message tags (things like `account-tag` on by default) - - `account-notify`, `away-notify`, `chghost`, `extended-join`, etc -- all handled seemlessly ([cap.go](https://github.com/yunginnanet/girc-atomic/blob/master/cap.go) for more info). +- Message tags (things like `account-tag` on by default) +- `account-notify`, `away-notify`, `chghost`, `extended-join`, etc -- all handled seemlessly ([cap.go](https://github.com/yunginnanet/girc-atomic/blob/master/cap.go) for more info). - Channel and user tracking. Easily find what users are in a channel, if a user is away, or if they are authenticated (if the server supports it!) - Client state/capability tracking. Easy methods to access capability data ([LookupChannel](https://godoc.org/github.com/yunginnanet/girc-atomic#Client.LookupChannel), [LookupUser](https://godoc.org/github.com/yunginnanet/girc-atomic#Client.LookupUser), [GetServerOpt (ISUPPORT)](https://godoc.org/github.com/yunginnanet/girc-atomic#Client.GetServerOpt), etc.) - Built-in support for things you would commonly have to implement yourself. - - Nick collision detection and prevention (also see [Config.HandleNickCollide](https://godoc.org/github.com/yunginnanet/girc-atomic#Config).) - - Event/message rate limiting. - - Channel, nick, and user validation methods ([IsValidChannel](https://godoc.org/github.com/yunginnanet/girc-atomic#IsValidChannel), [IsValidNick](https://godoc.org/github.com/yunginnanet/girc-atomic#IsValidNick), etc.) - - CTCP handling and auto-responses ([CTCP](https://godoc.org/github.com/yunginnanet/girc-atomic#CTCP)) - - Utilizes the atomic/value package from stdlib to reduce backpressure in multi-client usage. - - Additional CTCP handlers and customization. - - ?????? - - PROFIT!!!1! +- Nick collision detection and prevention (also see [Config.HandleNickCollide](https://godoc.org/github.com/yunginnanet/girc-atomic#Config).) +- Event/message rate limiting. +- Channel, nick, and user validation methods ([IsValidChannel](https://godoc.org/github.com/yunginnanet/girc-atomic#IsValidChannel), [IsValidNick](https://godoc.org/github.com/yunginnanet/girc-atomic#IsValidNick), etc.) +- CTCP handling and auto-responses ([CTCP](https://godoc.org/github.com/yunginnanet/girc-atomic#CTCP)) +- Utilizes the atomic/value package from stdlib to reduce backpressure in multi-client usage. +- Additional CTCP handlers and customization. +- ?????? +- PROFIT!!!1! ## Examples @@ -59,8 +59,8 @@ Working on a project and want to add it to the list? Submit a pull request! ## Contributing ~~Please review the [CONTRIBUTING](CONTRIBUTING.md) doc for submitting issues/a guide -on submitting pull requests and helping out.~~ - +on submitting pull requests and helping out.~~ + **OH GOD PLEASE MAKE IT STOP** diff --git a/builtin.go b/builtin.go index a0e509f..90cca0f 100644 --- a/builtin.go +++ b/builtin.go @@ -576,6 +576,7 @@ func handleNAMES(c *Client, e Event) { var modes, nick string var ok bool + var s *Source for i := 0; i < len(parts); i++ { modes, nick, ok = parseUserPrefix(parts[i]) diff --git a/cap_sasl.go b/cap_sasl.go index 9aecccf..d880316 100644 --- a/cap_sasl.go +++ b/cap_sasl.go @@ -120,7 +120,6 @@ func handleSASL(c *Client, e Event) { break } } - return } func handleSASLError(c *Client, e Event) { diff --git a/conn.go b/conn.go index f0e551c..0e2a8d2 100644 --- a/conn.go +++ b/conn.go @@ -43,7 +43,6 @@ type ircConn struct { // lastPong is the last successful time that we pinged the server and // received a successful pong back. lastPong atomic.Value - // pingDelay time.Duration } // Dialer is an interface implementation of net.Dialer. Use this if you would @@ -275,7 +274,6 @@ func (c *Client) MockConnect(conn net.Conn) error { func (c *Client) internalConnect(mock net.Conn, dialer Dialer) error { startConn: - if c.conn != nil { panic("use of connect more than once") } @@ -614,13 +612,18 @@ func (c *Client) pingLoop(ctx context.Context, errs chan error, working *int32) if time.Since(c.conn.lastPong.Load().(time.Time)) > c.Config.PingDelay+(120*time.Second) { // It's 60 seconds over what out ping delay is, connection // has probably dropped. - errs <- ErrTimedOut{ + + err := ErrTimedOut{ TimeSinceSuccess: time.Since(c.conn.lastPong.Load().(time.Time)), LastPong: c.conn.lastPong.Load().(time.Time), LastPing: c.conn.lastPing.Load().(time.Time), Delay: c.Config.PingDelay, } + go func() { + errs <- err + }() + wg.Done() return } diff --git a/conn_test.go b/conn_test.go index e6a8a48..b31abc3 100644 --- a/conn_test.go +++ b/conn_test.go @@ -48,8 +48,6 @@ func TestDecode(t *testing.T) { if err == nil { t.Fatalf("should have failed to parse decoded event. got: %#v", event) } - - return } func TestEncode(t *testing.T) { @@ -72,8 +70,6 @@ func TestEncode(t *testing.T) { if want != line { t.Fatalf("encoded line wanted: %q, got: %q", want, line) } - - return } func TestRate(t *testing.T) { @@ -90,8 +86,6 @@ func TestRate(t *testing.T) { if delay := c.rate(200); delay > (3 * time.Second) { t.Fatal("rate delay too high") } - - return } func genMockConn() (client *Client, clientConn net.Conn, serverConn net.Conn) { diff --git a/constants.go b/constants.go index f17e6c2..4442ab1 100644 --- a/constants.go +++ b/constants.go @@ -348,6 +348,7 @@ const ( RPL_LOCALUSERS = "265" // aircd/hybrid/bahamut, used on freenode. RPL_TOPICWHOTIME = "333" // ircu, used on freenode. RPL_WHOSPCRPL = "354" // ircu, used on networks with WHOX support. + RPL_CREATIONTIME = "329" ) // As seen in the wild. diff --git a/format_test.go b/format_test.go index 764e6a3..3c3ef00 100644 --- a/format_test.go +++ b/format_test.go @@ -13,32 +13,24 @@ func BenchmarkFormat(b *testing.B) { for i := 0; i < b.N; i++ { Fmt("{red}test{c}") } - - return } func BenchmarkFormatLong(b *testing.B) { for i := 0; i < b.N; i++ { Fmt("{red}test {blue}2 {red}3 {brown} {italic}test{c}") } - - return } func BenchmarkStripFormat(b *testing.B) { for i := 0; i < b.N; i++ { TrimFmt("{red}test{c}") } - - return } func BenchmarkStripFormatLong(b *testing.B) { for i := 0; i < b.N; i++ { TrimFmt("{red}test {blue}2 {red}3 {brown} {italic}test{c}") } - - return } func BenchmarkStripRaw(b *testing.B) { @@ -46,8 +38,6 @@ func BenchmarkStripRaw(b *testing.B) { for i := 0; i < b.N; i++ { StripRaw(text) } - - return } func BenchmarkStripRawLong(b *testing.B) { @@ -55,8 +45,6 @@ func BenchmarkStripRawLong(b *testing.B) { for i := 0; i < b.N; i++ { StripRaw(text) } - - return } func TestFormat(t *testing.T) { @@ -249,8 +237,6 @@ func TestToRFC1459(t *testing.T) { t.Errorf("ToRFC1459() = %q, want %q", got, tt.want) } } - - return } //func BenchmarkGlob(b *testing.B) { @@ -267,23 +253,17 @@ func testGlobMatch(t *testing.T, subj, pattern string) { if !Glob(subj, pattern) { t.Fatalf("'%s' should match '%s'", pattern, subj) } - - return } func testGlobNoMatch(t *testing.T, subj, pattern string) { if Glob(subj, pattern) { t.Fatalf("'%s' should not match '%s'", pattern, subj) } - - return } func TestEmptyPattern(t *testing.T) { testGlobMatch(t, "", "") testGlobNoMatch(t, "test", "") - - return } func TestEmptySubject(t *testing.T) { @@ -324,14 +304,10 @@ func TestEmptySubject(t *testing.T) { for _, pattern := range cases { testGlobNoMatch(t, pattern, "") } - - return } func TestPatternWithoutGlobs(t *testing.T) { testGlobMatch(t, "test", "test") - - return } func TestGlob(t *testing.T) { @@ -368,6 +344,4 @@ func TestGlob(t *testing.T) { for _, pattern := range cases { testGlobNoMatch(t, "this is a test", pattern) } - - return }