From 6253d4178c4abdec328f9e8bc6b58650eb38ef88 Mon Sep 17 00:00:00 2001 From: Eduardo Cuducos <4732915+cuducos@users.noreply.github.com> Date: Sat, 17 Aug 2024 13:54:21 -0400 Subject: [PATCH] Updates download for Federal Revenue files Fix #234 --- .github/workflows/gofmt.yaml | 2 +- .github/workflows/golint.yaml | 4 +- .github/workflows/tests.yaml | 2 +- Dockerfile | 2 +- docker-compose.yml | 4 +- docs/instalacao.md | 2 +- download/download.go | 13 ++-- download/download_test.go | 18 +++-- download/downloader_test.go | 2 +- download/federal_revenue.go | 111 ++++++++++++++++++++--------- download/federal_revenue_test.go | 102 +++++++++++++++----------- download/national_treasure.go | 2 +- download/national_treasure_test.go | 4 +- go.mod | 31 ++++---- go.sum | 56 +++++++-------- testdata/2024-08.html | 51 +++++++++++++ testdata/dados_abertos_cnpj.html | 17 +++++ 17 files changed, 278 insertions(+), 145 deletions(-) create mode 100644 testdata/2024-08.html create mode 100644 testdata/dados_abertos_cnpj.html diff --git a/.github/workflows/gofmt.yaml b/.github/workflows/gofmt.yaml index ebf1d201..4c0ab254 100644 --- a/.github/workflows/gofmt.yaml +++ b/.github/workflows/gofmt.yaml @@ -7,5 +7,5 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-go@v4 with: - go-version: "1.21" + go-version: "1.22" - run: if [ "$(gofmt -s -l . | wc -l)" -gt 0 ]; then exit 1; fi diff --git a/.github/workflows/golint.yaml b/.github/workflows/golint.yaml index 4e868048..18a7c2f4 100644 --- a/.github/workflows/golint.yaml +++ b/.github/workflows/golint.yaml @@ -7,6 +7,6 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-go@v4 with: - go-version: "1.21.x" - - run: "go install honnef.co/go/tools/cmd/staticcheck@2023.1.6" + go-version: "1.22.x" + - run: "go install honnef.co/go/tools/cmd/staticcheck@v0.5.1" - run: "staticcheck ./..." diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 08767748..fc9e6b5b 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -8,7 +8,7 @@ jobs: fail-fast: false matrix: os: [windows-latest, ubuntu-latest] - go: [1.20.x, 1.21.x] + go: [1.21.x, 1.22.x] runs-on: ${{ matrix.os }} diff --git a/Dockerfile b/Dockerfile index 8d46f3cd..1bf7fd08 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.21-bookworm AS build +FROM golang:1.22-bookworm AS build WORKDIR /minha-receita COPY go.mod . COPY go.sum . diff --git a/docker-compose.yml b/docker-compose.yml index 3e12d7af..6d0069ad 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,7 +10,7 @@ services: - ./data:/mnt/data postgres: - image: postgres:14-alpine + image: postgres:16.1-bookworm ports: - 5432:5432 volumes: @@ -26,7 +26,7 @@ services: retries: 5 postgres_test: - image: postgres:14-alpine + image: postgres:16.1-bookworm ports: - 5555:5432 environment: *credentials diff --git a/docs/instalacao.md b/docs/instalacao.md index a298207f..0b06251b 100644 --- a/docs/instalacao.md +++ b/docs/instalacao.md @@ -35,7 +35,7 @@ $ docker pull ghcr.io/cuducos/minha-receita:main #### A partir do código fonte -* [Go](https://golang.org/) versão 1.21 +* [Go](https://golang.org/) versão 1.22 Depois de clonar o repositório, baixe as dependências e compile a aplicação para um diretório incluído no `PATH`, por exemplo: diff --git a/download/download.go b/download/download.go index 0a0e1527..516d5fcd 100644 --- a/download/download.go +++ b/download/download.go @@ -11,10 +11,10 @@ import ( "time" ) -type getURLsHandler func(url, dir string) ([]string, error) +type getURLsHandler func(url string) ([]string, error) func getURLs(url string, handler getURLsHandler, dir string, skip bool) ([]string, error) { - urls, err := handler(url, dir) + urls, err := handler(url) if err != nil { return nil, fmt.Errorf("error getting urls: %w", err) } @@ -72,6 +72,9 @@ func Download(dir string, timeout time.Duration, skip, restart bool, parallel in if err := download(dir, urls, parallel, retries, chunkSize, timeout, restart); err != nil { return fmt.Errorf("error downloading files from the federal revenue: %w", err) } + if err := federalRevenueGetMetadata(federalRevenueMetadataURL, dir); err != nil { + return fmt.Errorf("error getting metadata: %w", err) + } return nil } @@ -90,7 +93,7 @@ func DownloadFromMirror(mirror string, dir string, timeout time.Duration, skip, // URLs shows the URLs to be downloaded. func URLs(dir string, skip bool) error { urls := []string{federalRevenueURL, nationalTreasureBaseURL} - handlers := []getURLsHandler{federalRevenueGetURLsNoUpdatedAt, nationalTreasureGetURLs} + handlers := []getURLsHandler{federalRevenueGetURLs, nationalTreasureGetURLs} var out []string for idx := range urls { u, err := getURLs(urls[idx], handlers[idx], dir, skip) @@ -106,7 +109,7 @@ func URLs(dir string, skip bool) error { // UpdatedAt shows the updated at of the files to be downloaded. func UpdatedAt() error { - u, err := fetchUpdatedAt(federalRevenueURL) + u, err := fetchUpdatedAt(federalRevenueMetadataURL) if err != nil { return fmt.Errorf("error getting updated at: %w", err) } @@ -116,7 +119,7 @@ func UpdatedAt() error { // HasUpdate checks if there is an update available. func HasUpdate(dir string) error { - h, err := hasUpdate(federalRevenueURL, dir) + h, err := hasUpdate(federalRevenueMetadataURL, dir) if err != nil { return fmt.Errorf("error getting updated at: %w", err) } diff --git a/download/download_test.go b/download/download_test.go index 344ac0a4..3c5b4d95 100644 --- a/download/download_test.go +++ b/download/download_test.go @@ -12,12 +12,12 @@ import ( func TestGetURLs(t *testing.T) { for _, tc := range []struct { name string - fixture string + fixture []string handler getURLsHandler expected int }{ - {"federal revenue", "cadastro-nacional-de-pessoa-juridica-cnpj.json", federalRevenueGetURLs, 37}, - {"national treasure", "national-treasure.json", nationalTreasureGetURLs, 1}, + {"federal revenue", []string{"dados_abertos_cnpj.html", "2024-08.html"}, federalRevenueGetURLs, 37}, + {"national treasure", []string{"national-treasure.json"}, nationalTreasureGetURLs, 1}, } { ts := httpTestServer(t, tc.fixture) defer ts.Close() @@ -47,16 +47,22 @@ func loadFixture(t *testing.T, n string) (*os.File, int64) { return f, i.Size() } -func httpTestServer(t *testing.T, n string) *httptest.Server { +func httpTestServer(t *testing.T, cs []string) *httptest.Server { + if len(cs) == 0 { + panic("no content provided to the test server") + } + var c int return httptest.NewServer( http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + idx := c % len(cs) + c += 1 if r.Method == http.MethodHead { - f, s := loadFixture(t, n) + f, s := loadFixture(t, cs[idx]) defer f.Close() w.Header().Add("Content-Length", fmt.Sprint(s)) return } - http.ServeFile(w, r, path.Join("..", "testdata", n)) + http.ServeFile(w, r, path.Join("..", "testdata", cs[idx])) })) } diff --git a/download/downloader_test.go b/download/downloader_test.go index f4c0590f..10eab195 100644 --- a/download/downloader_test.go +++ b/download/downloader_test.go @@ -8,7 +8,7 @@ import ( ) func TestDownloader(t *testing.T) { - ts := httpTestServer(t, "cadastro-nacional-de-pessoa-juridica-cnpj.json") + ts := httpTestServer(t, []string{"cadastro-nacional-de-pessoa-juridica-cnpj.json"}) defer ts.Close() f, s := loadFixture(t, "cadastro-nacional-de-pessoa-juridica-cnpj.json") diff --git a/download/federal_revenue.go b/download/federal_revenue.go index 14f8664f..3f4a02d4 100644 --- a/download/federal_revenue.go +++ b/download/federal_revenue.go @@ -9,24 +9,84 @@ import ( "os" "path/filepath" "regexp" + "slices" "strings" "time" ) const ( + userAgent = "Minha Receita/0.0.1 (minhareceita.org)" + // FederalRevenueUpdatedAt is a file that contains the date the data was // extracted by the Federal Revenue FederalRevenueUpdatedAt = "updated_at.txt" - federalRevenueURL = "https://dados.gov.br/api/publico/conjuntos-dados/cadastro-nacional-da-pessoa-juridica---cnpj" - federalRevenueFormat = "zip+csv" + // Metadata source + federalRevenueMetadataURL = "https://dados.gov.br/api/publico/conjuntos-dados/cadastro-nacional-da-pessoa-juridica---cnpj" federalRevenueDateFormat = "02/01/2006 15:04:05" federalRevenueDateFormatNotes = "02/01/2006" - userAgent = "Minha Receita/0.0.1 (minhareceita.org)" + // Zipped CSV source + federalRevenueURL = "https://dadosabertos.rfb.gov.br/CNPJ/dados_abertos_cnpj" ) var datePattern = regexp.MustCompile(`Data da última extração:? +(?P\d{2}/\d{2}/\d{4})`) +var yearMonthPattern = regexp.MustCompile(`href="(\d{4}-\d{2}/)"`) +var filePattern = regexp.MustCompile(`href="(\w+\d?\.zip)"`) + +func httpGet(url string) (string, error) { + c := http.Client{} + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return "", fmt.Errorf("error creating request %s: %w", url, err) + } + req.Header.Set("User-Agent", userAgent) + r, err := c.Do(req) + if err != nil { + return "", fmt.Errorf("error getting %s: %w", url, err) + } + defer r.Body.Close() + if r.StatusCode != http.StatusOK { + return "", fmt.Errorf("%s responded with %s", url, r.Status) + } + b, err := io.ReadAll(r.Body) + if err != nil { + return "", fmt.Errorf("could not read %s response body: %w", url, err) + } + return string(b), nil +} + +func federalRevenueGetMostRecentURL(url string) (string, error) { + b, err := httpGet(url) + if err != nil { + return "", fmt.Errorf("error getting %s: %w", url, err) + } + var bs []string + for _, m := range yearMonthPattern.FindAllStringSubmatch(b, -1) { + bs = append(bs, m[1]) + } + slices.Sort(bs) + if len(bs) == 0 { + return "", fmt.Errorf("no batches found in %s", url) + } + return url + "/" + bs[len(bs)-1], nil +} + +func federalRevenueGetURLs(url string) ([]string, error) { + u, err := federalRevenueGetMostRecentURL(url) + if err != nil { + return nil, fmt.Errorf("could not read %s response body: %w", url, err) + } + b, err := httpGet(u) + if err != nil { + return nil, fmt.Errorf("error getting %s: %w", url, err) + } + var urls []string + for _, m := range filePattern.FindAllStringSubmatch(b, -1) { + urls = append(urls, u+m[1]) + } + return urls, nil +} type federalRevenueTime struct{ Time time.Time } @@ -44,18 +104,18 @@ func (t *federalRevenueTime) UnmarshalJSON(b []byte) error { return nil } -type federalRevenueResource struct { +type federalRevenueMetadataResource struct { Format string `json:"format"` URL string `json:"url"` MetadataModified federalRevenueTime `json:"metadata_modified"` } -type federalRevenueResponse struct { - Resources []federalRevenueResource `json:"resources"` - Notes string `json:"notes"` +type federalRevenueMetadata struct { + Resources []federalRevenueMetadataResource `json:"resources"` + Notes string `json:"notes"` } -func (r *federalRevenueResponse) updatedAt() (t time.Time) { +func (r *federalRevenueMetadata) updatedAt() (t time.Time) { m := datePattern.FindStringSubmatch(r.Notes) if len(m) == 2 { t, err := time.Parse(federalRevenueDateFormatNotes, m[1]) @@ -72,7 +132,7 @@ func (r *federalRevenueResponse) updatedAt() (t time.Time) { return t } -func newFederalRevenueResponse(url string) (*federalRevenueResponse, error) { +func newFederalRevenueMetadata(url string) (*federalRevenueMetadata, error) { c := http.Client{} req, err := http.NewRequest("GET", url, nil) if err != nil { @@ -91,42 +151,27 @@ func newFederalRevenueResponse(url string) (*federalRevenueResponse, error) { if err != nil { return nil, fmt.Errorf("could not read %s response body: %w", url, err) } - var data federalRevenueResponse + var data federalRevenueMetadata if err := json.Unmarshal(b, &data); err != nil { return nil, fmt.Errorf("could not unmarshal %s json response: %w", url, err) } return &data, nil } -func federalRevenueGetURLsBase(url, dir string, updatedAt bool) ([]string, error) { - data, err := newFederalRevenueResponse(url) +func federalRevenueGetMetadata(url, dir string) error { + data, err := newFederalRevenueMetadata(url) if err != nil { - return nil, fmt.Errorf("error getting federal revenue data: %w", err) - } - var u []string - for _, v := range data.Resources { - if v.Format == federalRevenueFormat { - u = append(u, v.URL) - } - } - if updatedAt { - if err := saveUpdatedAt(dir, data.updatedAt()); err != nil { - return nil, fmt.Errorf("could not save the update at date: %w", err) - } + return fmt.Errorf("error getting federal revenue data: %w", err) } - return u, nil -} - -func federalRevenueGetURLs(url, dir string) ([]string, error) { - return federalRevenueGetURLsBase(url, dir, true) -} + if err := saveUpdatedAt(dir, data.updatedAt()); err != nil { + return fmt.Errorf("could not save the update at date: %w", err) -func federalRevenueGetURLsNoUpdatedAt(url, dir string) ([]string, error) { - return federalRevenueGetURLsBase(url, dir, false) + } + return nil } func fetchUpdatedAt(url string) (string, error) { - data, err := newFederalRevenueResponse(url) + data, err := newFederalRevenueMetadata(url) if err != nil { return "", fmt.Errorf("error getting federal revenue data: %w", err) } diff --git a/download/federal_revenue_test.go b/download/federal_revenue_test.go index deb6d99f..76f92c22 100644 --- a/download/federal_revenue_test.go +++ b/download/federal_revenue_test.go @@ -6,60 +6,80 @@ import ( "testing" ) +func TestFederalRevenueGetMostRecentURL(t *testing.T) { + ts := httpTestServer(t, []string{"dados_abertos_cnpj.html"}) + defer ts.Close() + + t.Run("returns download urls", func(t *testing.T) { + got, err := federalRevenueGetMostRecentURL(ts.URL) + if err != nil { + t.Errorf("expected to run without errors, got: %v:", err) + } + expected := ts.URL + "/2024-08/" + if got != expected { + t.Errorf("expected %s, got %s", expected, got) + } + }) +} + func TestFederalRevenueGetURLs(t *testing.T) { - tmp := t.TempDir() - ts := httpTestServer(t, "cadastro-nacional-de-pessoa-juridica-cnpj.json") + ts := httpTestServer(t, []string{"dados_abertos_cnpj.html", "2024-08.html"}) defer ts.Close() t.Run("returns download urls", func(t *testing.T) { - got, err := federalRevenueGetURLs(ts.URL, tmp) + got, err := federalRevenueGetURLs(ts.URL) if err != nil { t.Errorf("expected to run without errors, got: %v:", err) } expected := []string{ - "https://dadosabertos.rfb.gov.br/CNPJ/Cnaes.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Empresas0.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Empresas1.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Empresas2.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Empresas3.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Empresas4.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Empresas5.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Empresas6.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Empresas7.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Empresas8.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Empresas9.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Estabelecimentos0.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Estabelecimentos1.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Estabelecimentos2.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Estabelecimentos3.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Estabelecimentos4.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Estabelecimentos5.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Estabelecimentos6.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Estabelecimentos7.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Estabelecimentos8.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Estabelecimentos9.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Motivos.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Municipios.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Naturezas.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Paises.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Qualificacoes.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Simples.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Socios0.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Socios1.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Socios2.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Socios3.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Socios4.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Socios5.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Socios6.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Socios7.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Socios8.zip", - "https://dadosabertos.rfb.gov.br/CNPJ/Socios9.zip", + ts.URL + "/2024-08/Cnaes.zip", + ts.URL + "/2024-08/Empresas0.zip", + ts.URL + "/2024-08/Empresas1.zip", + ts.URL + "/2024-08/Empresas2.zip", + ts.URL + "/2024-08/Empresas3.zip", + ts.URL + "/2024-08/Empresas4.zip", + ts.URL + "/2024-08/Empresas5.zip", + ts.URL + "/2024-08/Empresas6.zip", + ts.URL + "/2024-08/Empresas7.zip", + ts.URL + "/2024-08/Empresas8.zip", + ts.URL + "/2024-08/Empresas9.zip", + ts.URL + "/2024-08/Estabelecimentos0.zip", + ts.URL + "/2024-08/Estabelecimentos1.zip", + ts.URL + "/2024-08/Estabelecimentos2.zip", + ts.URL + "/2024-08/Estabelecimentos3.zip", + ts.URL + "/2024-08/Estabelecimentos4.zip", + ts.URL + "/2024-08/Estabelecimentos5.zip", + ts.URL + "/2024-08/Estabelecimentos6.zip", + ts.URL + "/2024-08/Estabelecimentos7.zip", + ts.URL + "/2024-08/Estabelecimentos8.zip", + ts.URL + "/2024-08/Estabelecimentos9.zip", + ts.URL + "/2024-08/Motivos.zip", + ts.URL + "/2024-08/Municipios.zip", + ts.URL + "/2024-08/Naturezas.zip", + ts.URL + "/2024-08/Paises.zip", + ts.URL + "/2024-08/Qualificacoes.zip", + ts.URL + "/2024-08/Simples.zip", + ts.URL + "/2024-08/Socios0.zip", + ts.URL + "/2024-08/Socios1.zip", + ts.URL + "/2024-08/Socios2.zip", + ts.URL + "/2024-08/Socios3.zip", + ts.URL + "/2024-08/Socios4.zip", + ts.URL + "/2024-08/Socios5.zip", + ts.URL + "/2024-08/Socios6.zip", + ts.URL + "/2024-08/Socios7.zip", + ts.URL + "/2024-08/Socios8.zip", + ts.URL + "/2024-08/Socios9.zip", } assertArraysHaveSameItems(t, got, expected) }) +} +func TestFederalRevenueGetMetadata(t *testing.T) { + ts := httpTestServer(t, []string{"cadastro-nacional-de-pessoa-juridica-cnpj.json"}) + defer ts.Close() t.Run("saves updated at date", func(t *testing.T) { - _, err := federalRevenueGetURLs(ts.URL, tmp) + tmp := t.TempDir() + err := federalRevenueGetMetadata(ts.URL, tmp) if err != nil { t.Errorf("expected to run without errors, got: %v:", err) } diff --git a/download/national_treasure.go b/download/national_treasure.go index c559b7cd..e912736a 100644 --- a/download/national_treasure.go +++ b/download/national_treasure.go @@ -55,6 +55,6 @@ func ckanGetURLS(baseURL, pkgID string) ([]string, error) { return urls, nil } -func nationalTreasureGetURLs(baseURL, dir string) ([]string, error) { +func nationalTreasureGetURLs(baseURL string) ([]string, error) { return ckanGetURLS(baseURL, nationalTreasurePkgID) } diff --git a/download/national_treasure_test.go b/download/national_treasure_test.go index d14f787f..823d1116 100644 --- a/download/national_treasure_test.go +++ b/download/national_treasure_test.go @@ -5,9 +5,9 @@ import ( ) func TestNationalTreasureGetURLs(t *testing.T) { - ts := httpTestServer(t, "national-treasure.json") + ts := httpTestServer(t, []string{"national-treasure.json"}) defer ts.Close() - got, err := nationalTreasureGetURLs(ts.URL, t.TempDir()) + got, err := nationalTreasureGetURLs(ts.URL) if err != nil { t.Errorf("expected to run without errors, got: %v:", err) return diff --git a/go.mod b/go.mod index 198959b7..96e528b8 100644 --- a/go.mod +++ b/go.mod @@ -1,23 +1,22 @@ module github.com/cuducos/minha-receita -go 1.21 +go 1.22 require ( - github.com/aws/aws-sdk-go v1.49.7 + github.com/aws/aws-sdk-go v1.55.5 github.com/cuducos/chunk v1.1.2 github.com/cuducos/go-cnpj v0.1.1 github.com/dgraph-io/badger/v4 v4.2.0 - github.com/jackc/pgx/v5 v5.5.0 - github.com/newrelic/go-agent/v3 v3.27.0 + github.com/jackc/pgx/v5 v5.6.0 + github.com/newrelic/go-agent/v3 v3.32.0 github.com/newrelic/go-agent/v3/integrations/logcontext-v2/logWriter v1.0.1 - github.com/newrelic/go-agent/v3/integrations/nrpgx5 v1.2.0 - github.com/schollz/progressbar/v3 v3.14.1 - github.com/spf13/cobra v1.8.0 - golang.org/x/text v0.14.0 + github.com/newrelic/go-agent/v3/integrations/nrpgx5 v1.3.0 + github.com/schollz/progressbar/v3 v3.14.6 + github.com/spf13/cobra v1.8.1 + golang.org/x/text v0.17.0 ) require ( - github.com/andybalholm/brotli v1.0.6 // indirect github.com/avast/retry-go v3.0.0+incompatible // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect @@ -40,19 +39,17 @@ require ( github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrwriter v1.0.0 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/rivo/uniseg v0.4.4 // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasthttp v1.51.0 // indirect go.opencensus.io v0.24.0 // indirect - golang.org/x/crypto v0.15.0 // indirect + golang.org/x/crypto v0.17.0 // indirect golang.org/x/net v0.18.0 // indirect - golang.org/x/sync v0.5.0 // indirect - golang.org/x/sys v0.14.0 // indirect - golang.org/x/term v0.14.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/term v0.22.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect google.golang.org/grpc v1.59.0 // indirect google.golang.org/protobuf v1.31.0 // indirect ) -// +heroku goVersion go1.21 +// +heroku goVersion go1.22 diff --git a/go.sum b/go.sum index 17cc1d71..904b64be 100644 --- a/go.sum +++ b/go.sum @@ -1,12 +1,10 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI= -github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0= github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= -github.com/aws/aws-sdk-go v1.49.7 h1:qQAOWYajSCRQQUFt+OZZ4pgDg2Uf3h4bBQmYzPyyka8= -github.com/aws/aws-sdk-go v1.49.7/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= +github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= @@ -16,7 +14,7 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= 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/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/cuducos/chunk v1.1.2 h1:XNFpuOAfwQKilvGYyQDdOgamTISofiHjU2Xd3KbV+VE= github.com/cuducos/chunk v1.1.2/go.mod h1:KQ8TL8O6ammHyniLCSMqcn7yv855iPMowvQWlG3ha8g= @@ -127,8 +125,8 @@ github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQ github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= github.com/jackc/pgx/v4 v4.18.1 h1:YP7G1KABtKpB5IHrO9vYwSrCOhs7p3uqhvhhQBptya0= github.com/jackc/pgx/v4 v4.18.1/go.mod h1:FydWkUyadDmdNH/mHnGob881GawxeEm7TcMCzkb+qQE= -github.com/jackc/pgx/v5 v5.5.0 h1:NxstgwndsTRy7eq9/kqYc/BZh5w2hHJV86wjvO+1xPw= -github.com/jackc/pgx/v5 v5.5.0/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA= +github.com/jackc/pgx/v5 v5.6.0 h1:SWJzexBzPL5jb0GEsrPMLIsi/3jOo7RHlzTjcAeDrPY= +github.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw= 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.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= @@ -162,36 +160,36 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= -github.com/newrelic/go-agent/v3 v3.27.0 h1:Z3XB49d8FKjRcGzCyViCO9itBxiLPSpwjY1HlMvgamQ= -github.com/newrelic/go-agent/v3 v3.27.0/go.mod h1:TUzePinDc0BMH4Sui66rl4SBe6yOKJ5X/bRJekwuAtM= +github.com/newrelic/go-agent/v3 v3.32.0 h1:99Et9lXXzeQV1CfYldfeTXv+d9W9KatpMbb50kIscWo= +github.com/newrelic/go-agent/v3 v3.32.0/go.mod h1:SMdqPzE/ghkWdY0rYGSD7Clw2daK/XH6pUnVd4albg4= github.com/newrelic/go-agent/v3/integrations/logcontext-v2/logWriter v1.0.1 h1:QHUFxBPgC8YYcCRCGfteWJUnaQjetEFTmd67KQ44t1M= github.com/newrelic/go-agent/v3/integrations/logcontext-v2/logWriter v1.0.1/go.mod h1:eATzimYSQLsG+VFK2xJXWmniC1+zr44K7Owz5WEAoqc= github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrwriter v1.0.0 h1:ugrng2OpXAEmwCQgLNmIGM8m0MZiitpswBVotVjyivA= github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrwriter v1.0.0/go.mod h1:5+hmfTxwzTj022CzgB8RpMZeY4AVBav25MvcTKSX/vg= -github.com/newrelic/go-agent/v3/integrations/nrpgx5 v1.2.0 h1:P1YjRtD7dsP7G/+nZQGublcYQcPFDA3vImveaomy1S8= -github.com/newrelic/go-agent/v3/integrations/nrpgx5 v1.2.0/go.mod h1:XKdAgg6FSzCGaNR5dZwr7H2fzlbMU0A49lo/1JScWMo= +github.com/newrelic/go-agent/v3/integrations/nrpgx5 v1.3.0 h1:aT9xRekVkt0aJdX2ebZuiWMkwqCcC8IHvjHddh/+7qw= +github.com/newrelic/go-agent/v3/integrations/nrpgx5 v1.3.0/go.mod h1:l7DSVUZzYyjY8mOR/ybiHMP20raWuStebhOrGgXg0mQ= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= -github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 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.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/schollz/progressbar/v3 v3.14.1 h1:VD+MJPCr4s3wdhTc7OEJ/Z3dAeBzJ7yKH/P4lC5yRTI= -github.com/schollz/progressbar/v3 v3.14.1/go.mod h1:Zc9xXneTzWXF81TGoqL71u0sBPjULtEHYtj/WVgVy8E= +github.com/schollz/progressbar/v3 v3.14.6 h1:GyjwcWBAf+GFDMLziwerKvpuS7ZF+mNTAXIB2aspiZs= +github.com/schollz/progressbar/v3 v3.14.6/go.mod h1:Nrzpuw3Nl0srLY0VlTvC4V6RL50pcEymjy6qyJAaLa0= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= 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/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -208,10 +206,6 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA= -github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= @@ -240,8 +234,8 @@ golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA= -golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -274,8 +268,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/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.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 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= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -295,14 +289,14 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20221010170243-090e33056c14/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.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= 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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8= -golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= +golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= +golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/text v0.3.0/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= @@ -310,8 +304,8 @@ golang.org/x/text v0.3.4/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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -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.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= diff --git a/testdata/2024-08.html b/testdata/2024-08.html new file mode 100644 index 00000000..b848a06e --- /dev/null +++ b/testdata/2024-08.html @@ -0,0 +1,51 @@ + + + + Index of /CNPJ/dados_abertos_cnpj/2024-08 + + +

Index of /CNPJ/dados_abertos_cnpj/2024-08

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
[ICO]NameLast modifiedSizeDescription

[PARENTDIR]Parent Directory   -  
[   ]Cnaes.zip 2024-08-14 11:48 22K 
[   ]Empresas0.zip 2024-08-14 11:48 341M 
[   ]Empresas1.zip 2024-08-14 11:48 74M 
[   ]Empresas2.zip 2024-08-14 11:48 75M 
[   ]Empresas3.zip 2024-08-14 11:48 81M 
[   ]Empresas4.zip 2024-08-14 11:48 86M 
[   ]Empresas5.zip 2024-08-14 11:48 93M 
[   ]Empresas6.zip 2024-08-14 11:48 90M 
[   ]Empresas7.zip 2024-08-14 11:48 95M 
[   ]Empresas8.zip 2024-08-14 11:48 95M 
[   ]Empresas9.zip 2024-08-14 11:48 91M 
[   ]Estabelecimentos0.zip 2024-08-14 11:48 1.3G 
[   ]Estabelecimentos1.zip 2024-08-14 11:48 323M 
[   ]Estabelecimentos2.zip 2024-08-14 11:48 322M 
[   ]Estabelecimentos3.zip 2024-08-14 11:48 321M 
[   ]Estabelecimentos4.zip 2024-08-14 11:48 343M 
[   ]Estabelecimentos5.zip 2024-08-14 11:48 330M 
[   ]Estabelecimentos6.zip 2024-08-14 11:48 322M 
[   ]Estabelecimentos7.zip 2024-08-14 11:48 320M 
[   ]Estabelecimentos8.zip 2024-08-14 11:48 335M 
[   ]Estabelecimentos9.zip 2024-08-14 11:48 339M 
[   ]Motivos.zip 2024-08-14 11:48 1.1K 
[   ]Municipios.zip 2024-08-14 11:48 42K 
[   ]Naturezas.zip 2024-08-14 11:48 1.5K 
[   ]Paises.zip 2024-08-14 11:48 2.7K 
[   ]Qualificacoes.zip 2024-08-14 11:48 1.0K 
[   ]Simples.zip 2024-08-14 11:48 223M 
[   ]Socios0.zip 2024-08-14 11:49 147M 
[   ]Socios1.zip 2024-08-14 11:49 47M 
[   ]Socios2.zip 2024-08-14 11:49 47M 
[   ]Socios3.zip 2024-08-14 11:49 47M 
[   ]Socios4.zip 2024-08-14 11:49 47M 
[   ]Socios5.zip 2024-08-14 11:49 47M 
[   ]Socios6.zip 2024-08-14 11:49 47M 
[   ]Socios7.zip 2024-08-14 11:49 47M 
[   ]Socios8.zip 2024-08-14 11:49 47M 
[   ]Socios9.zip 2024-08-14 11:49 47M 

+ diff --git a/testdata/dados_abertos_cnpj.html b/testdata/dados_abertos_cnpj.html new file mode 100644 index 00000000..de056da4 --- /dev/null +++ b/testdata/dados_abertos_cnpj.html @@ -0,0 +1,17 @@ + + + + Index of /CNPJ/dados_abertos_cnpj + + +

Index of /CNPJ/dados_abertos_cnpj

+ + + + + + + + +
[ICO]NameLast modifiedSizeDescription

[PARENTDIR]Parent Directory   -  
[DIR]2024-06/ 2024-08-16 09:58 -  
[DIR]2024-07/ 2024-08-15 15:32 -  
[DIR]2024-08/ 2024-08-14 11:42 -  

+