Compare commits
No commits in common. "83f0d3337494fe3cfa98ea2eb0a71ed6de129a6a" and "dc939b6ed11cffc57cacda1e41569bcfd3b543e4" have entirely different histories.
83f0d33374
...
dc939b6ed1
269 changed files with 1624 additions and 5275 deletions
190
.deadlines.yml
Normal file
190
.deadlines.yml
Normal file
|
@ -0,0 +1,190 @@
|
|||
- group: Bonus
|
||||
start: 11-02-2023 18:00
|
||||
deadline: 29-05-2023 23:59
|
||||
tasks:
|
||||
- task: consistenthash
|
||||
score: 200
|
||||
- task: gossip
|
||||
score: 300
|
||||
- task: smartsched
|
||||
score: 200
|
||||
watch:
|
||||
- distbuild/pkg/scheduler
|
||||
- task: wasm
|
||||
score: 300
|
||||
|
||||
- group: Analysis
|
||||
start: 29-04-2023 18:00
|
||||
deadline: 10-05-2023 23:59
|
||||
tasks:
|
||||
- task: testifycheck
|
||||
score: 200
|
||||
- task: gzep
|
||||
score: 100
|
||||
|
||||
- group: "[HW] Dist Build"
|
||||
start: 26-04-2023 12:00
|
||||
deadline: 29-05-2023 23:59
|
||||
tasks:
|
||||
- task: distbuild
|
||||
score: 0
|
||||
|
||||
- group: Low level
|
||||
start: 22-04-2023 16:00
|
||||
deadline: 03-05-2023 23:59
|
||||
tasks:
|
||||
- task: illegal
|
||||
score: 100
|
||||
- task: blowfish
|
||||
score: 100
|
||||
|
||||
- group: Reflect
|
||||
start: 15-04-2023 16:00
|
||||
deadline: 25-04-2023 23:59
|
||||
tasks:
|
||||
- task: reversemap
|
||||
score: 100
|
||||
- task: jsonlist
|
||||
score: 100
|
||||
- task: jsonrpc
|
||||
score: 100
|
||||
- task: structtags
|
||||
score: 100
|
||||
|
||||
- group: SQL
|
||||
start: 08-04-2023 16:00
|
||||
deadline: 18-04-2023 23:59
|
||||
tasks:
|
||||
- task: dao
|
||||
score: 100
|
||||
- task: ledger
|
||||
score: 200
|
||||
- task: shopfront
|
||||
score: 100
|
||||
- task: wscat
|
||||
score: 200
|
||||
|
||||
- group: Generics
|
||||
start: 01-04-2023 16:00
|
||||
deadline: 11-04-2023 23:59
|
||||
tasks:
|
||||
- task: genericsum
|
||||
score: 100
|
||||
- task: treeiter
|
||||
score: 100
|
||||
- task: coverme
|
||||
score: 300
|
||||
|
||||
- group: HTTP
|
||||
start: 25-03-2023 16:00
|
||||
deadline: 06-04-2023 23:59
|
||||
tasks:
|
||||
- task: urlshortener
|
||||
score: 100
|
||||
- task: digitalclock
|
||||
score: 100
|
||||
- task: middleware
|
||||
score: 200
|
||||
- task: olympics
|
||||
score: 200
|
||||
- task: firewall
|
||||
score: 200
|
||||
|
||||
- group: Concurrency with shared memory
|
||||
start: 18-03-2023 15:59
|
||||
deadline: 29-03-2023 23:59
|
||||
tasks:
|
||||
- task: dupcall
|
||||
score: 200
|
||||
- task: keylock
|
||||
score: 200
|
||||
- task: batcher
|
||||
score: 200
|
||||
- task: pubsub
|
||||
score: 300
|
||||
|
||||
- group: Testing
|
||||
start: 11-03-2023 13:00
|
||||
deadline: 21-03-2023 23:59
|
||||
tasks:
|
||||
- task: testequal
|
||||
score: 100
|
||||
- task: fileleak
|
||||
score: 100
|
||||
- task: tabletest
|
||||
score: 100
|
||||
- task: tparallel
|
||||
score: 200
|
||||
- task: iprange
|
||||
score: 100
|
||||
|
||||
- group: "[HW] Gitfame"
|
||||
start: 04-03-2023 16:30
|
||||
deadline: 19-03-2023 23:59
|
||||
tasks:
|
||||
- task: gitfame
|
||||
score: 0
|
||||
|
||||
- group: Goroutines
|
||||
start: 04-03-2023 16:30
|
||||
deadline: 14-03-2023 23:59
|
||||
tasks:
|
||||
- task: tour1
|
||||
score: 100
|
||||
- task: once
|
||||
score: 100
|
||||
- task: rwmutex
|
||||
score: 100
|
||||
- task: waitgroup
|
||||
score: 100
|
||||
- task: cond
|
||||
score: 100
|
||||
- task: ratelimit
|
||||
score: 100
|
||||
|
||||
- group: Interfaces
|
||||
start: 25-02-2023 16:30
|
||||
deadline: 07-03-2023 23:59
|
||||
tasks:
|
||||
- task: otp
|
||||
score: 100
|
||||
- task: lrucache
|
||||
score: 100
|
||||
- task: externalsort
|
||||
score: 100
|
||||
- task: retryupdate
|
||||
score: 100
|
||||
- task: ciletters
|
||||
score: 100
|
||||
|
||||
- group: Basics
|
||||
start: 18-02-2023 16:00
|
||||
deadline: 28-02-2023 23:59
|
||||
tasks:
|
||||
- task: hotelbusiness
|
||||
score: 100
|
||||
- task: hogwarts
|
||||
score: 100
|
||||
- task: utf8
|
||||
score: 100
|
||||
- task: varfmt
|
||||
score: 100
|
||||
- task: speller
|
||||
score: 100
|
||||
- task: forth
|
||||
score: 100
|
||||
|
||||
- group: Hello World
|
||||
start: 11-02-2023 18:00
|
||||
deadline: 21-02-2023 23:59
|
||||
tasks:
|
||||
- task: sum
|
||||
score: 100
|
||||
- task: tour0
|
||||
score: 100
|
||||
- task: wordcount
|
||||
score: 100
|
||||
- task: urlfetch
|
||||
score: 100
|
||||
- task: fetchall
|
||||
score: 100
|
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -2,8 +2,4 @@
|
|||
*.swp
|
||||
.vscode/
|
||||
|
||||
/example/
|
||||
|
||||
# Go profiling files
|
||||
*.out
|
||||
*.test
|
||||
/example/
|
|
@ -1,7 +1,11 @@
|
|||
grade:
|
||||
tags:
|
||||
- experimental
|
||||
image: gitlab.manytask.org:5050/go/public-2024-spring
|
||||
image: cr.yandex/crp9onavos88ug32d5r2/grader/go
|
||||
variables:
|
||||
DOCKER_HOST: tcp://docker:2375/
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
APP_HOST: docker
|
||||
# services:
|
||||
#- docker:dind
|
||||
script:
|
||||
- testtool grade
|
||||
timeout: 10 minutes
|
||||
|
|
263
.manytask.yml
263
.manytask.yml
|
@ -1,263 +0,0 @@
|
|||
version: 1
|
||||
|
||||
|
||||
settings: # required
|
||||
course_name: go
|
||||
|
||||
gitlab_base_url: https://gitlab.manytask.org
|
||||
public_repo: go/public-2024-spring
|
||||
students_group: go/students-2024-spring
|
||||
|
||||
|
||||
ui:
|
||||
task_url_template: https://github.com/slon/shad-go/tree/main/$TASK_NAME
|
||||
|
||||
# optional, any number of links
|
||||
links:
|
||||
"TG Channel": https://t.me/+eb5z6ZS-sI8xZDNi
|
||||
"TG Chat": https://t.me/+Tk8VTMAk5Tlp7Txm
|
||||
"LMS": https://lk.yandexdataschool.ru/
|
||||
"Contribute Manytask": https://github.com/manytask
|
||||
|
||||
|
||||
deadlines:
|
||||
timezone: Europe/Moscow
|
||||
|
||||
deadlines: hard # hard/interpolate
|
||||
# max_submissions: 10 # optional
|
||||
# submission_penalty: 0.1 # optional
|
||||
|
||||
schedule:
|
||||
- group: Hello World
|
||||
start: 2024-01-01 18:00
|
||||
steps:
|
||||
0.3: 2024-02-27 23:59
|
||||
end: 2024-07-10 23:59
|
||||
tasks:
|
||||
- task: sum
|
||||
score: 100
|
||||
- task: tour0
|
||||
score: 100
|
||||
- task: wordcount
|
||||
score: 100
|
||||
- task: urlfetch
|
||||
score: 100
|
||||
- task: fetchall
|
||||
score: 100
|
||||
|
||||
- group: Basics
|
||||
start: 2024-02-24 13:00
|
||||
steps:
|
||||
0.3: 2024-03-06 06:00
|
||||
end: 2024-07-10 23:59
|
||||
tasks:
|
||||
- task: hotelbusiness
|
||||
score: 100
|
||||
- task: hogwarts
|
||||
score: 100
|
||||
- task: utf8
|
||||
score: 100
|
||||
- task: varfmt
|
||||
score: 100
|
||||
- task: speller
|
||||
score: 100
|
||||
- task: forth
|
||||
score: 100
|
||||
|
||||
- group: Interfaces
|
||||
start: 2024-03-02 13:00
|
||||
steps:
|
||||
0.3: 2024-03-12 23:59
|
||||
end: 2024-07-10 23:59
|
||||
tasks:
|
||||
- task: otp
|
||||
score: 100
|
||||
- task: retryupdate
|
||||
score: 100
|
||||
- task: lrucache
|
||||
score: 100
|
||||
- task: externalsort
|
||||
score: 100
|
||||
- task: ciletters
|
||||
score: 100
|
||||
|
||||
- group: Goroutines
|
||||
start: 2024-03-03 13:00
|
||||
steps:
|
||||
0.3: 2024-03-19 23:59
|
||||
end: 2024-07-10 23:59
|
||||
tasks:
|
||||
- task: tour1
|
||||
score: 100
|
||||
- task: once
|
||||
score: 100
|
||||
- task: rwmutex
|
||||
score: 100
|
||||
- task: waitgroup
|
||||
score: 100
|
||||
- task: cond
|
||||
score: 100
|
||||
- task: ratelimit
|
||||
score: 100
|
||||
|
||||
- group: "[HW] Gitfame"
|
||||
start: 2024-03-09 13:00
|
||||
end: 2024-03-24 23:59
|
||||
tasks:
|
||||
- task: gitfame
|
||||
score: 0
|
||||
|
||||
- group: Testing
|
||||
start: 2024-03-16 13:00
|
||||
steps:
|
||||
0.3: 2024-03-27 23:59
|
||||
end: 2024-07-10 23:59
|
||||
tasks:
|
||||
- task: testequal
|
||||
score: 100
|
||||
- task: fileleak
|
||||
score: 100
|
||||
- task: tabletest
|
||||
score: 100
|
||||
- task: tparallel
|
||||
score: 200
|
||||
- task: iprange
|
||||
score: 100
|
||||
|
||||
- group: Concurrency with shared memory
|
||||
start: 2024-03-30 13:00
|
||||
steps:
|
||||
0.3: 2024-04-10 23:59
|
||||
end: 2024-07-10 23:59
|
||||
tasks:
|
||||
- task: dupcall
|
||||
score: 200
|
||||
- task: keylock
|
||||
score: 200
|
||||
- task: batcher
|
||||
score: 200
|
||||
- task: pubsub
|
||||
score: 300
|
||||
|
||||
- group: HTTP
|
||||
start: 2024-04-06 13:00
|
||||
steps:
|
||||
0.3: 2024-04-16 23:59
|
||||
end: 2024-07-10 23:59
|
||||
tasks:
|
||||
- task: urlshortener
|
||||
score: 100
|
||||
- task: digitalclock
|
||||
score: 100
|
||||
- task: middleware
|
||||
score: 200
|
||||
- task: firewall
|
||||
score: 200
|
||||
- task: olympics
|
||||
score: 200
|
||||
|
||||
- group: SQL
|
||||
start: 2024-04-13 13:00
|
||||
steps:
|
||||
0.3: 2024-04-23 23:59
|
||||
end: 2024-07-10 23:59
|
||||
tasks:
|
||||
- task: dao
|
||||
score: 100
|
||||
- task: ledger
|
||||
score: 200
|
||||
- task: shopfront
|
||||
score: 100
|
||||
- task: wscat
|
||||
score: 200
|
||||
|
||||
- group: "[HW] Dist Build"
|
||||
start: 2024-04-13 13:00
|
||||
end: 2024-05-13 23:59
|
||||
tasks:
|
||||
- task: distbuild
|
||||
score: 1
|
||||
|
||||
- group: Generics
|
||||
start: 2024-04-20 13:00
|
||||
steps:
|
||||
0.3: 2024-05-02 23:59
|
||||
end: 2024-07-10 23:59
|
||||
tasks:
|
||||
- task: genericsum
|
||||
score: 100
|
||||
- task: treeiter
|
||||
score: 100
|
||||
- task: coverme
|
||||
score: 300
|
||||
|
||||
- group: Reflect
|
||||
start: 2024-04-27 13:00
|
||||
steps:
|
||||
0.3: 2024-05-07 23:59
|
||||
end: 2024-07-10 23:59
|
||||
tasks:
|
||||
- task: reversemap
|
||||
score: 100
|
||||
- task: jsonlist
|
||||
score: 100
|
||||
- task: jsonrpc
|
||||
score: 100
|
||||
- task: structtags
|
||||
score: 100
|
||||
|
||||
- group: Low level
|
||||
start: 2024-05-04 13:00
|
||||
steps:
|
||||
0.3: 2024-05-14 23:59
|
||||
end: 2024-07-10 23:59
|
||||
tasks:
|
||||
- task: illegal
|
||||
score: 100
|
||||
- task: blowfish
|
||||
score: 100
|
||||
- task: gzep
|
||||
score: 100
|
||||
|
||||
- group: Analysis
|
||||
start: 2024-05-11 13:00
|
||||
steps:
|
||||
0.3: 2024-05-21 23:59
|
||||
end: 2024-07-10 23:59
|
||||
tasks:
|
||||
- task: testifycheck
|
||||
score: 200
|
||||
|
||||
- group: Bonus
|
||||
start: 2024-03-03 13:00
|
||||
end: 2024-07-10 23:59
|
||||
tasks:
|
||||
- task: yamlembed
|
||||
is_bonus: true
|
||||
score: 100
|
||||
- task: consistenthash
|
||||
is_bonus: true
|
||||
score: 200
|
||||
- task: gossip
|
||||
is_bonus: true
|
||||
score: 300
|
||||
- task: smartsched
|
||||
is_bonus: true
|
||||
score: 200
|
||||
watch:
|
||||
- distbuild/pkg/scheduler
|
||||
- task: wasm
|
||||
is_bonus: true
|
||||
score: 300
|
||||
- task: firegod
|
||||
is_bonus: true
|
||||
score: 200
|
||||
- task: excelwriter
|
||||
is_bonus: true
|
||||
score: 200
|
||||
- task: rsem
|
||||
is_bonus: true
|
||||
score: 200
|
||||
- task: psycher
|
||||
is_bonus: true
|
||||
score: 200
|
3
.private
3
.private
|
@ -1,2 +1 @@
|
|||
wasm/flappygopher/main_solution.go
|
||||
rsem/try_lock.lua
|
||||
wasm/flappygopher/main_solution.go
|
|
@ -1,5 +1,11 @@
|
|||
check:
|
||||
image: gitlab.manytask.org:5050/go/public-2024-spring/build
|
||||
image: cr.yandex/crp9onavos88ug32d5r2/grader/go-build
|
||||
variables:
|
||||
DOCKER_HOST: tcp://docker:2375/
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
APP_HOST: docker
|
||||
# services:
|
||||
#- docker:dind
|
||||
script:
|
||||
- golangci-lint run --build-tags private,solution ./...
|
||||
#- go test -v -tags private,solution ./...
|
||||
|
@ -13,8 +19,8 @@ rebuild-base-image:
|
|||
- docker
|
||||
when: manual
|
||||
script:
|
||||
- docker build -f build.docker -t gitlab.manytask.org:5050/go/public-2024-spring/build .
|
||||
- docker push gitlab.manytask.org:5050/go/public-2024-spring/build:latest
|
||||
- docker build -f build.docker -t cr.yandex/crp9onavos88ug32d5r2/grader/go-build .
|
||||
- docker push cr.yandex/crp9onavos88ug32d5r2/grader/go-build:latest
|
||||
|
||||
deploy:
|
||||
only:
|
||||
|
@ -22,9 +28,9 @@ deploy:
|
|||
tags:
|
||||
- docker
|
||||
script:
|
||||
- docker pull gitlab.manytask.org:5050/go/public-2024-spring/build:latest
|
||||
- docker build -f testenv.docker -t gitlab.manytask.org:5050/go/public-2024-spring .
|
||||
- docker push gitlab.manytask.org:5050/go/public-2024-spring:latest
|
||||
- docker pull cr.yandex/crp9onavos88ug32d5r2/grader/go-build:latest
|
||||
- docker build -f testenv.docker -t cr.yandex/crp9onavos88ug32d5r2/grader/go .
|
||||
- docker push cr.yandex/crp9onavos88ug32d5r2/grader/go:latest
|
||||
|
||||
build-slides:
|
||||
only:
|
||||
|
@ -32,32 +38,28 @@ build-slides:
|
|||
tags:
|
||||
- docker
|
||||
script:
|
||||
- docker build lectures -t gitlab.manytask.org:5050/go/public-2024-spring/lectures
|
||||
- docker push gitlab.manytask.org:5050/go/public-2024-spring/lectures
|
||||
|
||||
update-config:
|
||||
only:
|
||||
- master
|
||||
script:
|
||||
- >
|
||||
curl -v --fail --silent -X POST \
|
||||
-H "Authorization: Bearer $TESTER_TOKEN" \
|
||||
-H "Content-type: application/x-yaml" \
|
||||
--data-binary "@.manytask.yml" \
|
||||
https://go.manytask.org/api/update_config
|
||||
- >
|
||||
curl -v --fail --silent -X POST \
|
||||
-H "Authorization: Bearer $TESTER_TOKEN" \
|
||||
https://go.manytask.org/api/update_cache
|
||||
- docker build lectures -t cr.yandex/crp9onavos88ug32d5r2/go-lectures
|
||||
- docker push cr.yandex/crp9onavos88ug32d5r2/go-lectures
|
||||
|
||||
push-to-public:
|
||||
stage: .post
|
||||
image: gitlab.manytask.org:5050/go/public-2024-spring
|
||||
parallel:
|
||||
matrix:
|
||||
- REMOTE:
|
||||
- git@github.com:slon/shad-go.git
|
||||
- git@gitlab.manytask.org:go/public-2024-spring.git
|
||||
image: cr.yandex/crp9onavos88ug32d5r2/grader/go
|
||||
only:
|
||||
- master
|
||||
script:
|
||||
- git remote rm public || true
|
||||
- git remote add -f public https://svparamoshkin:${CI_PUSH_TOKEN}@gitlab.manytask.org/go/public-itmo-2023-fall
|
||||
- git config --global user.email 'svparamoshkin@yandex-team.ru'
|
||||
- git config --global user.name 'svparamoshkin'
|
||||
- git fetch public
|
||||
- git branch -D public || true
|
||||
- git branch public public/master
|
||||
- testtool export --push --move-to-master=false
|
||||
- curl -F token=$TESTER_TOKEN http://itmo-go.manytask.org/api/sync_task_columns
|
||||
|
||||
push-to-github:
|
||||
stage: .post
|
||||
image: cr.yandex/crp9onavos88ug32d5r2/grader/go
|
||||
only:
|
||||
- master
|
||||
script:
|
||||
|
@ -67,7 +69,7 @@ push-to-public:
|
|||
- git branch -D main || true
|
||||
- git checkout -b main
|
||||
- git remote rm github || true
|
||||
- env GIT_SSH_COMMAND="ssh -i ${PWD}/private.key -o StrictHostKeyChecking=no" git remote add -f github $REMOTE
|
||||
- env GIT_SSH_COMMAND="ssh -i ${PWD}/private.key -o StrictHostKeyChecking=no" git remote add -f github git@github.com:slon/shad-go.git
|
||||
- env GIT_SSH_COMMAND="ssh -i ${PWD}/private.key -o StrictHostKeyChecking=no" git push github main
|
||||
|
||||
deploy-slides:
|
||||
|
@ -77,5 +79,5 @@ deploy-slides:
|
|||
tags:
|
||||
- web
|
||||
script:
|
||||
- docker pull gitlab.manytask.org:5050/go/public-2024-spring/lectures
|
||||
- docker pull cr.yandex/crp9onavos88ug32d5r2/go-lectures
|
||||
- cd /srv/manytask/go && docker compose up -d
|
||||
|
|
|
@ -1,28 +1,26 @@
|
|||
# Как послать патч
|
||||
|
||||
Если вы нашли недоработку в тестах или неточность/опечатку в условии, то вы можете послать PR
|
||||
Если вы нашли недоработку в тестах или неточность/опечатку в условии, то вы можете послать MR
|
||||
с исправлением в репозиторий курса.
|
||||
|
||||
За все исправления начисляются дополнительные баллы в колонке bonus в таблице.
|
||||
За все исправления начисляются дополнительные баллы в колонке bugs в таблице.
|
||||
Размер дополнительных баллов зависит от серьёзности исправления и определяется преподавателями.
|
||||
|
||||
## Небольшие исправления
|
||||
|
||||
Небольшие исправления на <10 строк проще всего послать через веб интерфейс гитхаба.
|
||||
Небольшие исправления на <10 строк проще всего послать через веб интерфейс гитлаба.
|
||||
|
||||
1. Откройте нужный файл в веб интерфейсе репозитория https://github.com/slon/shad-go
|
||||
2. Нажмите на кнопку "Edit in place".
|
||||
![](docs/edit-in-place.png)
|
||||
3. На следующем экране нажмите "Fork this repository".
|
||||
3. Внесите изменения в файл. Нажмите "Commit Changes" сверху страницы.
|
||||
4. Добавьте описание вашего изменения. Нажмите "Propose changed".
|
||||
5. Нажмите "Create pull request".
|
||||
1. Откройте нужный файл в веб интерфейсе репозитория https://gitlab.com/manytask/itmo-go/private
|
||||
2. Нажмите на кнопку "Edit". Во всплывающей подсказке нажмите кнопку "Fork".
|
||||
![](docs/edit-and-fork.png)
|
||||
3. Внесите изменения в файл. Нажмите "Commit Changes" внизу страницы.
|
||||
4. Добавьте описание вашего изменения. Нажмите "Submit Merge Request".
|
||||
|
||||
## Продвинутые исправления
|
||||
|
||||
Для многофайловых исправлений можно сначала сделать исправление локально:
|
||||
|
||||
1. Создайте форк https://github.com/slon/shad-go аналогично тому, что выше.
|
||||
1. Создайте форк https://gitlab.com/manytask/itmo-go/private аналогично тому, что выше.
|
||||
|
||||
2. Закоммитьте все локальные изменения, которые вы не хотите добавлять в репозиторий курса.
|
||||
|
||||
|
@ -32,13 +30,16 @@
|
|||
git checkout origin/master -b newbranchforupdate
|
||||
```
|
||||
|
||||
4. Внесите локальные изменения и запушьте их в свой форк на [github.com](https://github.com/) (не в `student`), например
|
||||
4. Внесите локальные изменения и запушьте их в свой форк на [gitlab.com](https://gitlab.com/) (не в `student`), например
|
||||
```
|
||||
git add .
|
||||
git commit -m "Update tests"
|
||||
git push https://github.com/%USERNAME%/shad-go/
|
||||
git push https://gitlab.com/%USERNAME%/shad-go/
|
||||
```
|
||||
|
||||
5. В своём форке выберите созданную ветку и создайте Pull Request в репозиторий курса. Обычно Github подсказывает недавно запушенную ветку и предлагает создать для неё PR.
|
||||
5. В своём форке выберите созданную ветку и создайте Merge Request в репозиторий курса. Обычно GitLab подсказывает недавно запушенную ветку и предлагает создать для неё MR.
|
||||
|
||||
На странице c формой нового Pull Request убедитесь, что ветвь назначения — `slon/shad-go:master`. Нажмите кнопку "Create Pull Request".
|
||||
![](docs/create-mr.png)
|
||||
|
||||
На странице c формой нового Merge Request убедитесь, что ветвь назначения — `slon/shad-go:master`. Нажмите кнопку "Create Merge Request".
|
||||
![](docs/create-mr-form.png)
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
# Курс по Го в ШАД
|
||||
|
||||
Для работы с кодом нужен go 1.18 или выше.
|
||||
|
||||
```sh
|
||||
git clone https://gitlab.com/manytask/itmo-go/private.git
|
||||
cd shad-go
|
||||
go test ./sum/...
|
||||
```
|
||||
|
||||
Проект можно открыть в любой go IDE с поддержкой модулей.
|
||||
|
||||
## Информация
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
```
|
||||
goos: linux
|
||||
goarch: amd64
|
||||
pkg: gitlab.com/slon/shad-go/allocs
|
||||
pkg: gitlab.com/manytask/itmo-go/private/allocs
|
||||
Benchmark/count-4 73200 16294 ns/op 880 B/op 5 allocs/op
|
||||
Benchmark/main-4 40485 30113 ns/op 1034 B/op 9 allocs/op
|
||||
```
|
||||
|
@ -23,7 +23,7 @@ Benchmark/main-4 40485 30113 ns/op 1034
|
|||
Значения бенчмарков для авторского решения:
|
||||
```goos: linux
|
||||
goarch: amd64
|
||||
pkg: gitlab.com/slon/shad-go/allocs
|
||||
pkg: gitlab.com/manytask/itmo-go/private/allocs
|
||||
Benchmark/count-4 212850 5471 ns/op 4144 B/op 2 allocs/op
|
||||
Benchmark/main-4 143937 8247 ns/op 4176 B/op 3 allocs/op
|
||||
```
|
||||
|
|
|
@ -5,6 +5,7 @@ package allocs
|
|||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
@ -23,7 +24,7 @@ func NewBaselineCounter() Counter {
|
|||
}
|
||||
|
||||
func (c BaselineCounter) Count(r io.Reader) error {
|
||||
data, err := io.ReadAll(r)
|
||||
data, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
|
||||
package batcher
|
||||
|
||||
import "gitlab.com/slon/shad-go/batcher/slow"
|
||||
import "gitlab.com/manytask/itmo-go/private/batcher/slow"
|
||||
|
||||
type Batcher struct {
|
||||
}
|
||||
type Batcher struct{}
|
||||
|
||||
func NewBatcher(v *slow.Value) *Batcher {
|
||||
return nil
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/goleak"
|
||||
|
||||
"gitlab.com/slon/shad-go/batcher/slow"
|
||||
"gitlab.com/manytask/itmo-go/private/batcher/slow"
|
||||
)
|
||||
|
||||
func TestSimple(t *testing.T) {
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gitlab.com/slon/shad-go/blowfish"
|
||||
"gitlab.com/manytask/itmo-go/private/blowfish"
|
||||
)
|
||||
|
||||
var _ cipher.Block = (*blowfish.Blowfish)(nil)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM golang:1.22
|
||||
FROM golang:1.20
|
||||
|
||||
# enable backports for git-filter-repo
|
||||
RUN echo "deb http://deb.debian.org/debian bullseye-backports main" >> /etc/apt/sources.list.d/backports.list
|
||||
|
@ -7,4 +7,4 @@ RUN apt-get update && apt-get install -y \
|
|||
rsync libssl-dev postgresql sudo redis-server git-filter-repo/bullseye-backports \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.56.2
|
||||
RUN curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.51.1
|
||||
|
|
|
@ -35,7 +35,7 @@ Your pipeline #194613 has failed! // 194613 -- это ID pipeline'а
|
|||
// Далее идут последние 10 строк лога gitlab runner'а
|
||||
testtool: copying go.mod, go.sum and .golangci.yml
|
||||
testtool: running tests
|
||||
testtool: > go test -mod readonly -tags private -c -o /tmp/bincache730817117/5d83984f885e61c1 gitlab.com/slon/shad-go/sum
|
||||
testtool: > go test -mod readonly -tags private -c -o /tmp/bincache730817117/5d83984f885e61c1 gitlab.com/manytask/itmo-go/private/sum
|
||||
--- FAIL: TestSum (0.00s)
|
||||
sum_test.go:19: 2 + 2 == 0 != 4
|
||||
sum_test.go:19: 9223372036854775807 + 1 == 0 != -9223372036854775808
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gitlab.com/slon/shad-go/tools/testtool"
|
||||
"gitlab.com/manytask/itmo-go/private/tools/testtool"
|
||||
)
|
||||
|
||||
type testCase struct {
|
||||
|
@ -93,7 +93,7 @@ testtool: copying !change files
|
|||
testtool: copying testdata directory
|
||||
testtool: copying go.mod, go.sum and .golangci.yml
|
||||
testtool: running tests
|
||||
testtool: > go test -mod readonly -tags private -c -o /tmp/bincache730817117/5d83984f885e61c1 gitlab.com/slon/shad-go/sum
|
||||
testtool: > go test -mod readonly -tags private -c -o /tmp/bincache730817117/5d83984f885e61c1 gitlab.com/manytask/itmo-go/private/sum
|
||||
--- FAIL: TestSum (0.00s)
|
||||
sum_test.go:19: 2 + 2 == 0 != 4
|
||||
sum_test.go:19: 9223372036854775807 + 1 == 0 != -9223372036854775808
|
||||
|
@ -113,7 +113,7 @@ ERROR: Job failed: exit code 1`,
|
|||
Stage: test, Job grade
|
||||
testtool: copying go.mod, go.sum and .golangci.yml
|
||||
testtool: running tests
|
||||
testtool: > go test -mod readonly -tags private -c -o /tmp/bincache730817117/5d83984f885e61c1 gitlab.com/slon/shad-go/sum
|
||||
testtool: > go test -mod readonly -tags private -c -o /tmp/bincache730817117/5d83984f885e61c1 gitlab.com/manytask/itmo-go/private/sum
|
||||
--- FAIL: TestSum (0.00s)
|
||||
sum_test.go:19: 2 + 2 == 0 != 4
|
||||
sum_test.go:19: 9223372036854775807 + 1 == 0 != -9223372036854775808
|
||||
|
@ -156,7 +156,7 @@ testtool: copying !change files
|
|||
testtool: copying testdata directory
|
||||
testtool: copying go.mod, go.sum and .golangci.yml
|
||||
testtool: running tests
|
||||
testtool: > go test -mod readonly -tags private -c -o /tmp/bincache730817117/5d83984f885e61c1 gitlab.com/slon/shad-go/sum
|
||||
testtool: > go test -mod readonly -tags private -c -o /tmp/bincache730817117/5d83984f885e61c1 gitlab.com/manytask/itmo-go/private/sum
|
||||
--- FAIL: TestSum (0.00s)
|
||||
sum_test.go:19: 2 + 2 == 0 != 4
|
||||
sum_test.go:19: 9223372036854775807 + 1 == 0 != -9223372036854775808
|
||||
|
@ -188,7 +188,7 @@ ERROR: Job failed: exit code 1`,
|
|||
Stage: %v, Job %v
|
||||
testtool: copying go.mod, go.sum and .golangci.yml
|
||||
testtool: running tests
|
||||
testtool: > go test -mod readonly -tags private -c -o /tmp/bincache730817117/5d83984f885e61c1 gitlab.com/slon/shad-go/sum
|
||||
testtool: > go test -mod readonly -tags private -c -o /tmp/bincache730817117/5d83984f885e61c1 gitlab.com/manytask/itmo-go/private/sum
|
||||
--- FAIL: TestSum (0.00s)
|
||||
sum_test.go:19: 2 + 2 == 0 != 4
|
||||
sum_test.go:19: 9223372036854775807 + 1 == 0 != -9223372036854775808
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package cond
|
||||
|
||||
import (
|
||||
"gitlab.com/slon/shad-go/tools/testtool"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -45,38 +44,6 @@ func TestCondSignal(t *testing.T) {
|
|||
c.Signal()
|
||||
}
|
||||
|
||||
func TestCondSignalOveruse(t *testing.T) {
|
||||
var m sync.Mutex
|
||||
c := New(&m)
|
||||
running := make(chan bool, 1)
|
||||
awake := make(chan bool, 1)
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
c.Signal() // Checks if empty signals are not deadlocking
|
||||
}
|
||||
|
||||
go func() {
|
||||
m.Lock()
|
||||
running <- true
|
||||
c.Wait() // Checks if it will wait after empty signals
|
||||
awake <- true
|
||||
m.Unlock()
|
||||
|
||||
}()
|
||||
|
||||
<-running
|
||||
|
||||
select {
|
||||
case <-awake:
|
||||
t.Fatal("goroutine not asleep")
|
||||
default:
|
||||
}
|
||||
m.Lock()
|
||||
c.Signal()
|
||||
m.Unlock()
|
||||
<-awake // Will deadlock if no goroutine wakes up
|
||||
}
|
||||
|
||||
func TestCondSignalGenerations(t *testing.T) {
|
||||
var m sync.Mutex
|
||||
c := New(&m)
|
||||
|
@ -215,7 +182,3 @@ func TestCondSignalStealing(t *testing.T) {
|
|||
cond.Broadcast()
|
||||
}
|
||||
}
|
||||
|
||||
func TestNoSyncPackageImported(t *testing.T) {
|
||||
testtool.CheckForbiddenImport(t, "sync")
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ func TestHash_EvenDistribution(t *testing.T) {
|
|||
h.AddNode(&n)
|
||||
}
|
||||
|
||||
counts := map[*node]float64{}
|
||||
counts := map[*node]int{}
|
||||
const N = 1 << 16
|
||||
for i := 0; i < N; i++ {
|
||||
counts[h.GetNode(fmt.Sprintf("key%d", i))] += 1
|
||||
|
@ -65,23 +65,14 @@ func TestHash_EvenDistribution(t *testing.T) {
|
|||
|
||||
const P = 1 / float64(K)
|
||||
const variance = N * (P) * (1 - P)
|
||||
idealStddev := math.Sqrt(variance)
|
||||
|
||||
t.Logf("P = %v, var = %v, stddev = %v", P, variance, idealStddev)
|
||||
stddev := math.Sqrt(variance)
|
||||
t.Logf("P = %v, var = %v, stddev = %v", P, variance, stddev)
|
||||
t.Logf("counts = %v", maps.Values(counts))
|
||||
|
||||
total := float64(N)
|
||||
mean := total / K
|
||||
|
||||
var dispersion float64
|
||||
for _, count := range counts {
|
||||
dispersion += (count - mean) * (count - mean)
|
||||
require.Greater(t, count, int(N/K-stddev*10))
|
||||
require.Less(t, count, int(N/K+stddev*10))
|
||||
}
|
||||
|
||||
realStddev := math.Sqrt(dispersion / K)
|
||||
t.Logf("read stddev = %v", realStddev)
|
||||
|
||||
require.Less(t, math.Abs(realStddev-idealStddev)/idealStddev, float64(4))
|
||||
}
|
||||
|
||||
func TestHash_ConsistentDistribution(t *testing.T) {
|
||||
|
|
|
@ -12,8 +12,8 @@ import (
|
|||
"github.com/gorilla/handlers"
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"gitlab.com/slon/shad-go/coverme/models"
|
||||
"gitlab.com/slon/shad-go/coverme/utils"
|
||||
"gitlab.com/manytask/itmo-go/private/coverme/models"
|
||||
"gitlab.com/manytask/itmo-go/private/coverme/utils"
|
||||
)
|
||||
|
||||
type App struct {
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"gitlab.com/slon/shad-go/coverme/models"
|
||||
"gitlab.com/manytask/itmo-go/private/coverme/models"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
|
|
|
@ -5,8 +5,8 @@ package main
|
|||
import (
|
||||
"flag"
|
||||
|
||||
"gitlab.com/slon/shad-go/coverme/app"
|
||||
"gitlab.com/slon/shad-go/coverme/models"
|
||||
"gitlab.com/manytask/itmo-go/private/coverme/app"
|
||||
"gitlab.com/manytask/itmo-go/private/coverme/models"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
|
@ -31,14 +31,18 @@ sudo apt install postgresql
|
|||
Альтернативный способ — запустить бд в докере.
|
||||
|
||||
Для этого нужно установить docker и docker-compose по инструкции из [dockertest](../dockertest/README.md).
|
||||
Добиться успешного запуска
|
||||
```
|
||||
go test -v ./dockertest/...
|
||||
```
|
||||
|
||||
Запускать тесты можно будет так:
|
||||
```
|
||||
(cd dao && docker compose up -d --wait && env PGCONN="host=127.0.0.1 port=5432 database=shad-go user=gopher password=pass" go test -v ./... -count=1 || true && docker compose down)
|
||||
(cd dao && docker-compose up -d && sleep 1 && env PGCONN="host=127.0.0.1 port=5432 database=shad-go user=gopher password=pass" go test -v ./... -count=1 || true && docker-compose down)
|
||||
```
|
||||
Эта команда стартует docker с postgresql, запускает тесты, передав им DSN через переменную окружения, удаляет контейнеры в конце.
|
||||
|
||||
Как подчистить контейнеры, если что-то пошло не так:
|
||||
```
|
||||
(cd dao && docker compose down)
|
||||
(cd dao && docker-compose down)
|
||||
```
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/goleak"
|
||||
|
||||
"gitlab.com/slon/shad-go/pgfixture"
|
||||
"gitlab.com/manytask/itmo-go/private/pgfixture"
|
||||
)
|
||||
|
||||
func TestDao(t *testing.T) {
|
||||
|
@ -36,7 +36,7 @@ func TestDao(t *testing.T) {
|
|||
|
||||
alice, err := dao.Lookup(ctx, aliceID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, User{ID: aliceID, Name: "Alice"}, alice)
|
||||
require.Equal(t, alice, User{ID: aliceID, Name: "Alice"})
|
||||
|
||||
require.NoError(t, dao.Delete(ctx, bobID))
|
||||
|
||||
|
@ -44,7 +44,6 @@ func TestDao(t *testing.T) {
|
|||
require.ErrorIs(t, err, sql.ErrNoRows)
|
||||
|
||||
require.NoError(t, dao.Update(ctx, &User{ID: charlieID, Name: "Chaplin"}))
|
||||
require.Error(t, dao.Update(ctx, &User{ID: 999, Name: "FooBar"}))
|
||||
|
||||
users, err := dao.List(ctx)
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -8,8 +8,3 @@ services:
|
|||
POSTGRES_PASSWORD: pass
|
||||
ports:
|
||||
- 5432:5432
|
||||
healthcheck:
|
||||
test: [ "CMD-SHELL", "pg_isready -U $${POSTGRES_USER}" ]
|
||||
interval: 1s
|
||||
timeout: 3s
|
||||
retries: 5
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"image"
|
||||
"image/png"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
|
@ -17,10 +18,10 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gitlab.com/slon/shad-go/tools/testtool"
|
||||
"gitlab.com/manytask/itmo-go/private/tools/testtool"
|
||||
)
|
||||
|
||||
const importPath = "gitlab.com/slon/shad-go/digitalclock"
|
||||
const importPath = "gitlab.com/manytask/itmo-go/private/digitalclock"
|
||||
|
||||
var binCache testtool.BinCache
|
||||
|
||||
|
@ -124,7 +125,7 @@ func TestDigitalClock_valid(t *testing.T) {
|
|||
port, stop := startServer(t)
|
||||
defer stop()
|
||||
|
||||
files, err := os.ReadDir("./testdata")
|
||||
files, err := ioutil.ReadDir("./testdata")
|
||||
require.NoError(t, err)
|
||||
|
||||
c := &http.Client{Timeout: time.Second * 10}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
@ -16,13 +17,13 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/goleak"
|
||||
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/api"
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/artifact"
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/client"
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/dist"
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/filecache"
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/worker"
|
||||
"gitlab.com/slon/shad-go/tools/testtool"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/api"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/artifact"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/client"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/dist"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/filecache"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/worker"
|
||||
"gitlab.com/manytask/itmo-go/private/tools/testtool"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
@ -49,11 +50,7 @@ type Config struct {
|
|||
WorkerCount int
|
||||
}
|
||||
|
||||
func newEnv(t *testing.T, config *Config) (e *env) {
|
||||
t.Cleanup(func() {
|
||||
goleak.VerifyNone(t)
|
||||
})
|
||||
|
||||
func newEnv(t *testing.T, config *Config) (e *env, cancel func()) {
|
||||
cwd, err := os.Getwd()
|
||||
require.NoError(t, err)
|
||||
|
||||
|
@ -63,9 +60,9 @@ func newEnv(t *testing.T, config *Config) (e *env) {
|
|||
rootDir := filepath.Join(absCWD, "workdir", t.Name())
|
||||
require.NoError(t, os.RemoveAll(rootDir))
|
||||
|
||||
if err = os.MkdirAll(rootDir, 0777); err != nil {
|
||||
if err = os.MkdirAll(rootDir, 0o777); err != nil {
|
||||
if errors.Is(err, os.ErrPermission) {
|
||||
rootDir, err = os.MkdirTemp("", "")
|
||||
rootDir, err = ioutil.TempDir("", "")
|
||||
require.NoError(t, err)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
|
@ -93,10 +90,6 @@ func newEnv(t *testing.T, config *Config) (e *env) {
|
|||
env.Logger, err = cfg.Build()
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
_ = env.Logger.Sync()
|
||||
})
|
||||
|
||||
t.Helper()
|
||||
t.Logf("test is running inside %s; see test.log file for more info", filepath.Join("workdir", t.Name()))
|
||||
|
||||
|
@ -107,7 +100,6 @@ func newEnv(t *testing.T, config *Config) (e *env) {
|
|||
|
||||
var cancelRootContext func()
|
||||
env.Ctx, cancelRootContext = context.WithCancel(context.Background())
|
||||
t.Cleanup(cancelRootContext)
|
||||
|
||||
env.Client = client.NewClient(
|
||||
env.Logger.Named("client"),
|
||||
|
@ -121,7 +113,6 @@ func newEnv(t *testing.T, config *Config) (e *env) {
|
|||
env.Logger.Named("coordinator"),
|
||||
coordinatorCache,
|
||||
)
|
||||
t.Cleanup(env.Coordinator.Stop)
|
||||
|
||||
router := http.NewServeMux()
|
||||
router.Handle("/coordinator/", http.StripPrefix("/coordinator", env.Coordinator))
|
||||
|
@ -170,11 +161,6 @@ func newEnv(t *testing.T, config *Config) (e *env) {
|
|||
}
|
||||
}()
|
||||
|
||||
t.Cleanup(func() {
|
||||
cancelRootContext()
|
||||
_ = env.HTTP.Shutdown(context.Background())
|
||||
})
|
||||
|
||||
for _, w := range env.Workers {
|
||||
go func(w *worker.Worker) {
|
||||
err := w.Run(env.Ctx)
|
||||
|
@ -195,14 +181,20 @@ func newEnv(t *testing.T, config *Config) (e *env) {
|
|||
}
|
||||
}()
|
||||
|
||||
return env
|
||||
return env, func() {
|
||||
cancelRootContext()
|
||||
_ = env.HTTP.Shutdown(context.Background())
|
||||
_ = env.Logger.Sync()
|
||||
|
||||
goleak.VerifyNone(t)
|
||||
}
|
||||
}
|
||||
|
||||
func newWinFileSink(u *url.URL) (zap.Sink, error) {
|
||||
if len(u.Opaque) > 0 {
|
||||
// Remove leading slash left by url.Parse()
|
||||
return os.OpenFile(u.Opaque[1:], os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
|
||||
return os.OpenFile(u.Opaque[1:], os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0o644)
|
||||
}
|
||||
// if url.URL is empty, don't panic slice index error
|
||||
return os.OpenFile(u.Opaque, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
|
||||
return os.OpenFile(u.Opaque, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0o644)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package disttest
|
||||
|
||||
import (
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/build"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build"
|
||||
)
|
||||
|
||||
type JobResult struct {
|
||||
|
|
|
@ -2,14 +2,13 @@ package disttest
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/build"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build"
|
||||
)
|
||||
|
||||
var singleWorkerConfig = &Config{WorkerCount: 1}
|
||||
|
@ -27,7 +26,8 @@ var echoGraph = build.Graph{
|
|||
}
|
||||
|
||||
func TestSingleCommand(t *testing.T) {
|
||||
env := newEnv(t, singleWorkerConfig)
|
||||
env, cancel := newEnv(t, singleWorkerConfig)
|
||||
defer cancel()
|
||||
|
||||
recorder := NewRecorder()
|
||||
require.NoError(t, env.Client.Build(env.Ctx, echoGraph, recorder))
|
||||
|
@ -37,9 +37,10 @@ func TestSingleCommand(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestJobCaching(t *testing.T) {
|
||||
env := newEnv(t, singleWorkerConfig)
|
||||
env, cancel := newEnv(t, singleWorkerConfig)
|
||||
defer cancel()
|
||||
|
||||
tmpFile, err := os.CreateTemp("", "")
|
||||
tmpFile, err := ioutil.TempFile("", "")
|
||||
require.NoError(t, err)
|
||||
|
||||
graph := build.Graph{
|
||||
|
@ -61,12 +62,12 @@ func TestJobCaching(t *testing.T) {
|
|||
assert.Len(t, recorder.Jobs, 1)
|
||||
assert.Equal(t, &JobResult{Stdout: "OK\n", Code: new(int)}, recorder.Jobs[build.ID{'a'}])
|
||||
|
||||
require.NoError(t, os.WriteFile(tmpFile.Name(), []byte("NOTOK\n"), 0666))
|
||||
require.NoError(t, ioutil.WriteFile(tmpFile.Name(), []byte("NOTOK\n"), 0o666))
|
||||
|
||||
// Second build must get results from cache.
|
||||
require.NoError(t, env.Client.Build(env.Ctx, graph, NewRecorder()))
|
||||
|
||||
output, err := io.ReadAll(tmpFile)
|
||||
output, err := ioutil.ReadAll(tmpFile)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []byte("NOTOK\n"), output)
|
||||
}
|
||||
|
@ -93,7 +94,8 @@ var sourceFilesGraph = build.Graph{
|
|||
}
|
||||
|
||||
func TestSourceFiles(t *testing.T) {
|
||||
env := newEnv(t, singleWorkerConfig)
|
||||
env, cancel := newEnv(t, singleWorkerConfig)
|
||||
defer cancel()
|
||||
|
||||
recorder := NewRecorder()
|
||||
require.NoError(t, env.Client.Build(env.Ctx, sourceFilesGraph, recorder))
|
||||
|
@ -123,7 +125,8 @@ var artifactTransferGraph = build.Graph{
|
|||
}
|
||||
|
||||
func TestArtifactTransferBetweenJobs(t *testing.T) {
|
||||
env := newEnv(t, singleWorkerConfig)
|
||||
env, cancel := newEnv(t, singleWorkerConfig)
|
||||
defer cancel()
|
||||
|
||||
recorder := NewRecorder()
|
||||
require.NoError(t, env.Client.Build(env.Ctx, artifactTransferGraph, recorder))
|
||||
|
|
|
@ -9,13 +9,14 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/build"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build"
|
||||
)
|
||||
|
||||
var threeWorkerConfig = &Config{WorkerCount: 3}
|
||||
|
||||
func TestArtifactTransferBetweenWorkers(t *testing.T) {
|
||||
env := newEnv(t, threeWorkerConfig)
|
||||
env, cancel := newEnv(t, threeWorkerConfig)
|
||||
defer cancel()
|
||||
|
||||
baseJob := build.Job{
|
||||
ID: build.ID{'a'},
|
||||
|
|
|
@ -3,7 +3,7 @@ package api
|
|||
import (
|
||||
"context"
|
||||
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/build"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build"
|
||||
)
|
||||
|
||||
type BuildRequest struct {
|
||||
|
@ -25,8 +25,7 @@ type BuildFailed struct {
|
|||
Error string
|
||||
}
|
||||
|
||||
type BuildFinished struct {
|
||||
}
|
||||
type BuildFinished struct{}
|
||||
|
||||
type UploadDone struct{}
|
||||
|
||||
|
@ -34,8 +33,7 @@ type SignalRequest struct {
|
|||
UploadDone *UploadDone
|
||||
}
|
||||
|
||||
type SignalResponse struct {
|
||||
}
|
||||
type SignalResponse struct{}
|
||||
|
||||
type StatusWriter interface {
|
||||
Started(rsp *BuildStarted) error
|
||||
|
|
|
@ -7,11 +7,10 @@ import (
|
|||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/build"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build"
|
||||
)
|
||||
|
||||
type BuildClient struct {
|
||||
}
|
||||
type BuildClient struct{}
|
||||
|
||||
func NewBuildClient(l *zap.Logger, endpoint string) *BuildClient {
|
||||
panic("implement me")
|
||||
|
|
|
@ -12,9 +12,9 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/zap/zaptest"
|
||||
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/api"
|
||||
mock "gitlab.com/slon/shad-go/distbuild/pkg/api/mock"
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/build"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/api"
|
||||
mock "gitlab.com/manytask/itmo-go/private/distbuild/pkg/api/mock"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build"
|
||||
)
|
||||
|
||||
//go:generate mockgen -package mock -destination mock/mock.go . Service
|
||||
|
@ -28,6 +28,7 @@ type env struct {
|
|||
|
||||
func (e *env) stop() {
|
||||
e.server.Close()
|
||||
e.ctrl.Finish()
|
||||
}
|
||||
|
||||
func newEnv(t *testing.T) (*env, func()) {
|
||||
|
@ -55,8 +56,8 @@ func TestBuildSignal(t *testing.T) {
|
|||
|
||||
ctx := context.Background()
|
||||
|
||||
buildIDa := build.ID{01}
|
||||
buildIDb := build.ID{02}
|
||||
buildIDa := build.ID{0o1}
|
||||
buildIDb := build.ID{0o2}
|
||||
req := &api.SignalRequest{}
|
||||
rsp := &api.SignalResponse{}
|
||||
|
||||
|
@ -90,10 +91,10 @@ func TestBuildRunning(t *testing.T) {
|
|||
|
||||
ctx := context.Background()
|
||||
|
||||
buildID := build.ID{02}
|
||||
buildID := build.ID{0o2}
|
||||
|
||||
req := &api.BuildRequest{
|
||||
Graph: build.Graph{SourceFiles: map[build.ID]string{{01}: "a.txt"}},
|
||||
Graph: build.Graph{SourceFiles: map[build.ID]string{{0o1}: "a.txt"}},
|
||||
}
|
||||
|
||||
started := &api.BuildStarted{ID: buildID}
|
||||
|
@ -140,7 +141,7 @@ func TestBuildResultsStreaming(t *testing.T) {
|
|||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
buildID := build.ID{02}
|
||||
buildID := build.ID{0o2}
|
||||
req := &api.BuildRequest{}
|
||||
started := &api.BuildStarted{ID: buildID}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package api
|
|||
import (
|
||||
"context"
|
||||
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/build"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build"
|
||||
)
|
||||
|
||||
// JobResult описывает результат работы джоба.
|
||||
|
|
|
@ -11,15 +11,16 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/zap/zaptest"
|
||||
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/api"
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/api/mock"
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/build"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/api"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/api/mock"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build"
|
||||
)
|
||||
|
||||
//go:generate mockgen -package mock -destination mock/heartbeat.go . HeartbeatService
|
||||
|
||||
func TestHeartbeat(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
l := zaptest.NewLogger(t)
|
||||
m := mock.NewMockHeartbeatService(ctrl)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: gitlab.com/slon/shad-go/distbuild/pkg/api (interfaces: HeartbeatService)
|
||||
// Source: gitlab.com/manytask/itmo-go/private/distbuild/pkg/api (interfaces: HeartbeatService)
|
||||
|
||||
// Package mock is a generated GoMock package.
|
||||
package mock
|
||||
|
@ -7,7 +7,7 @@ package mock
|
|||
import (
|
||||
context "context"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
api "gitlab.com/slon/shad-go/distbuild/pkg/api"
|
||||
api "gitlab.com/manytask/itmo-go/private/distbuild/pkg/api"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: gitlab.com/slon/shad-go/distbuild/pkg/api (interfaces: Service)
|
||||
// Source: gitlab.com/manytask/itmo-go/private/distbuild/pkg/api (interfaces: Service)
|
||||
|
||||
// Package mock is a generated GoMock package.
|
||||
package mock
|
||||
|
@ -7,8 +7,8 @@ package mock
|
|||
import (
|
||||
context "context"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
api "gitlab.com/slon/shad-go/distbuild/pkg/api"
|
||||
build "gitlab.com/slon/shad-go/distbuild/pkg/build"
|
||||
api "gitlab.com/manytask/itmo-go/private/distbuild/pkg/api"
|
||||
build "gitlab.com/manytask/itmo-go/private/distbuild/pkg/build"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
|
|
|
@ -4,11 +4,12 @@ import (
|
|||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/build"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -33,18 +34,18 @@ func NewCache(root string) (*Cache, error) {
|
|||
if err := os.RemoveAll(tmpDir); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := os.MkdirAll(tmpDir, 0777); err != nil {
|
||||
if err := os.MkdirAll(tmpDir, 0o777); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cacheDir := filepath.Join(root, "c")
|
||||
if err := os.MkdirAll(cacheDir, 0777); err != nil {
|
||||
if err := os.MkdirAll(cacheDir, 0o777); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := 0; i < 256; i++ {
|
||||
d := hex.EncodeToString([]byte{uint8(i)})
|
||||
if err := os.MkdirAll(filepath.Join(cacheDir, d), 0777); err != nil {
|
||||
if err := os.MkdirAll(filepath.Join(cacheDir, d), 0o777); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
@ -109,13 +110,13 @@ func (c *Cache) writeUnlock(id build.ID) {
|
|||
}
|
||||
|
||||
func (c *Cache) Range(artifactFn func(artifact build.ID) error) error {
|
||||
shards, err := os.ReadDir(c.cacheDir)
|
||||
shards, err := ioutil.ReadDir(c.cacheDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, shard := range shards {
|
||||
dirs, err := os.ReadDir(filepath.Join(c.cacheDir, shard.Name()))
|
||||
dirs, err := ioutil.ReadDir(filepath.Join(c.cacheDir, shard.Name()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -150,7 +151,7 @@ func (c *Cache) Create(artifact build.ID) (path string, commit, abort func() err
|
|||
}
|
||||
|
||||
path = filepath.Join(c.tmpDir, artifact.String())
|
||||
if err = os.MkdirAll(path, 0777); err != nil {
|
||||
if err = os.MkdirAll(path, 0o777); err != nil {
|
||||
c.writeUnlock(artifact)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -2,14 +2,15 @@ package artifact_test
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/artifact"
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/build"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/artifact"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build"
|
||||
)
|
||||
|
||||
type testCache struct {
|
||||
|
@ -22,7 +23,7 @@ func (c *testCache) cleanup() {
|
|||
}
|
||||
|
||||
func newTestCache(t *testing.T) *testCache {
|
||||
tmpDir, err := os.MkdirTemp("", "")
|
||||
tmpDir, err := ioutil.TempDir("", "")
|
||||
require.NoError(t, err)
|
||||
|
||||
cache, err := artifact.NewCache(tmpDir)
|
||||
|
|
|
@ -5,7 +5,7 @@ package artifact
|
|||
import (
|
||||
"context"
|
||||
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/build"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build"
|
||||
)
|
||||
|
||||
// Download artifact from remote cache into local cache.
|
||||
|
|
|
@ -2,17 +2,17 @@ package artifact_test
|
|||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/zap/zaptest"
|
||||
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/artifact"
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/build"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/artifact"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build"
|
||||
)
|
||||
|
||||
func TestArtifactTransfer(t *testing.T) {
|
||||
|
@ -23,7 +23,7 @@ func TestArtifactTransfer(t *testing.T) {
|
|||
|
||||
dir, commit, _, err := remoteCache.Create(id)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, os.WriteFile(filepath.Join(dir, "a.txt"), []byte("foobar"), 0777))
|
||||
require.NoError(t, ioutil.WriteFile(filepath.Join(dir, "a.txt"), []byte("foobar"), 0o777))
|
||||
require.NoError(t, commit())
|
||||
|
||||
l := zaptest.NewLogger(t)
|
||||
|
@ -42,7 +42,7 @@ func TestArtifactTransfer(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
defer unlock()
|
||||
|
||||
content, err := os.ReadFile(filepath.Join(dir, "a.txt"))
|
||||
content, err := ioutil.ReadFile(filepath.Join(dir, "a.txt"))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []byte("foobar"), content)
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ type Job struct {
|
|||
// exec - выполняет произвольную команду
|
||||
// cat - записывает строку в файл
|
||||
//
|
||||
// Все строки в описании команды могут содержать в себе ссылки на контекстные переменные. Перед выполнением
|
||||
// Все строки в описании команды могут содержать в себе на переменные. Перед выполнением
|
||||
// реальной команды, переменные заменяются на их реальные значения.
|
||||
//
|
||||
// {{.OutputDir}} - абсолютный путь до выходной директории джоба.
|
||||
|
|
|
@ -7,11 +7,10 @@ import (
|
|||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/build"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
}
|
||||
type Client struct{}
|
||||
|
||||
func NewClient(
|
||||
l *zap.Logger,
|
||||
|
|
9
distbuild/pkg/dist/coordinator.go
vendored
9
distbuild/pkg/dist/coordinator.go
vendored
|
@ -8,12 +8,11 @@ import (
|
|||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/filecache"
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/scheduler"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/filecache"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/scheduler"
|
||||
)
|
||||
|
||||
type Coordinator struct {
|
||||
}
|
||||
type Coordinator struct{}
|
||||
|
||||
var defaultConfig = scheduler.Config{
|
||||
CacheTimeout: time.Millisecond * 10,
|
||||
|
@ -27,8 +26,6 @@ func NewCoordinator(
|
|||
panic("implement me")
|
||||
}
|
||||
|
||||
func (c *Coordinator) Stop() {}
|
||||
|
||||
func (c *Coordinator) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
|
|
@ -7,11 +7,10 @@ import (
|
|||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/build"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
}
|
||||
type Client struct{}
|
||||
|
||||
func NewClient(l *zap.Logger, endpoint string) *Client {
|
||||
panic("implement me")
|
||||
|
|
|
@ -3,9 +3,9 @@ package filecache_test
|
|||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"testing"
|
||||
|
@ -14,8 +14,8 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/zap/zaptest"
|
||||
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/build"
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/filecache"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/filecache"
|
||||
)
|
||||
|
||||
type env struct {
|
||||
|
@ -52,7 +52,7 @@ func TestFileUpload(t *testing.T) {
|
|||
content := bytes.Repeat([]byte("foobar"), 1024*1024)
|
||||
|
||||
tmpFilePath := filepath.Join(env.cache.tmpDir, "foo.txt")
|
||||
require.NoError(t, os.WriteFile(tmpFilePath, content, 0666))
|
||||
require.NoError(t, ioutil.WriteFile(tmpFilePath, content, 0o666))
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
|
@ -65,7 +65,7 @@ func TestFileUpload(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
defer unlock()
|
||||
|
||||
actualContent, err := os.ReadFile(path)
|
||||
actualContent, err := ioutil.ReadFile(path)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, content, actualContent)
|
||||
})
|
||||
|
@ -123,7 +123,7 @@ func TestFileDownload(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
defer unlock()
|
||||
|
||||
content, err := os.ReadFile(path)
|
||||
content, err := ioutil.ReadFile(path)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []byte("foobar"), content)
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/artifact"
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/build"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/artifact"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
@ -2,13 +2,14 @@ package filecache_test
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/build"
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/filecache"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/filecache"
|
||||
)
|
||||
|
||||
type testCache struct {
|
||||
|
@ -17,7 +18,7 @@ type testCache struct {
|
|||
}
|
||||
|
||||
func newCache(t *testing.T) *testCache {
|
||||
tmpDir, err := os.MkdirTemp("", "filecache")
|
||||
tmpDir, err := ioutil.TempDir("", "filecache")
|
||||
require.NoError(t, err)
|
||||
|
||||
c, err := filecache.New(tmpDir)
|
||||
|
@ -35,25 +36,25 @@ func (c *testCache) cleanup() {
|
|||
func TestFileCache(t *testing.T) {
|
||||
cache := newCache(t)
|
||||
|
||||
_, abort, err := cache.Write(build.ID{01})
|
||||
_, abort, err := cache.Write(build.ID{0o1})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, abort())
|
||||
|
||||
_, _, err = cache.Get(build.ID{01})
|
||||
_, _, err = cache.Get(build.ID{0o1})
|
||||
require.Truef(t, errors.Is(err, filecache.ErrNotFound), "%v", err)
|
||||
|
||||
f, _, err := cache.Write(build.ID{02})
|
||||
f, _, err := cache.Write(build.ID{0o2})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = f.Write([]byte("foo bar"))
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, f.Close())
|
||||
|
||||
path, unlock, err := cache.Get(build.ID{02})
|
||||
path, unlock, err := cache.Get(build.ID{0o2})
|
||||
require.NoError(t, err)
|
||||
defer unlock()
|
||||
|
||||
content, err := os.ReadFile(path)
|
||||
content, err := ioutil.ReadFile(path)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []byte("foo bar"), content)
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@ import (
|
|||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/api"
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/build"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/api"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build"
|
||||
)
|
||||
|
||||
var TimeAfter = time.After
|
||||
|
@ -25,8 +25,7 @@ type Config struct {
|
|||
DepsTimeout time.Duration
|
||||
}
|
||||
|
||||
type Scheduler struct {
|
||||
}
|
||||
type Scheduler struct{}
|
||||
|
||||
func NewScheduler(l *zap.Logger, config Config) *Scheduler {
|
||||
panic("implement me")
|
||||
|
@ -47,7 +46,3 @@ func (c *Scheduler) ScheduleJob(job *api.JobSpec) *PendingJob {
|
|||
func (c *Scheduler) PickJob(ctx context.Context, workerID api.WorkerID) *PendingJob {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (c *Scheduler) Stop() {
|
||||
panic("implement me")
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package tarstream_test
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
@ -9,11 +10,11 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/tarstream"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/tarstream"
|
||||
)
|
||||
|
||||
func TestTarStream(t *testing.T) {
|
||||
tmpDir, err := os.MkdirTemp("", "tarstream")
|
||||
tmpDir, err := ioutil.TempDir("", "tarstream")
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Logf("running inside %s", tmpDir)
|
||||
|
@ -21,15 +22,15 @@ func TestTarStream(t *testing.T) {
|
|||
from := filepath.Join(tmpDir, "from")
|
||||
to := filepath.Join(tmpDir, "to")
|
||||
|
||||
require.NoError(t, os.Mkdir(from, 0777))
|
||||
require.NoError(t, os.Mkdir(to, 0777))
|
||||
require.NoError(t, os.Mkdir(from, 0o777))
|
||||
require.NoError(t, os.Mkdir(to, 0o777))
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
require.NoError(t, os.Mkdir(filepath.Join(from, "a"), 0777))
|
||||
require.NoError(t, os.MkdirAll(filepath.Join(from, "b", "c", "d"), 0777))
|
||||
require.NoError(t, os.WriteFile(filepath.Join(from, "a", "x.bin"), []byte("xxx"), 0777))
|
||||
require.NoError(t, os.WriteFile(filepath.Join(from, "b", "c", "y.txt"), []byte("yyy"), 0666))
|
||||
require.NoError(t, os.Mkdir(filepath.Join(from, "a"), 0o777))
|
||||
require.NoError(t, os.MkdirAll(filepath.Join(from, "b", "c", "d"), 0o777))
|
||||
require.NoError(t, ioutil.WriteFile(filepath.Join(from, "a", "x.bin"), []byte("xxx"), 0o777))
|
||||
require.NoError(t, ioutil.WriteFile(filepath.Join(from, "b", "c", "y.txt"), []byte("yyy"), 0o666))
|
||||
|
||||
require.NoError(t, tarstream.Send(from, &buf))
|
||||
|
||||
|
@ -52,15 +53,15 @@ func TestTarStream(t *testing.T) {
|
|||
|
||||
require.Equal(t, mode.String(), st.Mode().String())
|
||||
|
||||
b, err := os.ReadFile(path)
|
||||
b, err := ioutil.ReadFile(path)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, content, b)
|
||||
}
|
||||
|
||||
checkFile(filepath.Join(to, "a", "x.bin"), []byte("xxx"), 0755)
|
||||
checkFile(filepath.Join(to, "b", "c", "y.txt"), []byte("yyy"), 0644)
|
||||
checkFile(filepath.Join(to, "a", "x.bin"), []byte("xxx"), 0o755)
|
||||
checkFile(filepath.Join(to, "b", "c", "y.txt"), []byte("yyy"), 0o644)
|
||||
}
|
||||
|
||||
func init() {
|
||||
unix.Umask(0022)
|
||||
unix.Umask(0o022)
|
||||
}
|
||||
|
|
|
@ -8,13 +8,12 @@ import (
|
|||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/api"
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/artifact"
|
||||
"gitlab.com/slon/shad-go/distbuild/pkg/filecache"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/api"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/artifact"
|
||||
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/filecache"
|
||||
)
|
||||
|
||||
type Worker struct {
|
||||
}
|
||||
type Worker struct{}
|
||||
|
||||
func New(
|
||||
workerID api.WorkerID,
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
✗ go test -v -run=^$ -bench=BenchmarkSprintf -memprofile=mem.out ./varfmt/...
|
||||
goos: linux
|
||||
goarch: amd64
|
||||
pkg: gitlab.com/slon/shad-go/varfmt
|
||||
pkg: gitlab.com/manytask/itmo-go/private/varfmt
|
||||
cpu: Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz
|
||||
BenchmarkSprintf
|
||||
BenchmarkSprintf/small
|
||||
|
@ -17,7 +17,7 @@ BenchmarkSprintf/small_string-8 13282659 84.48 ns/op 16 B/op
|
|||
BenchmarkSprintf/big
|
||||
BenchmarkSprintf/big-8 20089 62372 ns/op 16388 B/op 1 allocs/op
|
||||
PASS
|
||||
ok gitlab.com/slon/shad-go/varfmt 4.363s
|
||||
ok gitlab.com/manytask/itmo-go/private/varfmt 4.363s
|
||||
```
|
||||
|
||||
Сэмплы профайлера будут записаны в бинарный файл `mem.out`.
|
||||
|
@ -53,7 +53,7 @@ Showing nodes accounting for 715.73MB, 99.37% of 720.23MB total
|
|||
Dropped 24 nodes (cum <= 3.60MB)
|
||||
flat flat% sum% cum cum%
|
||||
715.73MB 99.37% 99.37% 716.73MB 99.51% fmt.Sprintf
|
||||
0 0% 99.37% 716.73MB 99.51% gitlab.com/slon/shad-go/varfmt.BenchmarkSprintf.func1
|
||||
0 0% 99.37% 716.73MB 99.51% gitlab.com/manytask/itmo-go/private/varfmt.BenchmarkSprintf.func1
|
||||
0 0% 99.37% 716.73MB 99.51% testing.(*B).launch
|
||||
0 0% 99.37% 716.73MB 99.51% testing.(*B).runN
|
||||
(pprof)
|
||||
|
|
BIN
docs/create-mr-form.png
Normal file
BIN
docs/create-mr-form.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 67 KiB |
BIN
docs/create-mr.png
Normal file
BIN
docs/create-mr.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
BIN
docs/edit-and-fork.png
Normal file
BIN
docs/edit-and-fork.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 128 KiB |
Binary file not shown.
Before Width: | Height: | Size: 173 KiB |
|
@ -63,8 +63,8 @@ import (
|
|||
"flag"
|
||||
"log"
|
||||
|
||||
"gitlab.com/slon/shad-go/gitfame/configs"
|
||||
"gitlab.com/slon/shad-go/gitfame/internal"
|
||||
"gitlab.com/manytask/itmo-go/private/gitfame/configs"
|
||||
"gitlab.com/manytask/itmo-go/private/gitfame/internal"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
|
@ -81,8 +81,8 @@ import (
|
|||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"gitlab.com/slon/shad-go/gitfame/configs"
|
||||
"gitlab.com/slon/shad-go/gitfame/internal"
|
||||
"gitlab.com/manytask/itmo-go/private/gitfame/configs"
|
||||
"gitlab.com/manytask/itmo-go/private/gitfame/internal"
|
||||
)
|
||||
```
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
Low-level programming. unsafe. Package binary. bytes.Buffer. cgo, syscall.
|
||||
|
||||
11. Архитектура GC. Write barrier. Stack growth. GC pause. GOGC. sync.Pool. Шедулер
|
||||
горутин. GOMAXPROCS. Утечка тредов.
|
||||
горутин. GOMACPROCS. Утечка тредов.
|
||||
|
||||
12. Go tooling. pprof. CPU and Memory profiling. Кросс-компиляция. GOOS, GOARCH. CGO_ENABLED=0.
|
||||
Build tags. go modules. godoc. Code generation.
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gitlab.com/slon/shad-go/tools/testtool"
|
||||
"go.uber.org/goleak"
|
||||
)
|
||||
|
||||
|
@ -39,23 +38,6 @@ func TestCall_Simple(t *testing.T) {
|
|||
require.Equal(t, 2, called)
|
||||
}
|
||||
|
||||
func TestCall_NoBusyWait(t *testing.T) {
|
||||
done := make(chan struct{})
|
||||
defer close(done)
|
||||
|
||||
var call Call
|
||||
for i := 0; i < 10; i++ {
|
||||
go func() {
|
||||
_, _ = call.Do(context.Background(), func(ctx context.Context) (interface{}, error) {
|
||||
<-done
|
||||
return nil, nil
|
||||
})
|
||||
}()
|
||||
}
|
||||
|
||||
testtool.VerifyNoBusyGoroutines(t)
|
||||
}
|
||||
|
||||
func TestCall_Dedup(t *testing.T) {
|
||||
defer goleak.VerifyNone(t)
|
||||
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
# excelwriter [reflect]
|
||||
|
||||
В этой задаче нужно обернуть библиотеку для работы с exel'ем в reflect, реализовав интерфейс для построчной записи go объектов в excel
|
||||
```go
|
||||
type Writer interface {
|
||||
WriteRow(r any) error
|
||||
}
|
||||
```
|
||||
r — это либо структура, либо map[smth]any, либо указатель на что-то из этого.
|
||||
|
||||
smth — это либо строка, либо тип реализующий [TextMarshaler](https://pkg.go.dev/encoding#TextMarshaler)
|
||||
|
||||
Как должны сериализовываться поля структур подробно написано в интерфейсе.
|
||||
Всё, что не специфицировано в доке и не проверяется тестами можно делать как сочтёте разумным.
|
||||
|
||||
Также нужно реализовать конструктор
|
||||
```go
|
||||
func New(f *excelize.File) Writer {
|
||||
panic("implement me")
|
||||
}
|
||||
```
|
||||
принимающий на вход инициализированный excel клиент.
|
||||
Можно считать, что excel файл изначально пустой у которого создана 1 страница. Все записи нужно делать в ней.
|
||||
|
||||
Пример использования
|
||||
```go
|
||||
type Movie struct {
|
||||
Title string
|
||||
Year int `xlsx:"release_year"`
|
||||
}
|
||||
|
||||
func StoreMovies() {
|
||||
f := excelize.NewFile()
|
||||
_, _ = f.NewSheet("Sheet1")
|
||||
|
||||
w := excelwriter.New(f)
|
||||
_ = w.WriteRow(&Movie{Title: "Blade Runner", Year: 1982})
|
||||
_ = w.WriteRow(&Movie{Title: "Blade Runner 2049", Year: 2017})
|
||||
_ = w.WriteRow(map[string]any{"title": "Into the wild", "release_year": 2007})
|
||||
|
||||
out, _ := os.Create("/tmp/movie.xlsx")
|
||||
_, _ = f.WriteTo(out)
|
||||
}
|
||||
```
|
||||
|
||||
В результате будет создан excel документ со следующим содержимым
|
||||
```
|
||||
title release_year
|
||||
Blade Runner 1982
|
||||
Blade Runner 2049 2017
|
||||
Into the wild 2007
|
||||
```
|
||||
|
||||
В первой строке хранятся имена колонок, которые вычисляются из имён полей, тэгов и ключей map'ов.
|
||||
|
||||
Разные структуры могут превращаться в разные наборы колонок.
|
||||
Для каждого уникального имени должна быть ровно одна колонка, их нужно "создавать" по мере возникновения.
|
||||
|
||||
Новые ключи каждого конкретного мапа добавляются в колонки в отсортированном порядке, чтобы при перезапусках на одних и тех же данных получались одинаковые excel'ки.
|
||||
|
||||
Помимо имён полей в xlsx тэгах для числовых полей нужно поддержать стили форматирования.
|
||||
Например, в excel нет отдельного типа для дат. Дата — это 15-и значный double (excel тип Number) со стилем форматирования `d-mmm-yy`. Библиотека для работы с excel'ем определяет [наборы популярных стилей](https://pkg.go.dev/github.com/xuri/excelize/v2#File.NewStyle) в виде enum'а `15 d-mmm-yy`. Это число 15 и нужно поддержать в тэге `xslx:"date,numfmt:15"`.
|
||||
|
||||
## Вопросы со звёздочкой
|
||||
1. Как бы вы поддержали в тэгах стили форматирования ячеек (excelize.Fill, excelize.Border ...)?
|
||||
2. Как бы вы поддержали в тэгах кастомные стили форматирования числовых значений, те, что не входят в стандартный набор, например `0,"K"`?
|
||||
3. Как мог бы выглядеть Reader, совместимый с Writer'ом, читающий строчки из excel в Go структуры и map'ы?
|
|
@ -1,48 +0,0 @@
|
|||
//go:build !solution
|
||||
|
||||
package excelwriter
|
||||
|
||||
import (
|
||||
"github.com/xuri/excelize/v2"
|
||||
)
|
||||
|
||||
type Writer interface {
|
||||
// WriteRow appends struct fields or map values to excel sheet.
|
||||
//
|
||||
// Integers and floats are encoded as excel type Number.
|
||||
// Strings are encoded as excel type Text.
|
||||
// Booleans are encoded as excel type Logical.
|
||||
//
|
||||
// Pointer values are encoded as the value pointed to. A nil pointer is skipped.
|
||||
//
|
||||
// Values implementing encoding.TextMarshaler interface are encoded as excel Text.
|
||||
//
|
||||
// Interface values are encoded as the value contained in the interface. A nil interface is skipped.
|
||||
//
|
||||
// Channels and functions are skipped.
|
||||
//
|
||||
// Structs, maps, slices and arrays are marshaled into json and encoded as excel Text.
|
||||
//
|
||||
// Encoding of each struct field can be customized by format string
|
||||
// stored under the "xlsx" key in the field's tag.
|
||||
//
|
||||
// // Field appears in excel under column "my_field".
|
||||
// Field int `xlsx:"my_field"`
|
||||
//
|
||||
// // Field appears in excel under column "my_field" formatted with predeclared style 15 ("d-mmm-yy").
|
||||
// // Only applicable for integers and floats.
|
||||
// Field int `xlsx:"my_field,numfmt:15"`
|
||||
//
|
||||
// // Field is ignored by this package
|
||||
// Field int `xlsx:"-"`
|
||||
//
|
||||
// The first row is reserved for column names.
|
||||
// For structs column name must be either lowercase field name or the name from "xlsx" tag if present.
|
||||
// For maps column name is a map key.
|
||||
// If map key implements encoding.TextMarshaler then column name is string(key.MarshalText()).
|
||||
WriteRow(r any) error
|
||||
}
|
||||
|
||||
func New(f *excelize.File) Writer {
|
||||
panic("implement me")
|
||||
}
|
|
@ -1,268 +0,0 @@
|
|||
package excelwriter_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/xuri/excelize/v2"
|
||||
|
||||
"gitlab.com/slon/shad-go/excelwriter"
|
||||
)
|
||||
|
||||
const Sheet = "Sheet1"
|
||||
|
||||
type MyInt int
|
||||
|
||||
type Basic struct {
|
||||
I int `xlsx:"i"`
|
||||
UI uint `xlsx:"ui"`
|
||||
I16 int16 `xlsx:"i_16"`
|
||||
UI16 uint16 `xlsx:"ui_16"`
|
||||
I32 int32 `xlsx:"i_32"`
|
||||
UI32 uint32 `xlsx:"ui_32"`
|
||||
I64 int64 `xlsx:"i_64"`
|
||||
UI64 uint64 `xlsx:"ui_64"`
|
||||
|
||||
Float float32 `xlsx:"float"`
|
||||
Double float64 `xlsx:"double"`
|
||||
Bool bool `xlsx:"bool"`
|
||||
String string `xlsx:"string"`
|
||||
|
||||
MyInt int `xlsx:"my_int"`
|
||||
}
|
||||
|
||||
type Inner struct {
|
||||
Name string `xlsx:"name"`
|
||||
}
|
||||
|
||||
type TextInt int
|
||||
|
||||
func (i TextInt) MarshalText() ([]byte, error) {
|
||||
return []byte("__" + fmt.Sprint(i) + "__"), nil
|
||||
}
|
||||
|
||||
type TextStruct struct {
|
||||
V string
|
||||
}
|
||||
|
||||
func (s TextStruct) MarshalText() (text []byte, err error) {
|
||||
return []byte("__" + s.V + "__"), nil
|
||||
}
|
||||
|
||||
func TestWriter_basic(t *testing.T) {
|
||||
f := excelize.NewFile()
|
||||
_, err := f.NewSheet(Sheet)
|
||||
require.NoError(t, err)
|
||||
|
||||
w := excelwriter.New(f)
|
||||
|
||||
b := &Basic{
|
||||
I: -1,
|
||||
UI: 1,
|
||||
I16: -16,
|
||||
UI16: 16,
|
||||
I32: -32,
|
||||
UI32: 32,
|
||||
I64: -64,
|
||||
UI64: 64,
|
||||
|
||||
Float: -2.5,
|
||||
Double: 5.5,
|
||||
Bool: true,
|
||||
String: "hello",
|
||||
|
||||
MyInt: 23,
|
||||
}
|
||||
require.NoError(t, w.WriteRow(b))
|
||||
|
||||
storeFile(t, f, "basic")
|
||||
|
||||
rows := readAll(t, f, true)
|
||||
require.Equal(t, []string{"i", "ui", "i_16", "ui_16", "i_32", "ui_32", "i_64", "ui_64", "float", "double", "bool", "string", "my_int"}, rows[0])
|
||||
require.Equal(t, []string{"-1", "1", "-16", "16", "-32", "32", "-64", "64", "-2.5", "5.5", "1", "hello", "23"}, rows[1])
|
||||
}
|
||||
|
||||
func TestWriter_map(t *testing.T) {
|
||||
f := excelize.NewFile()
|
||||
_, err := f.NewSheet(Sheet)
|
||||
require.NoError(t, err)
|
||||
|
||||
w := excelwriter.New(f)
|
||||
|
||||
require.NoError(t, w.WriteRow(map[string]any{
|
||||
"id": 29,
|
||||
"name": "hello",
|
||||
"title": "yo",
|
||||
}))
|
||||
|
||||
require.NoError(t, w.WriteRow(map[string]any{}))
|
||||
|
||||
require.NoError(t, w.WriteRow(map[TextStruct]any{
|
||||
{"id"}: 18,
|
||||
{"name"}: "tm",
|
||||
}))
|
||||
|
||||
storeFile(t, f, "map")
|
||||
|
||||
rows := readAll(t, f, true)
|
||||
require.Equal(t, []string{"id", "name", "title", "__id__", "__name__"}, rows[0])
|
||||
require.Equal(t, []string{"29", "hello", "yo"}, rows[1])
|
||||
require.Equal(t, []string{"", "", "", "18", "tm"}, rows[2])
|
||||
}
|
||||
|
||||
type E struct {
|
||||
ID string `xlsx:"id"`
|
||||
NoTag string
|
||||
Skipped int `xlsx:"-"`
|
||||
private float32 `xlsx:"private"`
|
||||
|
||||
TextInt TextInt `xlsx:"text-int"`
|
||||
TextStruct TextStruct `xlsx:"text-struct"`
|
||||
|
||||
Struct Inner `xlsx:"inner"`
|
||||
StructPtr *Inner `xlsx:"inner-ptr"`
|
||||
|
||||
Slice []int `xlsx:"slice"`
|
||||
Array [2]int `xlsx:"arr"`
|
||||
|
||||
Map map[string]string `xlsx:"map"`
|
||||
TMMap map[TextStruct]string `xlsx:"tm-map"`
|
||||
|
||||
F func() `xlsx:"func"`
|
||||
Ch chan int `xlsx:"chan"`
|
||||
}
|
||||
|
||||
func TestWriter_elaborate(t *testing.T) {
|
||||
f := excelize.NewFile()
|
||||
_, err := f.NewSheet("Sheet1")
|
||||
require.NoError(t, err)
|
||||
|
||||
w := excelwriter.New(f)
|
||||
|
||||
e := &E{
|
||||
ID: "42",
|
||||
NoTag: "no-tag",
|
||||
Skipped: 29,
|
||||
private: 2,
|
||||
TextInt: 77,
|
||||
TextStruct: TextStruct{V: "text-struct"},
|
||||
Struct: Inner{Name: "inner"},
|
||||
StructPtr: &Inner{Name: "inner-ptr"},
|
||||
Slice: []int{1, 2, 3},
|
||||
Array: [2]int{4, 5},
|
||||
Map: map[string]string{"foo": "bar"},
|
||||
TMMap: map[TextStruct]string{{"foo"}: "bar"},
|
||||
F: func() { fmt.Println("hello") },
|
||||
Ch: make(chan int, 10),
|
||||
}
|
||||
require.NoError(t, w.WriteRow(e))
|
||||
|
||||
storeFile(t, f, "elaborate")
|
||||
|
||||
rows := readAll(t, f, true)
|
||||
require.Equal(t, []string{"id", "notag", "private", "text-int", "text-struct", "inner", "inner-ptr", "slice", "arr", "map", "tm-map"}, rows[0])
|
||||
require.Equal(t, []string{"42", "no-tag", "2", "__77__", "__text-struct__", `{"Name":"inner"}`, `{"Name":"inner-ptr"}`, "[1,2,3]", "[4,5]", `{"foo":"bar"}`, `{"__foo__":"bar"}`}, rows[1])
|
||||
}
|
||||
|
||||
func TestWriter_ptr(t *testing.T) {
|
||||
f := excelize.NewFile()
|
||||
_, err := f.NewSheet(Sheet)
|
||||
require.NoError(t, err)
|
||||
|
||||
w := excelwriter.New(f)
|
||||
|
||||
require.NoError(t, w.WriteRow(struct{ Name string }{"foo"}))
|
||||
require.NoError(t, w.WriteRow(&struct{ Name string }{"bar"}))
|
||||
require.NoError(t, w.WriteRow(map[string]string{"name": "baz"}))
|
||||
require.NoError(t, w.WriteRow(&map[string]string{"name": "qux"}))
|
||||
|
||||
storeFile(t, f, "ptr")
|
||||
|
||||
rows := readAll(t, f, true)
|
||||
require.Equal(t, []string{"name"}, rows[0])
|
||||
require.Equal(t, []string{"foo"}, rows[1])
|
||||
require.Equal(t, []string{"bar"}, rows[2])
|
||||
require.Equal(t, []string{"baz"}, rows[3])
|
||||
require.Equal(t, []string{"qux"}, rows[4])
|
||||
}
|
||||
|
||||
func TestWriter_unsupported(t *testing.T) {
|
||||
f := excelize.NewFile()
|
||||
_, err := f.NewSheet("Sheet1")
|
||||
require.NoError(t, err)
|
||||
|
||||
w := excelwriter.New(f)
|
||||
|
||||
require.Error(t, w.WriteRow(2))
|
||||
require.Error(t, w.WriteRow(nil))
|
||||
var b *Basic
|
||||
require.Error(t, w.WriteRow(b))
|
||||
}
|
||||
|
||||
type S struct {
|
||||
P float64 `xlsx:"percent,numfmt:9"`
|
||||
D int `xlsx:"date,numfmt:15"`
|
||||
D2 int `xlsx:",numfmt:15"`
|
||||
T float64 `xlsx:"time,numfmt:22"`
|
||||
Y int `xlsx:"jpy,numfmt:194"`
|
||||
}
|
||||
|
||||
func TestWriter_style(t *testing.T) {
|
||||
f := excelize.NewFile()
|
||||
_, err := f.NewSheet("Sheet1")
|
||||
require.NoError(t, err)
|
||||
|
||||
w := excelwriter.New(f)
|
||||
|
||||
s := &S{
|
||||
P: 0.5,
|
||||
D: 100,
|
||||
D2: 100,
|
||||
T: 100.5,
|
||||
Y: 200,
|
||||
}
|
||||
require.NoError(t, w.WriteRow(s))
|
||||
|
||||
storeFile(t, f, "style")
|
||||
|
||||
rows := readAll(t, f, false)
|
||||
require.Equal(t, []string{"percent", "date", "d2", "time", "jpy"}, rows[0])
|
||||
require.Equal(t, []string{"50%", "9-Apr-00", "9-Apr-00", "4/9/00 12:00", "¥200.00"}, rows[1])
|
||||
}
|
||||
|
||||
func readAll(t *testing.T, f *excelize.File, raw bool) [][]string {
|
||||
t.Helper()
|
||||
|
||||
var out [][]string
|
||||
|
||||
rows, err := f.Rows(Sheet)
|
||||
require.NoError(t, err)
|
||||
|
||||
var opts []excelize.Options
|
||||
if raw {
|
||||
opts = append(opts, excelize.Options{RawCellValue: true})
|
||||
}
|
||||
|
||||
for i := 1; rows.Next(); i++ {
|
||||
row, err := rows.Columns(opts...)
|
||||
require.NoError(t, err)
|
||||
|
||||
out = append(out, row)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func storeFile(t *testing.T, f *excelize.File, prefix string) {
|
||||
t.Helper()
|
||||
|
||||
out, err := os.CreateTemp("/tmp", prefix+"-*.xlsx")
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = f.WriteTo(out)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Logf("stored file in %s", out.Name())
|
||||
}
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
@ -11,7 +12,7 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gitlab.com/slon/shad-go/tools/testtool"
|
||||
"gitlab.com/manytask/itmo-go/private/tools/testtool"
|
||||
)
|
||||
|
||||
func TestMerge(t *testing.T) {
|
||||
|
@ -32,32 +33,6 @@ func TestMerge(t *testing.T) {
|
|||
1
|
||||
1
|
||||
2
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "with empty lines",
|
||||
in: []string{`
|
||||
0`, `
|
||||
|
||||
1
|
||||
1
|
||||
1`, `
|
||||
|
||||
|
||||
0
|
||||
2`},
|
||||
out: `
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
0
|
||||
0
|
||||
1
|
||||
1
|
||||
1
|
||||
2
|
||||
`,
|
||||
},
|
||||
} {
|
||||
|
@ -90,7 +65,7 @@ func TestSort(t *testing.T) {
|
|||
testDir := path.Join("./testdata", "sort")
|
||||
|
||||
readTestCase := func(dir string) (in []string, out string) {
|
||||
files, err := os.ReadDir(dir)
|
||||
files, err := ioutil.ReadDir(dir)
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, f := range files {
|
||||
|
@ -109,7 +84,7 @@ func TestSort(t *testing.T) {
|
|||
testCaseDir := path.Join(testDir, d)
|
||||
|
||||
t.Run(d, func(t *testing.T) {
|
||||
tmpDir, err := os.MkdirTemp("", fmt.Sprintf("sort%s-", d))
|
||||
tmpDir, err := ioutil.TempDir("", fmt.Sprintf("sort%s-", d))
|
||||
require.NoError(t, err)
|
||||
defer func() { _ = os.RemoveAll(tmpDir) }()
|
||||
|
||||
|
@ -120,7 +95,7 @@ func TestSort(t *testing.T) {
|
|||
w := bufio.NewWriter(&buf)
|
||||
require.NoError(t, Sort(w, in...))
|
||||
|
||||
expected, err := os.ReadFile(out)
|
||||
expected, err := ioutil.ReadFile(out)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, w.Flush())
|
||||
|
@ -132,7 +107,7 @@ func TestSort(t *testing.T) {
|
|||
func listDirs(t *testing.T, dir string) []string {
|
||||
t.Helper()
|
||||
|
||||
files, err := os.ReadDir(dir)
|
||||
files, err := ioutil.ReadDir(dir)
|
||||
require.NoError(t, err)
|
||||
|
||||
var dirs []string
|
||||
|
@ -159,11 +134,11 @@ func copyFiles(t *testing.T, in []string, dir string) []string {
|
|||
func copyFile(t *testing.T, f, dir string) string {
|
||||
t.Helper()
|
||||
|
||||
data, err := os.ReadFile(f)
|
||||
data, err := ioutil.ReadFile(f)
|
||||
require.NoError(t, err)
|
||||
|
||||
dst := path.Join(dir, path.Base(f))
|
||||
err = os.WriteFile(dst, data, 0644)
|
||||
err = ioutil.WriteFile(dst, data, 0o644)
|
||||
require.NoError(t, err)
|
||||
|
||||
return dst
|
||||
|
|
BIN
externalsort/testdata/.gitattributes
vendored
BIN
externalsort/testdata/.gitattributes
vendored
Binary file not shown.
|
@ -2,61 +2,6 @@
|
|||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
type HTTPGetResult struct {
|
||||
Success bool
|
||||
Body string
|
||||
Elapsed time.Duration
|
||||
Size int
|
||||
URL string
|
||||
Error error
|
||||
}
|
||||
|
||||
func (result HTTPGetResult) String() string {
|
||||
if result.Success {
|
||||
return fmt.Sprintf("%v\t%v\t%v", result.Elapsed, result.Size, result.URL)
|
||||
} else {
|
||||
return result.Error.Error()
|
||||
}
|
||||
}
|
||||
|
||||
func GetHTTPBody(url string, ch chan HTTPGetResult) {
|
||||
startTime := time.Now()
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
ch <- HTTPGetResult{Success: false, Error: err}
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
ch <- HTTPGetResult{Success: false, Error: err}
|
||||
return
|
||||
}
|
||||
ch <- HTTPGetResult{
|
||||
Success: true,
|
||||
Body: string(data),
|
||||
Elapsed: time.Since(startTime),
|
||||
Size: len(data),
|
||||
URL: url,
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
startTime := time.Now()
|
||||
urls, ch := os.Args[1:], make(chan HTTPGetResult)
|
||||
for _, url := range urls {
|
||||
go GetHTTPBody(url, ch)
|
||||
}
|
||||
for i := 0; i < len(urls); i++ {
|
||||
fmt.Println(<-ch)
|
||||
}
|
||||
fmt.Println(time.Since(startTime), "elapsed")
|
||||
|
||||
}
|
||||
|
|
|
@ -17,10 +17,10 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gitlab.com/slon/shad-go/tools/testtool"
|
||||
"gitlab.com/manytask/itmo-go/private/tools/testtool"
|
||||
)
|
||||
|
||||
const fetchallImportPath = "gitlab.com/slon/shad-go/fetchall"
|
||||
const fetchallImportPath = "gitlab.com/manytask/itmo-go/private/fetchall"
|
||||
|
||||
var binCache testtool.BinCache
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package fileleak_test
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"syscall"
|
||||
|
@ -10,8 +11,8 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gitlab.com/slon/shad-go/fileleak"
|
||||
"gitlab.com/slon/shad-go/tools/testtool"
|
||||
"gitlab.com/manytask/itmo-go/private/fileleak"
|
||||
"gitlab.com/manytask/itmo-go/private/tools/testtool"
|
||||
)
|
||||
|
||||
type fakeT struct {
|
||||
|
@ -74,7 +75,7 @@ func TestFileLeak_ReopenFile(t *testing.T) {
|
|||
checkLeak(t, true, func() {
|
||||
_ = f.Close()
|
||||
|
||||
ff, err := os.CreateTemp("", "")
|
||||
ff, err := ioutil.TempFile("", "")
|
||||
require.NoError(t, err)
|
||||
f = ff
|
||||
})
|
||||
|
@ -128,7 +129,6 @@ func TestFileLeak_DupLeak(t *testing.T) {
|
|||
var err error
|
||||
fd, err = syscall.Dup(1)
|
||||
require.NoError(t, err)
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
FROM golang:1.22
|
||||
|
||||
RUN ["mkdir", "-p", "/build"]
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN ["go", "build", "-tags", "solution", "-o", "/firegod", "./firegod"]
|
||||
|
||||
ENTRYPOINT [ "/firegod", "-http=0.0.0.0:8080" ]
|
|
@ -1,55 +0,0 @@
|
|||
# firegod
|
||||
|
||||
В этой задаче вам нужно научиться пользоваться связкой prometheus+grafana для отладки собственного кода.
|
||||
|
||||
Вам дан код сервиса. Нужно добавить в него метрики, и потом используя графану с помощью графиков ответить на ряд вопросов.
|
||||
|
||||
В этой задаче нет автоматической проверки. Чтобы получить оценку, нужно закоммитить свои ответы вместе со скриншотами в репозиторий, и поменять значение константы в `Solved` в файле `main.go` на `true`.
|
||||
|
||||
## Окружение
|
||||
|
||||
В файле `docker-compose.yaml` описан тестовый стенд.
|
||||
|
||||
- `prometheus` - контейнер с прометеем, который собирает метрики и выполняет запросы над ними.
|
||||
- `grafana` - контейнер с графаной, дающий удобный `Web UI` для работы с прометеем.
|
||||
- `my_service` - 5 реплик вашего сервиса.
|
||||
|
||||
Чтобы запустит тестовый стенд, выполните команду `docker compose up --build`. Чтобы перезапустить стенд, остановите `docker compose` нажав `Ctrl+C` и перезапустите команду.
|
||||
|
||||
После запуска стенда, проверьте что:
|
||||
- [targets](http://localhost:9090/targets) показывает правильный список процессов. Один прометей в состоянии `up` и 5 копий вашего сервиса в состоянии `down` с ошибкой `server returned HTTP status 404 Not Found`.
|
||||
- [grafana](http://localhost:3000/explore) пускает вас в интерфейс с логином `admin` и паролем `grafana`, а на странице Explore видно какие-то метрики (например `up`).
|
||||
|
||||
## Сервис
|
||||
|
||||
В пакете `dontlook` находится код сервиса. В него смотреть *нельзя*.
|
||||
|
||||
Вам нужно дописать код сбора и экспорта метрик в файл `main.go`.
|
||||
|
||||
1. Сделайте так, чтобы метрики экспортировались по запросу `GET /metrics`.
|
||||
2. Включите экспорт метрик go рантайма и процесса (если они уже не экспортируются по дефолту).
|
||||
3. Добавьте middleware записывающий метрики из http хендлеров.
|
||||
|
||||
## Вопросы
|
||||
|
||||
1. Сколько процессов каких сервисов подключено к прометею? (пример)
|
||||
|
||||
**Ответ**: 1 прометей и 5 моих сервисов.
|
||||
|
||||
![](screenshots/up.png)
|
||||
|
||||
2. Какой процесс постоянно перезапускается?
|
||||
|
||||
3. В каком процесс есть утечка файловых дескрипторов?
|
||||
|
||||
4. В каком процессе есть утечка памяти?
|
||||
|
||||
5. В каком процессе утекают горутины?
|
||||
|
||||
6. Какой хендлер пятисотит больше всех?
|
||||
|
||||
7. Сколько всего запросов в секунду приходит в сервис?
|
||||
|
||||
8. Какой хендлер медленнее всех отвечает, если сравнивать по 90-ой перцентиле времени ответа?
|
||||
|
||||
9. Какой хендлер генерирует больше всего трафика?
|
|
@ -1,62 +0,0 @@
|
|||
services:
|
||||
prometheus:
|
||||
image: prom/prometheus
|
||||
container_name: prometheus
|
||||
command:
|
||||
- '--config.file=/etc/prometheus/prometheus.yml'
|
||||
ports:
|
||||
- 9090:9090
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ./prometheus:/etc/prometheus
|
||||
|
||||
grafana:
|
||||
image: grafana/grafana
|
||||
container_name: grafana
|
||||
ports:
|
||||
- 3000:3000
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- GF_SECURITY_ADMIN_USER=admin
|
||||
- GF_SECURITY_ADMIN_PASSWORD=grafana
|
||||
volumes:
|
||||
- ./grafana:/etc/grafana/provisioning/datasources
|
||||
|
||||
my-service-0: &service
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: firegod/Dockerfile
|
||||
restart: always
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.5'
|
||||
memory: 100M
|
||||
|
||||
container_name: my-service-0
|
||||
environment:
|
||||
- REPLICA=0
|
||||
|
||||
my-service-1:
|
||||
<<: *service
|
||||
container_name: my-service-1
|
||||
environment:
|
||||
- REPLICA=1
|
||||
|
||||
my-service-2:
|
||||
<<: *service
|
||||
container_name: my-service-2
|
||||
environment:
|
||||
- REPLICA=2
|
||||
|
||||
my-service-3:
|
||||
<<: *service
|
||||
container_name: my-service-3
|
||||
environment:
|
||||
- REPLICA=3
|
||||
|
||||
my-service-4:
|
||||
<<: *service
|
||||
container_name: my-service-4
|
||||
environment:
|
||||
- REPLICA=4
|
|
@ -1,111 +0,0 @@
|
|||
package dontlook
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
func NewService(r chi.Router) {
|
||||
replica := os.Getenv("REPLICA")
|
||||
|
||||
switch replica {
|
||||
case "0":
|
||||
go func() {
|
||||
for {
|
||||
go func() { select {} }()
|
||||
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
}
|
||||
}()
|
||||
|
||||
case "2":
|
||||
go func() {
|
||||
var buf []string
|
||||
for i := 0; true; i++ {
|
||||
buf = append(buf, strings.Repeat("f", 1<<20))
|
||||
_ = buf
|
||||
|
||||
time.Sleep(time.Millisecond * 100 * time.Duration(i))
|
||||
}
|
||||
}()
|
||||
|
||||
case "3":
|
||||
go func() {
|
||||
for {
|
||||
_, _ = net.Dial("tcp", "localhost:8080")
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
}
|
||||
}()
|
||||
|
||||
case "4":
|
||||
go func() {
|
||||
time.Sleep(time.Second * 15)
|
||||
os.Exit(1)
|
||||
}()
|
||||
}
|
||||
|
||||
runClient := func(getUrl func() string) {
|
||||
for {
|
||||
go func() {
|
||||
rsp, err := http.Get(fmt.Sprintf("http://localhost:8080%s", getUrl()))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
_, _ = io.ReadAll(rsp.Body)
|
||||
_ = rsp.Body.Close()
|
||||
}()
|
||||
|
||||
time.Sleep(time.Microsecond * 100)
|
||||
}
|
||||
}
|
||||
|
||||
r.Get("/apple", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(200)
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
_, _ = w.Write([]byte("OK"))
|
||||
})
|
||||
go runClient(func() string { return "/apple" })
|
||||
|
||||
r.Get("/banana", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(200)
|
||||
_, _ = w.Write(bytes.Repeat([]byte("f"), 1<<10))
|
||||
|
||||
if replica == "0" {
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
})
|
||||
go runClient(func() string { return "/banana" })
|
||||
|
||||
var k atomic.Int32
|
||||
r.Get("/orange", func(w http.ResponseWriter, r *http.Request) {
|
||||
if k.Add(1)%100 == 0 {
|
||||
w.WriteHeader(500)
|
||||
} else {
|
||||
w.WriteHeader(200)
|
||||
}
|
||||
|
||||
})
|
||||
go runClient(func() string { return "/orange" })
|
||||
|
||||
r.Get("/kiwi/{id}", func(w http.ResponseWriter, r *http.Request) {
|
||||
if replica == "3" {
|
||||
w.WriteHeader(200)
|
||||
} else {
|
||||
w.WriteHeader(500)
|
||||
}
|
||||
})
|
||||
|
||||
var i atomic.Int32
|
||||
go runClient(func() string { return fmt.Sprintf("/kiwi/%d", i.Add(1)) })
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
apiVersion: 1
|
||||
|
||||
datasources:
|
||||
- name: Prometheus
|
||||
type: prometheus
|
||||
url: http://prometheus:9090
|
||||
isDefault: true
|
||||
access: proxy
|
||||
editable: true
|
|
@ -1,24 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"gitlab.com/slon/shad-go/firegod/dontlook"
|
||||
)
|
||||
|
||||
var Solved = false
|
||||
|
||||
var flagPort = flag.String("http", "", "")
|
||||
|
||||
var router = chi.NewRouter()
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
dontlook.NewService(router)
|
||||
|
||||
log.Fatal(http.ListenAndServe(*flagPort, router))
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestFiregod(t *testing.T) {
|
||||
require.True(t, Solved)
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
global:
|
||||
scrape_interval: 5s
|
||||
evaluation_interval: 5s
|
||||
scrape_timeout: 1s
|
||||
|
||||
alerting:
|
||||
alertmanagers:
|
||||
- static_configs:
|
||||
- targets: []
|
||||
scheme: http
|
||||
timeout: 1s
|
||||
api_version: v1
|
||||
|
||||
scrape_configs:
|
||||
- job_name: prometheus
|
||||
honor_timestamps: true
|
||||
scrape_interval: 5s
|
||||
scrape_timeout: 1s
|
||||
metrics_path: /metrics
|
||||
scheme: http
|
||||
static_configs:
|
||||
- targets:
|
||||
- localhost:9090
|
||||
- job_name: my-service
|
||||
honor_timestamps: true
|
||||
scrape_interval: 5s
|
||||
scrape_timeout: 1s
|
||||
metrics_path: /metrics
|
||||
scheme: http
|
||||
static_configs:
|
||||
- targets:
|
||||
- my-service-0:8080
|
||||
- my-service-1:8080
|
||||
- my-service-2:8080
|
||||
- my-service-3:8080
|
||||
- my-service-4:8080
|
Binary file not shown.
Before Width: | Height: | Size: 145 KiB |
|
@ -51,6 +51,6 @@ Forbidden
|
|||
## Resources
|
||||
|
||||
* project layout: https://github.com/golang-standards/project-layout
|
||||
* reverse proxy: https://pkg.go.dev/net/http/httputil#ReverseProxy
|
||||
* reverse proxy: https://en.wikipedia.org/wiki/Reverse_proxy
|
||||
* yaml: https://gopkg.in/yaml.v2
|
||||
* regexp: https://golang.org/pkg/regexp/
|
||||
|
|
|
@ -3,6 +3,7 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
|
@ -14,10 +15,10 @@ import (
|
|||
"github.com/go-resty/resty/v2"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gitlab.com/slon/shad-go/tools/testtool"
|
||||
"gitlab.com/manytask/itmo-go/private/tools/testtool"
|
||||
)
|
||||
|
||||
const importPath = "gitlab.com/slon/shad-go/firewall/cmd/firewall"
|
||||
const importPath = "gitlab.com/manytask/itmo-go/private/firewall/cmd/firewall"
|
||||
|
||||
var binCache testtool.BinCache
|
||||
|
||||
|
@ -35,7 +36,7 @@ func storeConfig(t *testing.T, conf string) (filename string, cleanup func()) {
|
|||
t.Helper()
|
||||
|
||||
filename = path.Join(os.TempDir(), testtool.RandomName()+".yaml")
|
||||
err := os.WriteFile(filename, []byte(conf), 0777)
|
||||
err := ioutil.WriteFile(filename, []byte(conf), 0o777)
|
||||
require.NoError(t, err)
|
||||
|
||||
cleanup = func() { _ = os.Remove(filename) }
|
||||
|
|
|
@ -79,18 +79,6 @@ Stack:
|
|||
а `definition` состоит из известных слов и чисел, разделённых пробелами.
|
||||
Слова можно переопределять.
|
||||
|
||||
При реализации механизма определений обратите внимание на юнит-тест
|
||||
|
||||
```go
|
||||
{
|
||||
description: "no redefinition",
|
||||
input: []string{": foo 5 ;", ": bar foo ;", ": foo 6 ;", "bar foo"},
|
||||
expected: []int{5, 6},
|
||||
},
|
||||
```
|
||||
|
||||
То есть семантика слова вычисляется непосредственно при определении и не меняется при переопределении "зависимостей".
|
||||
|
||||
### Проверка решения
|
||||
|
||||
Для запуска тестов нужно выполнить следующую команду:
|
||||
|
|
160
forth/eval.go
160
forth/eval.go
|
@ -2,173 +2,17 @@
|
|||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Evaluator struct {
|
||||
stack []int
|
||||
words map[string](func() error)
|
||||
}
|
||||
|
||||
func (e *Evaluator) push(n int) {
|
||||
e.stack = append(e.stack, n)
|
||||
}
|
||||
|
||||
func (e *Evaluator) pop() (int, error) {
|
||||
size := len(e.stack)
|
||||
if size == 0 {
|
||||
return 0, errors.New("nothing to pop")
|
||||
}
|
||||
n := e.stack[size-1]
|
||||
e.stack = e.stack[:size-1]
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (e *Evaluator) popTwo() (int, int, error) {
|
||||
if len(e.stack) < 2 {
|
||||
return 0, 0, errors.New("not enough elements on stack")
|
||||
}
|
||||
second, _ := e.pop()
|
||||
first, _ := e.pop()
|
||||
return first, second, nil
|
||||
}
|
||||
|
||||
// Used to initialzie arithemtic operations in words map
|
||||
func (e *Evaluator) arithmeticOp(op func(int, int) int) func() error {
|
||||
return func() error {
|
||||
a, b, err := e.popTwo()
|
||||
if err != nil {
|
||||
return errors.New("not enough elements on stack")
|
||||
}
|
||||
e.push(op(a, b))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Evaluator) initBasicWords() {
|
||||
e.words["+"] = e.arithmeticOp(func(a, b int) int { return a + b })
|
||||
e.words["-"] = e.arithmeticOp(func(a, b int) int { return a - b })
|
||||
e.words["*"] = e.arithmeticOp(func(a, b int) int { return a * b })
|
||||
e.words["/"] = func() error {
|
||||
a, b, err := e.popTwo()
|
||||
if err != nil {
|
||||
return errors.New("not enough elements on stack")
|
||||
}
|
||||
if b == 0 {
|
||||
return errors.New("division by zero")
|
||||
}
|
||||
e.push(a / b)
|
||||
return nil
|
||||
}
|
||||
e.words["dup"] = func() error {
|
||||
size := len(e.stack)
|
||||
if size == 0 {
|
||||
return errors.New("not enough elements on stack")
|
||||
}
|
||||
e.stack = append(e.stack, e.stack[size-1])
|
||||
return nil
|
||||
}
|
||||
e.words["over"] = func() error {
|
||||
size := len(e.stack)
|
||||
if size < 2 {
|
||||
return errors.New("not enough elements on stack")
|
||||
}
|
||||
e.stack = append(e.stack, e.stack[size-2])
|
||||
return nil
|
||||
}
|
||||
e.words["drop"] = func() error {
|
||||
_, err := e.pop()
|
||||
return err
|
||||
}
|
||||
e.words["swap"] = func() error {
|
||||
size := len(e.stack)
|
||||
if size < 2 {
|
||||
return errors.New("not enough elements on stack")
|
||||
}
|
||||
e.stack[size-1], e.stack[size-2] = e.stack[size-2], e.stack[size-1]
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Evaluator) getFunc(word string) (func() error, error) {
|
||||
call, found := e.words[word]
|
||||
if found {
|
||||
return call, nil
|
||||
}
|
||||
num, err := strconv.Atoi(word)
|
||||
if err != nil {
|
||||
return nil, errors.New("word is not numerical or is not defined")
|
||||
}
|
||||
call = func() error {
|
||||
e.push(num)
|
||||
return nil
|
||||
}
|
||||
return call, nil
|
||||
}
|
||||
|
||||
func (e *Evaluator) defineWord(word string, def string) error {
|
||||
_, err := strconv.Atoi(word)
|
||||
if err == nil {
|
||||
return errors.New("word definition must not be numeric")
|
||||
}
|
||||
definitionWords := strings.Fields(def)
|
||||
callChain := make([](func() error), len(definitionWords))
|
||||
for i, w := range definitionWords {
|
||||
call, err := e.getFunc(w)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
callChain[i] = call
|
||||
}
|
||||
e.words[word] = func() error {
|
||||
for _, call := range callChain {
|
||||
err := call()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewEvaluator creates evaluator.
|
||||
func NewEvaluator() *Evaluator {
|
||||
eval := &Evaluator{make([]int, 0), make(map[string](func() error))}
|
||||
eval.initBasicWords()
|
||||
return eval
|
||||
return &Evaluator{}
|
||||
}
|
||||
|
||||
// Process evaluates sequence of words or definition.
|
||||
//
|
||||
// Returns resulting stack state and an error.
|
||||
func (e *Evaluator) Process(row string) ([]int, error) {
|
||||
row = strings.ToLower(row)
|
||||
if strings.HasPrefix(row, ":") && strings.HasSuffix(row, ";") {
|
||||
row = strings.Trim(row, " :;")
|
||||
wordAndDef := strings.SplitN(row, " ", 2)
|
||||
if len(wordAndDef) < 2 {
|
||||
return e.stack, errors.New("couldn't define a new word - incorrect syntax")
|
||||
}
|
||||
word, def := wordAndDef[0], wordAndDef[1]
|
||||
err := e.defineWord(word, def)
|
||||
if err != nil {
|
||||
return e.stack, err
|
||||
}
|
||||
return e.stack, nil
|
||||
}
|
||||
for _, word := range strings.Fields(row) {
|
||||
call, err := e.getFunc(word)
|
||||
if err != nil {
|
||||
return e.stack, err
|
||||
}
|
||||
err = call()
|
||||
if err != nil {
|
||||
return e.stack, err
|
||||
}
|
||||
}
|
||||
return e.stack, nil
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
@ -99,11 +99,6 @@ var testCases = []testCase{
|
|||
input: []string{"2 4 * 3 /"},
|
||||
expected: []int{2},
|
||||
},
|
||||
{
|
||||
description: "add non-empty stack",
|
||||
input: []string{"1 2 3 +"},
|
||||
expected: []int{1, 5},
|
||||
},
|
||||
{
|
||||
description: "dup",
|
||||
input: []string{"1 dup"},
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/goleak"
|
||||
|
||||
"gitlab.com/slon/shad-go/genericsum"
|
||||
"gitlab.com/manytask/itmo-go/private/genericsum"
|
||||
)
|
||||
|
||||
func TestMin(t *testing.T) {
|
||||
|
@ -184,42 +184,11 @@ func TestIsHermitianMatrix(t *testing.T) {
|
|||
{7, 2, 12},
|
||||
{9, 12, 19},
|
||||
}))
|
||||
assert.True(t, genericsum.IsHermitianMatrix([][]int8{
|
||||
{-1, 7, 9},
|
||||
{7, -2, 12},
|
||||
{9, 12, -19},
|
||||
}))
|
||||
assert.True(t, genericsum.IsHermitianMatrix([][]uint16{
|
||||
{1, 7, 9},
|
||||
{7, 2, 12},
|
||||
{9, 12, 19},
|
||||
}))
|
||||
assert.False(t, genericsum.IsHermitianMatrix([][]int{
|
||||
{1, 12, 8},
|
||||
{3, 4, 7},
|
||||
{8, 7, 11},
|
||||
}))
|
||||
assert.False(t, genericsum.IsHermitianMatrix([][]int32{
|
||||
{1, 112, 8},
|
||||
{-3, 4, -7},
|
||||
{8, 7, 11},
|
||||
}))
|
||||
assert.False(t, genericsum.IsHermitianMatrix([][]uint64{
|
||||
{1, 12, 8},
|
||||
{3, 4, 7},
|
||||
{8, 7, 11},
|
||||
}))
|
||||
|
||||
assert.True(t, genericsum.IsHermitianMatrix([][]float32{
|
||||
{1.0, 7.0, 9.0},
|
||||
{7.0, 2.0, 12.0},
|
||||
{9.0, 12.0, 19.0},
|
||||
}))
|
||||
assert.False(t, genericsum.IsHermitianMatrix([][]float32{
|
||||
{1.0, 12.0, 8.0},
|
||||
{3.0, 4.0, 7.0},
|
||||
{8.0, 7.0, 11.0},
|
||||
}))
|
||||
assert.True(t, genericsum.IsHermitianMatrix([][]complex64{
|
||||
{1, 3 + 2i},
|
||||
{3 - 2i, 4},
|
||||
|
|
|
@ -175,11 +175,6 @@ export PATH=$GOPATH/bin:$PATH
|
|||
|
||||
После этого `gitfame` будет доступен всюду.
|
||||
|
||||
В реализации вы можете использовать сторонние библиотеки, которые уже доступны в нашем [`go.mod`](../go.mod). Менять `go.mod` нельзя.
|
||||
|
||||
Весь репозиторий курса - это один go модуль с одним go.mod файлом в корне. Корню репозитория соответствует импорт путь `gitlab.com/slon/shad-go`. Если вы создадите пакет в директории `gitfame/internal/git`, то импортировать его нужно будет по пути `gitlab.com/slon/shad-go/gitfame/internal/git`.
|
||||
|
||||
|
||||
### Code review comments
|
||||
|
||||
Прочитайте и исправьте [распространённые ошибки](../docs/gitfame_review_comments.md).
|
||||
|
|
|
@ -2,6 +2,7 @@ package integration
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
|
@ -13,10 +14,10 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"gitlab.com/slon/shad-go/tools/testtool"
|
||||
"gitlab.com/manytask/itmo-go/private/tools/testtool"
|
||||
)
|
||||
|
||||
const importPath = "gitlab.com/slon/shad-go/gitfame/cmd/gitfame"
|
||||
const importPath = "gitlab.com/manytask/itmo-go/private/gitfame/cmd/gitfame"
|
||||
|
||||
var binCache testtool.BinCache
|
||||
|
||||
|
@ -42,7 +43,7 @@ func TestGitFame(t *testing.T) {
|
|||
tc := ReadTestCase(t, filepath.Join(testsDir, dir))
|
||||
|
||||
t.Run(dir+"/"+tc.Name, func(t *testing.T) {
|
||||
dir, err := os.MkdirTemp("", "gitfame-")
|
||||
dir, err := ioutil.TempDir("", "gitfame-")
|
||||
require.NoError(t, err)
|
||||
defer func() { _ = os.RemoveAll(dir) }()
|
||||
|
||||
|
@ -74,7 +75,7 @@ func TestGitFame(t *testing.T) {
|
|||
func ListTestDirs(t *testing.T, path string) []string {
|
||||
t.Helper()
|
||||
|
||||
files, err := os.ReadDir(path)
|
||||
files, err := ioutil.ReadDir(path)
|
||||
require.NoError(t, err)
|
||||
|
||||
var names []string
|
||||
|
@ -108,7 +109,7 @@ func ReadTestCase(t *testing.T, path string) *TestCase {
|
|||
|
||||
desc := ReadTestDescription(t, path)
|
||||
|
||||
expected, err := os.ReadFile(filepath.Join(path, "expected.out"))
|
||||
expected, err := ioutil.ReadFile(filepath.Join(path, "expected.out"))
|
||||
require.NoError(t, err)
|
||||
|
||||
return &TestCase{TestDescription: desc, Expected: expected}
|
||||
|
@ -125,7 +126,7 @@ type TestDescription struct {
|
|||
func ReadTestDescription(t *testing.T, path string) *TestDescription {
|
||||
t.Helper()
|
||||
|
||||
data, err := os.ReadFile(filepath.Join(path, "description.yaml"))
|
||||
data, err := ioutil.ReadFile(filepath.Join(path, "description.yaml"))
|
||||
require.NoError(t, err)
|
||||
|
||||
var desc TestDescription
|
||||
|
|
84
go.mod
84
go.mod
|
@ -1,80 +1,66 @@
|
|||
module gitlab.com/slon/shad-go
|
||||
module gitlab.com/manytask/itmo-go/private
|
||||
|
||||
go 1.22.0
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/felixge/httpsnoop v1.0.3
|
||||
github.com/go-chi/chi/v5 v5.0.8
|
||||
github.com/go-git/go-git/v5 v5.11.0
|
||||
github.com/go-redis/redis/v8 v8.11.5
|
||||
github.com/go-resty/resty/v2 v2.1.0
|
||||
github.com/gofrs/uuid v3.3.0+incompatible
|
||||
github.com/golang/mock v1.6.0
|
||||
github.com/google/btree v1.1.2
|
||||
github.com/google/go-cmp v0.6.0
|
||||
github.com/golang/mock v1.4.1
|
||||
github.com/google/go-cmp v0.5.9
|
||||
github.com/gorilla/handlers v1.4.2
|
||||
github.com/gorilla/mux v1.7.4
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/jackc/pgx/v5 v5.5.3
|
||||
github.com/jonboulle/clockwork v0.4.0
|
||||
github.com/jackc/pgx/v4 v4.6.0
|
||||
github.com/jonboulle/clockwork v0.1.0
|
||||
github.com/spf13/cobra v1.1.3
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.8.4
|
||||
go.uber.org/goleak v1.3.0
|
||||
go.uber.org/zap v1.26.0
|
||||
github.com/stretchr/testify v1.8.2
|
||||
go.uber.org/goleak v1.0.0
|
||||
go.uber.org/zap v1.14.0
|
||||
golang.org/x/exp v0.0.0-20230321023759-10a507213a29
|
||||
golang.org/x/perf v0.0.0-20191209155426-36b577b0eb03
|
||||
golang.org/x/sync v0.6.0
|
||||
golang.org/x/sys v0.17.0
|
||||
golang.org/x/tools v0.18.0
|
||||
golang.org/x/sync v0.1.0
|
||||
golang.org/x/sys v0.7.0
|
||||
golang.org/x/tools v0.7.0
|
||||
google.golang.org/grpc v1.54.0
|
||||
google.golang.org/protobuf v1.33.0
|
||||
google.golang.org/protobuf v1.30.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
require (
|
||||
dario.cat/mergo v1.0.0 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/BurntSushi/toml v0.3.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/cloudflare/circl v1.3.3 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||
github.com/go-git/go-billy/v5 v5.5.0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
|
||||
github.com/jackc/pgconn v1.5.0 // indirect
|
||||
github.com/jackc/pgio v1.0.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.1 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||
github.com/pjbgf/sha1cd v0.3.0 // indirect
|
||||
github.com/jackc/pgproto3/v2 v2.0.1 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8 // indirect
|
||||
github.com/jackc/pgtype v1.3.0 // indirect
|
||||
github.com/kr/pretty v0.3.0 // indirect
|
||||
github.com/lib/pq v1.10.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_golang v1.19.1 // indirect
|
||||
github.com/prometheus/client_model v0.5.0 // indirect
|
||||
github.com/prometheus/common v0.48.0 // indirect
|
||||
github.com/prometheus/procfs v0.12.0 // indirect
|
||||
github.com/richardlehane/mscfb v1.0.4 // indirect
|
||||
github.com/richardlehane/msoleps v1.0.3 // indirect
|
||||
github.com/sergi/go-diff v1.1.0 // indirect
|
||||
github.com/skeema/knownhosts v1.2.1 // indirect
|
||||
github.com/rogpeppe/go-internal v1.8.0 // indirect
|
||||
github.com/stretchr/objx v0.5.0 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 // indirect
|
||||
github.com/xuri/excelize/v2 v2.8.1 // indirect
|
||||
github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 // indirect
|
||||
go.uber.org/multierr v1.10.0 // indirect
|
||||
golang.org/x/crypto v0.19.0 // indirect
|
||||
golang.org/x/mod v0.15.0 // indirect
|
||||
golang.org/x/net v0.21.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
go.uber.org/atomic v1.5.0 // indirect
|
||||
go.uber.org/multierr v1.3.0 // indirect
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee // indirect
|
||||
golang.org/x/crypto v0.5.0 // indirect
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de // indirect
|
||||
golang.org/x/mod v0.9.0 // indirect
|
||||
golang.org/x/net v0.9.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
honnef.co/go/tools v0.0.1-2019.2.3 // indirect
|
||||
)
|
||||
|
|
301
go.sum
301
go.sum
|
@ -11,50 +11,38 @@ cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7
|
|||
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
|
||||
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20190129172621-c8b1d7a94ddf/go.mod h1:aJ4qN3TfrelA6NZ6AXsXRfmEVaYin3EDbSPJrKS8OXo=
|
||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
||||
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
|
||||
github.com/aclements/go-gg v0.0.0-20170118225347-6dbb4e4fefb0/go.mod h1:55qNq4vcpkIuHowELi5C8e+1yUHtoLoOUR9QU5j7Tes=
|
||||
github.com/aclements/go-moremath v0.0.0-20161014184102-0ff62e0875ff/go.mod h1:idZL3yvz4kzx1dsBOAC+oYv6L92P1oFEhUXUB1A/lwQ=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
|
||||
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
|
||||
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
|
||||
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
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=
|
||||
|
@ -62,29 +50,14 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
|
|||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU=
|
||||
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
|
||||
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
|
||||
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
|
||||
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
|
||||
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
|
||||
github.com/go-chi/chi/v5 v5.0.8 h1:lD+NLqFcAi1ovnVZpsnObHGW4xb4J8lNmoYVfECH1Y0=
|
||||
github.com/go-chi/chi/v5 v5.0.8/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
|
||||
github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
|
||||
github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
||||
github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4=
|
||||
github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
|
@ -95,19 +68,18 @@ github.com/go-resty/resty/v2 v2.1.0 h1:Z6IefCpUMfnvItVJaJXWv/pMiiD11So35QgwEELsl
|
|||
github.com/go-resty/resty/v2 v2.1.0/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gofrs/uuid v3.3.0+incompatible h1:8K4tyRfvU1CYPgJsveYFQMhpFd/wXNM7iK6rR7UHz84=
|
||||
github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||
github.com/golang/mock v1.4.1 h1:ocYkMQY5RrXTYgXl7ICpV0IXwlEQGwKIsery4gyXa1U=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
|
@ -121,13 +93,11 @@ github.com/gonum/lapack v0.0.0-20181123203213-e4cdc5a0bff9/go.mod h1:XA3DeT6rxh2
|
|||
github.com/gonum/matrix v0.0.0-20181209220409-c518dec07be9/go.mod h1:0EXg4mc1CNP0HCqCz+K4ts155PXIlUywf0wqN+GfPZw=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
|
||||
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
|
@ -167,39 +137,78 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p
|
|||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
||||
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
|
||||
github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
|
||||
github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
|
||||
github.com/jackc/pgconn v1.5.0 h1:oFSOilzIZkyg787M1fEmyMfOUUvwj0daqYMfaWwNL4o=
|
||||
github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI=
|
||||
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
|
||||
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
|
||||
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2 h1:JVX6jT/XfzNqIjye4717ITLaNwV9mWbJx0dLCpcRzdA=
|
||||
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.5.3 h1:Ces6/M3wbDXYpM8JyyPD57ivTtJACFZJd885pdIaV2s=
|
||||
github.com/jackc/pgx/v5 v5.5.3/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
|
||||
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
|
||||
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||
github.com/jackc/pgproto3/v2 v2.0.1 h1:Rdjp4NFjwHnEslx2b66FfCI2S0LhO4itac3hXz6WX9M=
|
||||
github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8 h1:Q3tB+ExeflWUW7AFcAhXqk40s9mnNYLk1nOkKNZ5GnU=
|
||||
github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
|
||||
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
|
||||
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
|
||||
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
|
||||
github.com/jackc/pgtype v1.3.0 h1:l8JvKrby3RI7Kg3bYEeU9TA4vqC38QDpFCfcrC7KuN0=
|
||||
github.com/jackc/pgtype v1.3.0/go.mod h1:b0JqxHvPmljG+HQ5IsvQ0yqeSi4nGcDTVjFoiLDb0Ik=
|
||||
github.com/jackc/pgx v3.6.2+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
|
||||
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
|
||||
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
|
||||
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
|
||||
github.com/jackc/pgx/v4 v4.6.0 h1:Fh0O9GdlG4gYpjpwOqjdEodJUQM9jzN3Hdv7PN0xmm0=
|
||||
github.com/jackc/pgx/v4 v4.6.0/go.mod h1:vPh43ZzxijXUVJ+t/EmXBtFmbFVO72cuneCT9oAlxAg=
|
||||
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
|
||||
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
|
||||
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.10.0 h1:Zx5DJFEYQXio93kgXnQ09fXNiUKsqv4OUEu2UtGcB1E=
|
||||
github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||
github.com/mattn/go-sqlite3 v0.0.0-20161215041557-2d44decb4941/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
|
@ -213,20 +222,14 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
|
|||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
|
||||
github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
|
||||
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
|
||||
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
|
@ -236,40 +239,31 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
|||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
|
||||
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
|
||||
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE=
|
||||
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
|
||||
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
|
||||
github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
|
||||
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
|
||||
github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM=
|
||||
github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ=
|
||||
github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
|
@ -285,54 +279,50 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
|
|||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 h1:Chd9DkqERQQuHpXjR/HSV1jLZA6uaoiwwH3vSuF3IW0=
|
||||
github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
|
||||
github.com/xuri/excelize/v2 v2.8.1 h1:pZLMEwK8ep+CLIUWpWmvW8IWE/yxqG0I1xcN6cVMGuQ=
|
||||
github.com/xuri/excelize/v2 v2.8.1/go.mod h1:oli1E4C3Pa5RXg1TBXn4ENCXDV5JUMlBluUhG7c+CEE=
|
||||
github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 h1:qhbILQo1K3mphbwKh1vNm4oGezE1eF9fQWmNiIpSfI4=
|
||||
github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/goleak v1.0.0 h1:qsup4IcBdlmsnGfqyLl4Ntn3C2XCCuKAE7DwHpScyUo=
|
||||
go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
||||
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/multierr v1.3.0 h1:sFPn2GLc3poCkfrpIXGhBD2X0CMIo4Q/zSULXrj/+uc=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
|
||||
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
|
||||
go.uber.org/zap v1.14.0 h1:/pduUoebOeeJzTDFuoMgC6nRkiasr1sBCIEorly7m4o=
|
||||
go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
|
||||
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
|
@ -348,16 +338,14 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk
|
|||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
|
||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
|
||||
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -373,15 +361,9 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn
|
|||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/oauth2 v0.0.0-20170207211851-4464e7848382/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
@ -393,11 +375,8 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
|
|||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
@ -405,46 +384,25 @@ golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
@ -456,23 +414,26 @@ golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3
|
|||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ=
|
||||
golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg=
|
||||
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
|
||||
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.0.0-20170206182103-3d017632ea10/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
|
@ -505,21 +466,16 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
|
|||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
@ -532,5 +488,8 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
|
|
|
@ -5,7 +5,7 @@ package gossip
|
|||
import (
|
||||
"time"
|
||||
|
||||
"gitlab.com/slon/shad-go/gossip/meshpb"
|
||||
"gitlab.com/manytask/itmo-go/private/gossip/meshpb"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"gitlab.com/slon/shad-go/gossip"
|
||||
"gitlab.com/slon/shad-go/gossip/meshpb"
|
||||
"gitlab.com/manytask/itmo-go/private/gossip"
|
||||
"gitlab.com/manytask/itmo-go/private/gossip/meshpb"
|
||||
"go.uber.org/goleak"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
syntax = "proto3";
|
||||
|
||||
option go_package = "gitlab.com/slon/shad-go/gossip/meshpb";
|
||||
option go_package = "gitlab.com/manytask/itmo-go/private/gossip/meshpb";
|
||||
|
||||
// PeerMeta is arbitrary message that is propagated with peer gossip.
|
||||
message PeerMeta {
|
||||
|
|
|
@ -6,14 +6,14 @@
|
|||
```
|
||||
goos: linux
|
||||
goarch: amd64
|
||||
pkg: gitlab.com/slon/shad-go/gzep
|
||||
pkg: gitlab.com/manytask/itmo-go/private/gzep
|
||||
cpu: Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz
|
||||
BenchmarkEncodeSimple
|
||||
BenchmarkEncodeSimple-8 7047 176628 ns/op 813872 B/op 17 allocs/op
|
||||
BenchmarkEncode
|
||||
BenchmarkEncode-8 41706 32616 ns/op 19 B/op 0 allocs/op
|
||||
PASS
|
||||
ok gitlab.com/slon/shad-go/gzep 3.625s
|
||||
ok gitlab.com/manytask/itmo-go/private/gzep 3.625s
|
||||
```
|
||||
|
||||
### С чего начать?
|
||||
|
|
|
@ -9,8 +9,8 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gitlab.com/slon/shad-go/gzep"
|
||||
"gitlab.com/slon/shad-go/tools/testtool"
|
||||
"gitlab.com/manytask/itmo-go/private/gzep"
|
||||
"gitlab.com/manytask/itmo-go/private/tools/testtool"
|
||||
)
|
||||
|
||||
func BenchmarkEncode(b *testing.B) {
|
||||
|
@ -47,7 +47,6 @@ func TestEncode_RoundTrip(t *testing.T) {
|
|||
require.NoError(t, err, tc.in)
|
||||
require.Equal(t, tc.in, string(out))
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,39 +2,6 @@
|
|||
|
||||
package hogwarts
|
||||
|
||||
import (
|
||||
"log"
|
||||
"slices"
|
||||
)
|
||||
|
||||
func singleCourseList(
|
||||
course string, prereqs map[string][]string, list []string, traversed []string,
|
||||
) []string {
|
||||
if slices.Contains(traversed, course) {
|
||||
log.Panic("Recursive prereqs, aborting...")
|
||||
}
|
||||
traversed = append(traversed, course)
|
||||
for _, prereqCourse := range prereqs[course] {
|
||||
if !slices.Contains(list, prereqCourse) {
|
||||
i := slices.Index(list, course)
|
||||
if i == -1 {
|
||||
list = append(list, prereqCourse)
|
||||
} else {
|
||||
list = slices.Insert(list, i, prereqCourse)
|
||||
}
|
||||
}
|
||||
list = singleCourseList(prereqCourse, prereqs, list, traversed)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
func GetCourseList(prereqs map[string][]string) []string {
|
||||
list := make([]string, 0)
|
||||
for course := range prereqs {
|
||||
if !slices.Contains(list, course) {
|
||||
list = append(list, course)
|
||||
}
|
||||
list = singleCourseList(course, prereqs, list, []string{})
|
||||
}
|
||||
return list
|
||||
return []string{}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
package hotelbusiness
|
||||
|
||||
import "math"
|
||||
|
||||
type Guest struct {
|
||||
CheckInDate int
|
||||
CheckOutDate int
|
||||
|
@ -15,30 +13,5 @@ type Load struct {
|
|||
}
|
||||
|
||||
func ComputeLoad(guests []Guest) []Load {
|
||||
if len(guests) == 0 {
|
||||
return []Load{}
|
||||
}
|
||||
minDate, maxDate := math.MaxInt, math.MinInt
|
||||
loadsNoEmptyDays := make(map[int]int)
|
||||
for _, guest := range guests {
|
||||
if guest.CheckInDate < minDate {
|
||||
minDate = guest.CheckInDate
|
||||
}
|
||||
if guest.CheckOutDate > maxDate {
|
||||
maxDate = guest.CheckOutDate
|
||||
}
|
||||
for i := guest.CheckInDate; i < guest.CheckOutDate; i++ {
|
||||
loadsNoEmptyDays[i]++
|
||||
}
|
||||
}
|
||||
loads, prevGuestCount := make([]Load, 0), 0
|
||||
for i := minDate; i <= maxDate; i++ {
|
||||
guestCount := loadsNoEmptyDays[i]
|
||||
if prevGuestCount == guestCount {
|
||||
continue
|
||||
}
|
||||
loads = append(loads, Load{i, guestCount})
|
||||
prevGuestCount = guestCount
|
||||
}
|
||||
return loads
|
||||
return []Load{}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"gitlab.com/slon/shad-go/illegal"
|
||||
"gitlab.com/slon/shad-go/illegal/internal"
|
||||
"gitlab.com/manytask/itmo-go/private/illegal"
|
||||
"gitlab.com/manytask/itmo-go/private/illegal/internal"
|
||||
)
|
||||
|
||||
func TestIllegalField(t *testing.T) {
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"gitlab.com/slon/shad-go/illegal"
|
||||
"gitlab.com/manytask/itmo-go/private/illegal"
|
||||
)
|
||||
|
||||
func TestStringFromBytes(t *testing.T) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"fmt"
|
||||
"log"
|
||||
|
||||
"gitlab.com/slon/shad-go/iprange"
|
||||
"gitlab.com/manytask/itmo-go/private/iprange"
|
||||
)
|
||||
|
||||
func ExampleParseList() {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
В обычном `sync.Mutex` лок всего один. В один момент времени этот лок может находиться
|
||||
у одной горутины. В нашем примитиве локов может быть сколько угодно. Каждый лок мы идентифицируем
|
||||
ключом - строкой. Каждая горутина приходит к нам со списком ключей и хочет захватить сразу
|
||||
ключём - строкой. Каждая горутина приходит к нам со списком ключей и хочет захватить сразу
|
||||
все локи из этого списка. (Наша аналогия с `sync.Mutex` вовсе не значит, что нужно использовать
|
||||
`sync.Mutex` в реализации. Лучше использовать каналы, чтобы проще было реализовать отмену.)
|
||||
|
||||
|
|
|
@ -1,19 +1,14 @@
|
|||
package keylock_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"slices"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/goleak"
|
||||
|
||||
"gitlab.com/slon/shad-go/keylock"
|
||||
"gitlab.com/slon/shad-go/tools/testtool"
|
||||
"gitlab.com/manytask/itmo-go/private/keylock"
|
||||
)
|
||||
|
||||
func timeout(d time.Duration) <-chan struct{} {
|
||||
|
@ -62,21 +57,6 @@ func TestKeyLock_Progress(t *testing.T) {
|
|||
unlock1()
|
||||
}
|
||||
|
||||
func TestKeyLock_NoBusyWait(t *testing.T) {
|
||||
defer goleak.VerifyNone(t)
|
||||
l := keylock.New()
|
||||
|
||||
_, unlock0 := l.LockKeys([]string{"a", "b"}, nil)
|
||||
defer unlock0()
|
||||
|
||||
go func() {
|
||||
_, unlock := l.LockKeys([]string{"b", "c"}, nil)
|
||||
unlock()
|
||||
}()
|
||||
|
||||
testtool.VerifyNoBusyGoroutines(t)
|
||||
}
|
||||
|
||||
func TestKeyLock_DeadlockFree(t *testing.T) {
|
||||
const N = 10000
|
||||
|
||||
|
@ -136,7 +116,7 @@ func TestKeyLock_SingleKeyStress(t *testing.T) {
|
|||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
for j := 0; j < N; j++ {
|
||||
for i := 0; i < N; i++ {
|
||||
cancelled, unlock := l.LockKeys([]string{"a"}, timeout(time.Millisecond))
|
||||
if !cancelled {
|
||||
unlock()
|
||||
|
@ -147,58 +127,3 @@ func TestKeyLock_SingleKeyStress(t *testing.T) {
|
|||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestKeyLock_MutualExclusionStress(t *testing.T) {
|
||||
const (
|
||||
N = 1000
|
||||
G = 100
|
||||
M = 15
|
||||
K = 3
|
||||
)
|
||||
|
||||
defer goleak.VerifyNone(t)
|
||||
|
||||
locked := map[string]bool{}
|
||||
var mu sync.Mutex
|
||||
|
||||
l := keylock.New()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(G)
|
||||
|
||||
for i := 0; i < G; i++ {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
for j := 0; j < N; j++ {
|
||||
keys := []string{}
|
||||
for k := 0; k < K; k++ {
|
||||
keys = append(keys, fmt.Sprint(rand.Intn(N)))
|
||||
}
|
||||
|
||||
slices.Sort(keys)
|
||||
keys = slices.Compact(keys)
|
||||
|
||||
_, unlock := l.LockKeys(keys, nil)
|
||||
mu.Lock()
|
||||
for _, key := range keys {
|
||||
assert.False(t, locked[key])
|
||||
locked[key] = true
|
||||
}
|
||||
mu.Unlock()
|
||||
|
||||
time.Sleep(time.Millisecond)
|
||||
|
||||
mu.Lock()
|
||||
for _, key := range keys {
|
||||
locked[key] = false
|
||||
}
|
||||
mu.Unlock()
|
||||
|
||||
unlock()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
|
|
@ -3,9 +3,23 @@ package keylock
|
|||
import (
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkMutex_Baseline(b *testing.B) {
|
||||
var mu sync.Mutex
|
||||
|
||||
b.ReportAllocs()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
mu.Lock()
|
||||
_ = 0
|
||||
mu.Unlock()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkKeyLock_SingleKey(b *testing.B) {
|
||||
l := New()
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
@ -29,7 +30,7 @@ func fetch(url string, ch chan<- string) {
|
|||
}
|
||||
defer resp.Body.Close() // don't leak resources
|
||||
|
||||
nbytes, err := io.Copy(io.Discard, resp.Body)
|
||||
nbytes, err := io.Copy(ioutil.Discard, resp.Body)
|
||||
if err != nil {
|
||||
ch <- fmt.Sprintf("while reading %s: %v", url, err)
|
||||
return
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
|
||||
* Ссылки
|
||||
|
||||
.link https://github.com/slon/shad-go Репозиторий
|
||||
.link https://wiki.yandex.ru/shad/groups/2018/Semester4/GoLang/ Вики страница
|
||||
.link https://gitlab.com/manytask/itmo-go/private Репозиторий
|
||||
.link https://t.me/joinchat/BjrYSxdPJGtJdd1pae08Zg Чат курса в телеграме
|
||||
[[https://p.go.manytask.org]] - эти слайды.
|
||||
|
||||
|
@ -20,7 +21,7 @@
|
|||
- 12+ занятий
|
||||
- Семинарские задания после каждой лекции. *Дедлайн*10*дней.*
|
||||
- 4 _больших_ домашних задания. *Дедлайн*3*недели.*
|
||||
- Критерий оценки: *В*LMS* (>N домашек и >X% за семинары).
|
||||
- Критерий оценки: *TODO*.
|
||||
|
||||
* Hello world
|
||||
|
||||
|
@ -36,25 +37,12 @@ Systems
|
|||
|
||||
Language
|
||||
|
||||
* История
|
||||
|
||||
- 2009 go public announcement
|
||||
- 2012 go 1.0
|
||||
- 2008 github launch
|
||||
- 2011 C++11
|
||||
- 2011 pip initial release
|
||||
- 2010 npm first release
|
||||
- 2009 nodejs first release
|
||||
- 2008 python3
|
||||
- 2006 rust project started
|
||||
- 2015 rust 1.0
|
||||
|
||||
* Современный мир
|
||||
|
||||
- Море библиотек. Большие деревья зависимостей.
|
||||
: Нам нужен язык, который будет помогать контролировать сложность at large.
|
||||
- Архитектура построена вокруг сервисов, которые общаются по сети.
|
||||
: Скорее вам придётся писать stateless сервис. Stateful сервисы общаются с базой данных по сети.
|
||||
: Скорее вам придётся писать stateless сервис. Statefull сервисы общаются с базой данных по сети.
|
||||
- Многоядерные процессоры даже в телефонах.
|
||||
|
||||
* Скорость разработки
|
||||
|
@ -161,8 +149,6 @@ Language
|
|||
var s = ""
|
||||
var s string = ""
|
||||
|
||||
.link https://go.dev/blog/declaration-syntax Почему тип пишется после названия переменной
|
||||
|
||||
* uniq
|
||||
|
||||
.play -edit uniq/uniq.go
|
||||
|
@ -244,7 +230,7 @@ Pointers
|
|||
|
||||
var s string
|
||||
p := &s
|
||||
s2 := *p
|
||||
s2 = *p
|
||||
|
||||
var p Point
|
||||
p.X = 1
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue