Skip to content

Commit aab8b3c

Browse files
authored
feat: Integrate termlink (#253)
* fix: Goreleaser scripts * fix: Golangci config * chore: Bump go-tools image version to v0.5.0 * feat: Add termlink support
1 parent 902c556 commit aab8b3c

File tree

263 files changed

+24415
-2877
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

263 files changed

+24415
-2877
lines changed

.golangci.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ linters:
5555
disable-all: true
5656
enable:
5757
- bodyclose
58-
- deadcode
5958
- depguard
6059
- dogsled
6160
- dupl
@@ -82,13 +81,11 @@ linters:
8281
- nolintlint
8382
- rowserrcheck
8483
- staticcheck
85-
- structcheck
8684
- stylecheck
8785
- typecheck
8886
- unconvert
8987
- unparam
9088
- unused
91-
- varcheck
9289
- whitespace
9390
- revive
9491
- wsl

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ VERSION ?= $(shell git describe --tags $(git rev-list --tags --max-count=1))
44
APP_NAME?=aoc-cli
55
SHELL := env APP_NAME=$(APP_NAME) $(SHELL)
66

7-
GOTOOLS_IMAGE_TAG?=v0.4.3
7+
GOTOOLS_IMAGE_TAG?=v0.5.0
88
SHELL := env GOTOOLS_IMAGE_TAG=$(GOTOOLS_IMAGE_TAG) $(SHELL)
99

1010
COMPOSE_TOOLS_FILE=deployments/docker-compose/go-tools-docker-compose.yml

cmd/aoc-cli/handlers.go

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/manifoldco/promptui"
1414
promptlist "github.com/manifoldco/promptui/list"
1515
log "github.com/obalunenko/logger"
16+
"github.com/savioxavier/termlink"
1617
"github.com/urfave/cli/v2"
1718

1819
"github.com/obalunenko/advent-of-code/internal/command"
@@ -146,7 +147,7 @@ func searcher(items []string) promptlist.Searcher {
146147

147148
func handleYearChoices(ctx context.Context, opt promptui.Select) error {
148149
for {
149-
_, choice, err := opt.Run()
150+
_, yearOpt, err := opt.Run()
150151
if err != nil {
151152
if isAbort(err) {
152153
return nil
@@ -155,11 +156,11 @@ func handleYearChoices(ctx context.Context, opt promptui.Select) error {
155156
return fmt.Errorf("prompt failed: %w", err)
156157
}
157158

158-
if isExit(choice) {
159+
if isExit(yearOpt) {
159160
return nil
160161
}
161162

162-
err = menuPuzzle(ctx, choice)
163+
err = menuPuzzle(ctx, yearOpt)
163164
if err != nil {
164165
if errors.Is(err, errExit) {
165166
return nil
@@ -174,7 +175,7 @@ func handleYearChoices(ctx context.Context, opt promptui.Select) error {
174175

175176
func handlePuzzleChoices(ctx context.Context, year string, opt promptui.Select) error {
176177
for {
177-
_, choice, err := opt.Run()
178+
_, dayOpt, err := opt.Run()
178179
if err != nil {
179180
if isAbort(err) {
180181
return errExit
@@ -183,31 +184,47 @@ func handlePuzzleChoices(ctx context.Context, year string, opt promptui.Select)
183184
return fmt.Errorf("prompt failed: %w", err)
184185
}
185186

186-
if isExit(choice) {
187+
if isExit(dayOpt) {
187188
return errExit
188189
}
189190

190-
if isBack(choice) {
191+
if isBack(dayOpt) {
191192
return nil
192193
}
193194

194195
stopSpinner := setSpinner()
195196

196-
res, err := command.Run(ctx, year, choice)
197+
res, err := command.Run(ctx, year, dayOpt)
197198
if err != nil {
198-
log.WithError(ctx, err).Error("Puzzle run failed")
199-
200199
stopSpinner()
201200

201+
if errors.Is(err, command.ErrUnauthorized) {
202+
fmt.Println(termlink.Link("Authorize here", "https://adventofcode.com/auth/login"))
203+
204+
log.WithError(ctx, err).Fatal("Session expired")
205+
}
206+
207+
log.WithError(ctx, err).Error("Puzzle run failed")
208+
202209
continue
203210
}
204211

205-
stopSpinner()
212+
stopSpinner("Solved!")
213+
214+
url := getURL(year, dayOpt)
206215

207216
fmt.Println(res.String())
217+
218+
fmt.Println(termlink.Link("Enter puzzle answers here", url))
208219
}
209220
}
210221

222+
func getURL(year, day string) string {
223+
const urlFmt = "https://adventofcode.com/%s/day/%s"
224+
225+
return fmt.Sprintf(urlFmt, year, day)
226+
}
227+
211228
func isExit(in string) bool {
212229
return strings.EqualFold(exit, in)
213230
}
@@ -253,13 +270,13 @@ func sessionFromCli(c *cli.Context) string {
253270
}
254271

255272
// setSpinner runs the displaying of spinner to handle long time operations. Returns stop func.
256-
func setSpinner() func() {
273+
func setSpinner() func(msg ...string) {
257274
const delayMs = 100
258275

259276
s := spinner.New(
260277
spinner.CharSets[62],
261278
delayMs*time.Millisecond,
262-
spinner.WithFinalMSG("Solved!"),
279+
spinner.WithFinalMSG(""),
263280
spinner.WithHiddenCursor(true),
264281
spinner.WithColor("yellow"),
265282
spinner.WithWriter(os.Stderr),
@@ -269,7 +286,11 @@ func setSpinner() func() {
269286

270287
s.Start()
271288

272-
return func() {
289+
return func(msg ...string) {
290+
if len(msg) != 0 {
291+
s.FinalMSG = msg[0]
292+
}
293+
273294
s.Stop()
274295
}
275296
}

cmd/aoc-cli/handlers_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"testing"
55

66
"github.com/stretchr/testify/assert"
7+
8+
"github.com/obalunenko/advent-of-code/internal/puzzles"
79
)
810

911
func Test_makeMenuItemsList(t *testing.T) {
@@ -59,3 +61,34 @@ func Test_searcher(t *testing.T) {
5961

6062
assert.False(t, s("1", 2))
6163
}
64+
65+
func Test_getUrl(t *testing.T) {
66+
type args struct {
67+
year string
68+
day string
69+
}
70+
71+
tests := []struct {
72+
name string
73+
args args
74+
want string
75+
}{
76+
{
77+
name: "",
78+
args: args{
79+
year: puzzles.Year2022.String(),
80+
day: puzzles.Day01.String(),
81+
},
82+
want: "https://adventofcode.com/2022/day/1",
83+
},
84+
}
85+
86+
for _, tt := range tests {
87+
t.Run(tt.name, func(t *testing.T) {
88+
got := getURL(tt.args.year, tt.args.day)
89+
90+
assert.Equalf(t, tt.want, got,
91+
"getURL(%v, %v)", tt.args.year, tt.args.day)
92+
})
93+
}
94+
}

go.mod

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ require (
88
github.com/obalunenko/getenv v1.4.2
99
github.com/obalunenko/logger v0.6.0
1010
github.com/obalunenko/version v1.1.0
11+
github.com/savioxavier/termlink v1.2.1
1112
github.com/stretchr/testify v1.8.2
1213
github.com/urfave/cli/v2 v2.25.0
1314
)
@@ -18,16 +19,17 @@ require (
1819
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
1920
github.com/davecgh/go-spew v1.1.1 // indirect
2021
github.com/evalphobia/logrus_sentry v0.8.2 // indirect
21-
github.com/fatih/color v1.7.0 // indirect
22+
github.com/fatih/color v1.13.0 // indirect
2223
github.com/getsentry/raven-go v0.2.0 // indirect
23-
github.com/mattn/go-colorable v0.1.2 // indirect
24-
github.com/mattn/go-isatty v0.0.8 // indirect
24+
github.com/jwalton/go-supportscolor v1.1.0 // indirect
25+
github.com/mattn/go-colorable v0.1.9 // indirect
26+
github.com/mattn/go-isatty v0.0.14 // indirect
2527
github.com/pkg/errors v0.9.1 // indirect
2628
github.com/pmezard/go-difflib v1.0.0 // indirect
2729
github.com/russross/blackfriday/v2 v2.1.0 // indirect
2830
github.com/sirupsen/logrus v1.9.0 // indirect
2931
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
30-
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
31-
golang.org/x/term v0.1.0 // indirect
32+
golang.org/x/sys v0.6.0 // indirect
33+
golang.org/x/term v0.6.0 // indirect
3234
gopkg.in/yaml.v3 v3.0.1 // indirect
3335
)

go.sum

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,19 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
1515
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
1616
github.com/evalphobia/logrus_sentry v0.8.2 h1:dotxHq+YLZsT1Bb45bB5UQbfCh3gM/nFFetyN46VoDQ=
1717
github.com/evalphobia/logrus_sentry v0.8.2/go.mod h1:pKcp+vriitUqu9KiWj/VRFbRfFNUwz95/UkgG8a6MNc=
18-
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
19-
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
18+
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
19+
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
2020
github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs=
2121
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
22+
github.com/jwalton/go-supportscolor v1.1.0 h1:HsXFJdMPjRUAx8cIW6g30hVSFYaxh9yRQwEWgkAR7lQ=
23+
github.com/jwalton/go-supportscolor v1.1.0/go.mod h1:hFVUAZV2cWg+WFFC4v8pT2X/S2qUUBYMioBD9AINXGs=
2224
github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA=
2325
github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg=
24-
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
25-
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
26-
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
27-
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
26+
github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U=
27+
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
28+
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
29+
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
30+
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
2831
github.com/obalunenko/getenv v1.4.2 h1:m/Cer+5/Di+kbpNhtmZMcYXOquqqCjlgtvSc4X89e/M=
2932
github.com/obalunenko/getenv v1.4.2/go.mod h1:trfsd8x+Ulqtw8DHKTmL1DdM9wgUd8IvOUgo22GLn3U=
3033
github.com/obalunenko/logger v0.6.0 h1:Sif4MYn6aGUA5pBTcKkMtJXTZNRZ52EiP4KLiFgMEkI=
@@ -37,6 +40,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
3740
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
3841
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
3942
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
43+
github.com/savioxavier/termlink v1.2.1 h1:O9ZQvk9BPQQK4JQeMB56ZfV8uam0Ts+f97mJme7+dq8=
44+
github.com/savioxavier/termlink v1.2.1/go.mod h1:WA7FTALNwN41NGnmQMIrnjAYTsEhIAZ4RuzgEiB0Jp8=
4045
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
4146
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
4247
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -52,11 +57,17 @@ github.com/urfave/cli/v2 v2.25.0/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6f
5257
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
5358
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
5459
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
55-
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
56-
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
60+
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
61+
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
62+
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
63+
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
64+
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
5765
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
58-
golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw=
59-
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
66+
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
67+
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
68+
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
69+
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
70+
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
6071
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
6172
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
6273
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

internal/command/command.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package command
44
import (
55
"bytes"
66
"context"
7+
"errors"
78
"fmt"
89
"net/http"
910
"time"
@@ -12,13 +13,27 @@ import (
1213
"github.com/obalunenko/advent-of-code/internal/puzzles/input"
1314
)
1415

16+
var (
17+
// ErrUnauthorized returns when session is empty or invalid.
18+
ErrUnauthorized = errors.New("unauthorized")
19+
)
20+
1521
// Run runs puzzle solving for passed year/day date.
1622
func Run(ctx context.Context, year, day string) (puzzles.Result, error) {
1723
const timeout = time.Second * 30
1824

1925
cli := input.NewFetcher(http.DefaultClient, timeout)
2026

21-
return run(ctx, cli, year, day)
27+
result, err := run(ctx, cli, year, day)
28+
if err != nil {
29+
if errors.Is(err, input.ErrUnauthorized) {
30+
return puzzles.Result{}, ErrUnauthorized
31+
}
32+
33+
return puzzles.Result{}, err
34+
}
35+
36+
return result, nil
2237
}
2338

2439
func run(ctx context.Context, cli input.Fetcher, year, day string) (puzzles.Result, error) {

scripts/release/check.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,4 @@ export GO_BUILD_LDFLAGS="-s -w \
4545

4646
goreleaser check
4747

48-
goreleaser build --rm-dist --single-target --snapshot
48+
goreleaser build --clean --single-target --snapshot

scripts/release/local-snapshot-release.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,4 @@ export GO_BUILD_LDFLAGS="-s -w \
4242
-X ${BUILDINFO_VARS_PKG}.appname=${APP} \
4343
-X ${BUILDINFO_VARS_PKG}.goversion=${GOVERSION}"
4444

45-
goreleaser --snapshot --skip-publish --rm-dist
45+
goreleaser --snapshot --skip-publish --clean

scripts/release/release.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@ export GO_BUILD_LDFLAGS="-s -w \
4040
-X ${BUILDINFO_VARS_PKG}.appname=${APP} \
4141
-X ${BUILDINFO_VARS_PKG}.goversion=${GOVERSION}"
4242

43-
goreleaser release --rm-dist
43+
goreleaser release --clean

0 commit comments

Comments
 (0)