diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml new file mode 100644 index 0000000..d784887 --- /dev/null +++ b/.github/workflows/docker-image.yml @@ -0,0 +1,53 @@ +name: Docker Image CI + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +jobs: + + build: + + runs-on: ubuntu-latest + + steps: + + - name: Install NodeJS 20 + uses: actions/setup-node@v4 + with: + node-version: 20 + + # Build and start the DBHub.io server daemons + - name: Checkout the DBHub.io source code + uses: actions/checkout@v4 + with: + repository: 'sqlitebrowser/dbhub.io' + path: daemons + + - name: Build the DBHub.io daemons + run: cd daemons; yarn docker:build + + - name: Update the daemon config file + run: cd daemons; sed -i 's/bind_address = ":9444"/bind_address = "0.0.0.0:9444"/' docker/config.toml + + - name: Start the DBHub.io daemons + run: cd daemons; docker run -itd --rm --name dbhub-build --net host dbhub-build:latest && sleep 5 + + # Build and test the go-dbhub library + - name: Checkout go-dbhub library source code + uses: actions/checkout@v4 + with: + path: main + + - name: Set up Go for go-dbhub library + uses: actions/setup-go@v4 + with: + go-version: '1.20' + + - name: Build the go-dbhub library + run: cd main; go build -v + + - name: Test the go-dbhub library + run: cd main; go test -v diff --git a/dbhub_test.go b/dbhub_test.go new file mode 100644 index 0000000..f6b9f88 --- /dev/null +++ b/dbhub_test.go @@ -0,0 +1,633 @@ +package dbhub + +import ( + "bytes" + "crypto/tls" + "io" + "log" + "net/http" + "os" + "path/filepath" + "testing" + + "github.com/docker/docker/pkg/fileutils" + sqlite "github.com/gwenn/gosqlite" + "github.com/sqlitebrowser/dbhub.io/common" + "github.com/stretchr/testify/assert" +) + +// For now, the tests require the DBHub.io dev docker container be running on its standard +// ports (that means the API server is listening on https://localhost:9444) + +// TODO: Check that the "/x/apikeygen" end point on the web server checks for authentication data. While skimming over +// it quickly a few minutes ago, I didn't notice any (!) + +func TestMain(m *testing.M) { + log.Println("Seeding the database...") + + // Disable https cert validation for our tests + insecureTLS := tls.Config{InsecureSkipVerify: true} + insecureTransport := http.Transport{TLSClientConfig: &insecureTLS} + client := http.Client{Transport: &insecureTransport} + + // Seed the database + resp, err := client.Get("https://localhost:9443/x/test/seed") + if err != nil { + log.Fatal(err) + } + if resp.StatusCode != 200 { + log.Fatalf("Database seed request returned http code '%d'. Aborting tests.", resp.StatusCode) + } + log.Println("Database seeding completed ok.") + + // Run the tests + log.Println("Running the tests...") + m.Run() +} + +// TestBranches verifies retrieving the branch and default branch information using the API +func TestBranches(t *testing.T) { + // Create the local test server connection + conn := serverConnection("Rh3fPl6cl84XEw2FeWtj-FlUsn9OrxKz9oSJfe6kho7jT_1l5hizqw") + + // Retrieve branch details for the database + branches, defaultBranch, err := conn.Branches("default", "Assembly Election 2017 with view.sqlite") + if err != nil { + t.Error(err) + return + } + + // Verify the returned branch information matches what we're expecting + assert.Len(t, branches, 1) + assert.Contains(t, branches, "main") + assert.Equal(t, "main", defaultBranch) +} + +// TestColumns verifies retrieving the list of column names for a database using the API +func TestColumns(t *testing.T) { + // Create the local test server connection + conn := serverConnection("Rh3fPl6cl84XEw2FeWtj-FlUsn9OrxKz9oSJfe6kho7jT_1l5hizqw") + + // Retrieve the column info for a table or view in the remote database + table := "Candidate_Names" + columns, err := conn.Columns("default", "Assembly Election 2017 with view.sqlite", Identifier{Branch: "main"}, table) + if err != nil { + log.Fatal(err) + } + + // Verify the returned column information matches what we're expecting + assert.Len(t, columns, 2) + assert.Contains(t, columns[0].Name, "Firstname") + assert.Equal(t, "Surname", columns[1].Name) +} + +// TestCommits verifies retrieving commit information for standard databases using the API +func TestCommits(t *testing.T) { + // Create the local test server connection + conn := serverConnection("Rh3fPl6cl84XEw2FeWtj-FlUsn9OrxKz9oSJfe6kho7jT_1l5hizqw") + + // Retrieve the commit info for a remote database + commits, err := conn.Commits("default", "Assembly Election 2017 with view.sqlite") + if err != nil { + log.Fatal(err) + } + + // Verify the returned commit information matches what we're expecting + assert.Len(t, commits, 1) + + // Abort early if the returned length of commits isn't what we're expecting + if len(commits) != 1 { + return + } + + // Retrieve the the first commit id + var ids []string + for id := range commits { + ids = append(ids, id) + } + firstID := ids[0] + + // Verify the commit information is what we're expecting + assert.Equal(t, "default@docker-dev.dbhub.io", commits[firstID].AuthorEmail) + assert.Equal(t, "Default system user", commits[firstID].AuthorName) + assert.Equal(t, "Initial commit", commits[firstID].Message) + assert.Equal(t, "Assembly Election 2017 with view.sqlite", commits[firstID].Tree.Entries[0].Name) + assert.Equal(t, int64(73728), commits[firstID].Tree.Entries[0].Size) + assert.Equal(t, "9cb18719bddb949043abc1ba089dd7c4845ab024ddbe4ad19e9334da4e5b8cdc", commits[firstID].Tree.Entries[0].Sha256) + assert.Equal(t, "9348ddfd44da5a127c59141981954746a860ec8e03e0412cf3af7134af0f97e2", commits[firstID].Tree.Entries[0].LicenceSHA) +} + +// TestDatabases verifies retrieving the list of standard databases using the API +func TestDatabases(t *testing.T) { + // Create the local test server connection + conn := serverConnection("Rh3fPl6cl84XEw2FeWtj-FlUsn9OrxKz9oSJfe6kho7jT_1l5hizqw") + + // Retrieve the list of databases for the user + databases, err := conn.Databases() + if err != nil { + t.Errorf("Connecting to the API server failed: %v", err) + return + } + + // If no databases were found, the test failed + if len(databases) == 0 { + t.Error("No databases found") + return + } + + // Verify the expected database names were returned, and only them + assert.Contains(t, databases, "Assembly Election 2017 with view.sqlite") + assert.Contains(t, databases, "Assembly Election 2017.sqlite") + assert.Len(t, databases, 2) + return +} + +// TestDatabases verifies retrieving the list of live databases using the API +func TestDatabasesLive(t *testing.T) { + // Create the local test server connection + conn := serverConnection("Rh3fPl6cl84XEw2FeWtj-FlUsn9OrxKz9oSJfe6kho7jT_1l5hizqw") + + // Retrieve the list of live databases for the user + databases, err := conn.DatabasesLive() + if err != nil { + t.Error(err) + return + } + + // If no databases were found, the test failed + if len(databases) == 0 { + t.Error("No databases found") + return + } + + // Verify the expected database name was returned + assert.Contains(t, databases, "Join Testing with index.sqlite") + assert.Len(t, databases, 1) + return +} + +// TestDiff verifies the Diff API call +func TestDiff(t *testing.T) { + // Create the local test server connection + conn := serverConnection("Rh3fPl6cl84XEw2FeWtj-FlUsn9OrxKz9oSJfe6kho7jT_1l5hizqw") + + // Read the example database file into memory + dbFile := filepath.Join("examples", "upload", "example.db") + z, err := os.ReadFile(dbFile) + if err != nil { + t.Error(err) + return + } + + // Upload the example database + dbName := "uploadtest1.sqlite" + err = conn.Upload(dbName, UploadInformation{}, &z) + if err != nil { + t.Error(err) + return + } + t.Cleanup(func() { + // Delete the uploaded database when the test exits + err = conn.Delete(dbName) + if err != nil { + t.Error(err) + return + } + }) + + // Copy the database file to a temp location so we can make some changes + newFile := filepath.Join(t.TempDir(), "diff-"+common.RandomString(8)+".sqlite") + _, err = fileutils.CopyFile(dbFile, newFile) + if err != nil { + t.Error(err) + return + } + + // Make some changes to the copied database file + sdb, err := sqlite.Open(newFile, sqlite.OpenReadWrite|sqlite.OpenFullMutex) + if err != nil { + t.Error() + return + } + dbQuery := ` + CREATE TABLE foo (first integer); + INSERT INTO foo (first) values (10); + INSERT INTO foo (first) values (20);` + err = sdb.Exec(dbQuery) + if err != nil { + t.Error() + sdb.Close() + return + } + sdb.Close() + + // Retrieve the initial commit id for the database + dbOwner := "default" + commitMap, err := conn.Commits(dbOwner, dbName) + if err != nil { + t.Error(err) + return + } + var commits []string + for idx := range commitMap { + commits = append(commits, idx) + } + firstCommit := commits[0] + + // Upload the copied file as a new commit + z, err = os.ReadFile(newFile) + if err != nil { + t.Error(err) + return + } + uploadCommit := Identifier{CommitID: firstCommit} + err = conn.Upload(dbName, UploadInformation{Ident: uploadCommit}, &z) + if err != nil { + t.Error(err) + return + } + + // Retrieve the new commit id for the database + commitMap, err = conn.Commits(dbOwner, dbName) + if err != nil { + t.Error(err) + return + } + var secondCommit string + for idx := range commitMap { + if idx != firstCommit { + secondCommit = idx + } + } + + // Do the diff using NewPkMerge + commit1 := Identifier{CommitID: firstCommit} + commit2 := Identifier{CommitID: secondCommit} + diffs, err := conn.Diff(dbOwner, dbName, commit1, "", "", commit2, NewPkMerge) + if err != nil { + t.Error(err) + return + } + + // Verify the changes + assert.Len(t, diffs.Diff, 1) + assert.Equal(t, "foo", diffs.Diff[0].ObjectName) + assert.Equal(t, "table", diffs.Diff[0].ObjectType) + assert.Equal(t, common.DiffType("add"), diffs.Diff[0].Schema.ActionType) + assert.Equal(t, "CREATE TABLE foo (first integer);", diffs.Diff[0].Schema.Sql) + assert.Equal(t, "", diffs.Diff[0].Schema.Before) + assert.Equal(t, "CREATE TABLE foo (first integer)", diffs.Diff[0].Schema.After) + assert.Equal(t, `INSERT INTO "foo"("first") VALUES(10);`, diffs.Diff[0].Data[0].Sql) + assert.Equal(t, `INSERT INTO "foo"("first") VALUES(20);`, diffs.Diff[0].Data[1].Sql) + + // Diff with PreservePkMerge + diffs, err = conn.Diff(dbOwner, dbName, commit1, "", "", commit2, PreservePkMerge) + if err != nil { + t.Error(err) + return + } + + // Verify the changes + assert.Len(t, diffs.Diff, 1) + assert.Equal(t, "foo", diffs.Diff[0].ObjectName) + assert.Equal(t, "table", diffs.Diff[0].ObjectType) + assert.Equal(t, common.DiffType("add"), diffs.Diff[0].Schema.ActionType) + assert.Equal(t, "CREATE TABLE foo (first integer);", diffs.Diff[0].Schema.Sql) + assert.Equal(t, "", diffs.Diff[0].Schema.Before) + assert.Equal(t, "CREATE TABLE foo (first integer)", diffs.Diff[0].Schema.After) + assert.Equal(t, `INSERT INTO "foo"("first") VALUES(10);`, diffs.Diff[0].Data[0].Sql) + assert.Equal(t, `INSERT INTO "foo"("first") VALUES(20);`, diffs.Diff[0].Data[1].Sql) + + // Diff with NoMerge + diffs, err = conn.Diff(dbOwner, dbName, commit1, "", "", commit2, NoMerge) + if err != nil { + t.Error(err) + return + } + + // Verify the changes + assert.Len(t, diffs.Diff, 1) + assert.Equal(t, "foo", diffs.Diff[0].ObjectName) + assert.Equal(t, "table", diffs.Diff[0].ObjectType) + assert.Equal(t, common.DiffType("add"), diffs.Diff[0].Schema.ActionType) + assert.Equal(t, "", diffs.Diff[0].Schema.Sql) + assert.Equal(t, "", diffs.Diff[0].Schema.Before) + assert.Equal(t, "CREATE TABLE foo (first integer)", diffs.Diff[0].Schema.After) + assert.Equal(t, "", diffs.Diff[0].Data[0].Sql) + assert.Equal(t, "", diffs.Diff[0].Data[1].Sql) +} + +// TestExecute verifies the Execute API call +func TestExecute(t *testing.T) { + // Create the local test server connection + conn := serverConnection("Rh3fPl6cl84XEw2FeWtj-FlUsn9OrxKz9oSJfe6kho7jT_1l5hizqw") + + // Execute a SQL statement + dbQuery := `INSERT INTO table1 (id, Name) VALUES (7, "Stuff")` + rowsChanged, err := conn.Execute("default", "Join Testing with index.sqlite", dbQuery) + if err != nil { + t.Error(err) + return + } + + // Verify the result + assert.Equal(t, 1, rowsChanged) + + // Execute another SQL statement + dbQuery = `UPDATE table1 SET Name = "New Stuff" WHERE id = 1 OR id = 7` + rowsChanged, err = conn.Execute("default", "Join Testing with index.sqlite", dbQuery) + if err != nil { + t.Error(err) + return + } + + // Verify the result + assert.Equal(t, 2, rowsChanged) +} + +// TestIndexes verifies the Indexes API call +func TestIndexes(t *testing.T) { + // Create the local test server connection + conn := serverConnection("Rh3fPl6cl84XEw2FeWtj-FlUsn9OrxKz9oSJfe6kho7jT_1l5hizqw") + + // Retrieve the index information for the database + indexes, err := conn.Indexes("default", "Join Testing with index.sqlite", Identifier{}) + if err != nil { + t.Error(err) + return + } + + // Verify the index information + assert.Len(t, indexes, 1) + assert.Equal(t, "table1", indexes[0].Table) + assert.Equal(t, "stuff", indexes[0].Name) + assert.Empty(t, indexes[0].Columns[0].CID) + assert.Equal(t, "id", indexes[0].Columns[0].Name) +} + +// TestMetadata verifies the metadata API call +func TestMetadata(t *testing.T) { + // Create the local test server connection + conn := serverConnection("Rh3fPl6cl84XEw2FeWtj-FlUsn9OrxKz9oSJfe6kho7jT_1l5hizqw") + + // Retrieve the metadata information for the database + meta, err := conn.Metadata("default", "Assembly Election 2017 with view.sqlite") + if err != nil { + t.Error(err) + return + } + + // Get the commit id of the first commit + var firstCommit string + for _, c := range meta.Commits { + firstCommit = c.ID + } + + // Verify the metadata info + assert.Equal(t, "https://docker-dev.dbhub.io:9443/default/Assembly Election 2017 with view.sqlite", meta.WebPage) + assert.Equal(t, "main", meta.DefBranch) + assert.Equal(t, "", meta.Branches["main"].Description) + assert.Equal(t, 1, meta.Branches["main"].CommitCount) + assert.Empty(t, meta.Releases) + assert.Empty(t, meta.Tags) + assert.Equal(t, firstCommit, meta.Commits[firstCommit].ID) + assert.Equal(t, "Initial commit", meta.Commits[firstCommit].Message) + assert.Equal(t, "Default system user", meta.Commits[firstCommit].AuthorName) + assert.Equal(t, "default@docker-dev.dbhub.io", meta.Commits[firstCommit].AuthorEmail) + assert.Equal(t, int64(73728), meta.Commits[firstCommit].Tree.Entries[0].Size) +} + +// TestQuery verifies the Query API call +func TestQuery(t *testing.T) { + // Create the local test server connection + conn := serverConnection("Rh3fPl6cl84XEw2FeWtj-FlUsn9OrxKz9oSJfe6kho7jT_1l5hizqw") + + // Query the database + dbQuery := ` + SELECT id, Name + FROM table1 + ORDER BY Name DESC` + result, err := conn.Query("default", "Join Testing with index.sqlite", Identifier{}, false, dbQuery) + if err != nil { + t.Error(err) + return + } + + // Verify the result + assert.Len(t, result.Rows, 7) + assert.Contains(t, result.Rows, ResultRow{Fields: []string{"2", "Bar"}}) + assert.Contains(t, result.Rows, ResultRow{Fields: []string{"3", "Baz"}}) + assert.Contains(t, result.Rows, ResultRow{Fields: []string{"4", "Blumph"}}) + assert.Contains(t, result.Rows, ResultRow{Fields: []string{"5", "Blargo"}}) + assert.Contains(t, result.Rows, ResultRow{Fields: []string{"6", "Batty"}}) +} + +// TestReleases verifies the Releases API call +func TestReleases(t *testing.T) { + // Create the local test server connection + conn := serverConnection("Rh3fPl6cl84XEw2FeWtj-FlUsn9OrxKz9oSJfe6kho7jT_1l5hizqw") + + // Retrieve the releases for a database + releases, err := conn.Releases("default", "Assembly Election 2017.sqlite") + if err != nil { + t.Error(err) + return + } + + // Verify the retrieved information + assert.Len(t, releases, 2) + assert.Equal(t, "First release", releases["first"].Description) + assert.Equal(t, "Example Releaser", releases["first"].ReleaserName) + assert.Equal(t, "example@example.org", releases["first"].ReleaserEmail) + assert.Equal(t, "Second release", releases["second"].Description) + assert.Equal(t, "Example Releaser", releases["second"].ReleaserName) + assert.Equal(t, "example@example.org", releases["second"].ReleaserEmail) +} + +// TestTables verifies the Tables API call +func TestTables(t *testing.T) { + // Create the local test server connection + conn := serverConnection("Rh3fPl6cl84XEw2FeWtj-FlUsn9OrxKz9oSJfe6kho7jT_1l5hizqw") + + // Retrieve table information for a database + tbls, err := conn.Tables("default", "Assembly Election 2017.sqlite", Identifier{}) + if err != nil { + t.Error(err) + return + } + + // Verify the returned information + assert.Len(t, tbls, 3) + assert.Contains(t, tbls, "Candidate_Information") + assert.Contains(t, tbls, "Constituency_Turnout_Information") + assert.Contains(t, tbls, "Elected_Candidates") +} + +// TestTags verifies the Tags API call +func TestTags(t *testing.T) { + // Create the local test server connection + conn := serverConnection("Rh3fPl6cl84XEw2FeWtj-FlUsn9OrxKz9oSJfe6kho7jT_1l5hizqw") + + // Retrieve the tags for a database + tags, err := conn.Tags("default", "Assembly Election 2017.sqlite") + if err != nil { + t.Error(err) + return + } + + // Verify the retrieved information + assert.Len(t, tags, 2) + assert.Equal(t, "First tag", tags["first"].Description) + assert.Equal(t, "Example Tagger", tags["first"].TaggerName) + assert.Equal(t, "example@example.org", tags["first"].TaggerEmail) + assert.Equal(t, "Second tag", tags["second"].Description) + assert.Equal(t, "Example Tagger", tags["second"].TaggerName) + assert.Equal(t, "example@example.org", tags["second"].TaggerEmail) +} + +// TestUpload verifies uploading a standard database via the API +func TestUpload(t *testing.T) { + // Create the local test server connection + conn := serverConnection("Rh3fPl6cl84XEw2FeWtj-FlUsn9OrxKz9oSJfe6kho7jT_1l5hizqw") + + // Read the example database file into memory + dbFile := filepath.Join("examples", "upload", "example.db") + z, err := os.ReadFile(dbFile) + if err != nil { + t.Error(err) + return + } + + // Upload the example database + dbName := "testupload.sqlite" + err = conn.Upload(dbName, UploadInformation{}, &z) + if err != nil { + t.Error(err) + return + } + + // Verify the file contents. This is done by downloading the database and doing a byte comparison to ensure its + // identical to the upload + downloaded, err := conn.Download("default", dbName, Identifier{}) + if err != nil { + t.Error(err) + return + } + t.Cleanup(func() { + // Delete the uploaded file when the function exits + err = conn.Delete(dbName) + if err != nil { + t.Error(err) + return + } + }) + data, err := io.ReadAll(downloaded) + if err != nil { + t.Error(err) + return + } + result := bytes.Compare(z, data) + if result != 0 { + t.Errorf("Standard database upload succeeded, but failed verification when downloading it and comparing to the original") + return + } +} + +// TestUploadLive verifies uploading a live database via the API +func TestUploadLive(t *testing.T) { + // Create the local test server connection + conn := serverConnection("Rh3fPl6cl84XEw2FeWtj-FlUsn9OrxKz9oSJfe6kho7jT_1l5hizqw") + + // Read the example database file into memory + dbA := filepath.Join("examples", "upload", "example.db") + z, err := os.ReadFile(dbA) + if err != nil { + t.Error(err) + return + } + + // Upload the database + dbName := "testuploadlive.sqlite" + err = conn.UploadLive(dbName, &z) + if err != nil { + t.Error(err) + return + } + + // *** Verify the database *** + + // This is done by downloading and comparing (database diff) the database contents with the database file that was uploaded + downloaded, err := conn.Download("default", dbName, Identifier{}) + if err != nil { + t.Error(err) + return + } + t.Cleanup(func() { + // Delete the uploaded database when the test exits + err = conn.Delete(dbName) + if err != nil { + t.Error(err) + return + } + }) + data, err := io.ReadAll(downloaded) + if err != nil { + t.Error(err) + return + } + dbB := filepath.Join(t.TempDir(), "diff-"+common.RandomString(8)+".sqlite") + err = os.WriteFile(dbB, data, 0750) + if err != nil { + t.Error(err) + return + } + + // Do the comparison + diffs, err := common.DBDiff(dbA, dbB, common.NoMerge, false) + if err != nil { + t.Error(err) + return + } + assert.Empty(t, diffs.Diff) +} + +// TestViews verifies the Views API call +func TestViews(t *testing.T) { + // Create the local test server connection + conn := serverConnection("Rh3fPl6cl84XEw2FeWtj-FlUsn9OrxKz9oSJfe6kho7jT_1l5hizqw") + + // Get the list of views in the database + views, err := conn.Views("default", "Assembly Election 2017 with view.sqlite", Identifier{}) + if err != nil { + t.Error(err) + return + } + assert.Len(t, views, 1) + assert.Equal(t, "Candidate_Names", views[0]) +} + +// TestWebpage verifies the Webpage API call +func TestWebpage(t *testing.T) { + // Create the local test server connection + conn := serverConnection("Rh3fPl6cl84XEw2FeWtj-FlUsn9OrxKz9oSJfe6kho7jT_1l5hizqw") + + // Gather the data then test the result + pageData, err := conn.Webpage("default", "Assembly Election 2017.sqlite") + if err != nil { + t.Error(err) + return + } + assert.Equal(t, "https://docker-dev.dbhub.io:9443/default/Assembly Election 2017.sqlite", pageData.WebPage) +} + +// serverConnection is a utility function that sets up the API connection object to the test server, ready for use +func serverConnection(apiKey string) Connection { + // Create a new DBHub.io API object + db, err := New(apiKey) + if err != nil { + log.Fatal(err) + } + db.ChangeServer("https://localhost:9444") + db.ChangeVerifyServerCert(false) + return db +} diff --git a/go.mod b/go.mod index 3c07473..cccd145 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/sqlitebrowser/go-dbhub -go 1.17 +go 1.18 replace ( github.com/Sirupsen/logrus v1.0.5 => github.com/sirupsen/logrus v1.0.5 @@ -10,43 +10,59 @@ replace ( github.com/Sirupsen/logrus v1.6.0 => github.com/sirupsen/logrus v1.6.0 ) -require github.com/sqlitebrowser/dbhub.io v0.1.1 +require ( + github.com/docker/docker v24.0.7+incompatible + github.com/gwenn/gosqlite v0.0.0-20230220182433-af75c85b9faf + github.com/sqlitebrowser/dbhub.io v0.2.1 + github.com/stretchr/testify v1.8.4 +) require ( - github.com/BurntSushi/toml v0.3.1 // indirect + github.com/BurntSushi/toml v1.3.2 // indirect github.com/aquilax/truncate v1.0.0 // indirect github.com/aymerick/douceur v0.2.0 // indirect - github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b // indirect - github.com/go-ini/ini v1.56.0 // indirect - github.com/go-playground/locales v0.13.0 // indirect - github.com/go-playground/universal-translator v0.17.0 // indirect - github.com/go-playground/validator/v10 v10.3.0 // indirect - github.com/gopherjs/gopherjs v1.17.2 // indirect - github.com/gorilla/css v1.0.0 // indirect - github.com/gwenn/gosqlite v0.0.0-20200521090053-24878be1a237 // indirect - github.com/gwenn/yacr v0.0.0-20200112083327-bbe82c1f4d60 // indirect - github.com/jackc/pgx v2.11.0+incompatible // indirect - github.com/jtolds/gls v4.20.0+incompatible // indirect - github.com/leodido/go-urn v1.2.0 // indirect + github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect + github.com/containerd/containerd v1.7.11 // indirect + github.com/containerd/log v0.1.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/go-ini/ini v1.67.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.16.0 // indirect + github.com/golang-migrate/migrate/v4 v4.17.0 // indirect + github.com/gorilla/css v1.0.1 // indirect + github.com/gwenn/yacr v0.0.0-20230220182143-2858410e8872 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect + github.com/jackc/pgx/v5 v5.5.1 // indirect + github.com/jackc/puddle/v2 v2.2.1 // indirect + github.com/leodido/go-urn v1.2.4 // indirect github.com/microcosm-cc/bluemonday v1.0.16 // indirect github.com/minio/minio-go v6.0.14+incompatible // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/rabbitmq/amqp091-go v1.7.0 // indirect - github.com/segmentio/ksuid v1.0.3 // indirect - github.com/sergi/go-diff v1.1.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rabbitmq/amqp091-go v1.9.0 // indirect + github.com/sergi/go-diff v1.3.1 // indirect github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636 // indirect - github.com/shurcooL/highlight_diff v0.0.0-20181222201841-111da2e7d480 // indirect - github.com/shurcooL/highlight_go v0.0.0-20191220051317-782971ddf21b // indirect - github.com/shurcooL/octicon v0.0.0-20191102190552-cbb32d6a785c // indirect + github.com/shurcooL/highlight_diff v0.0.0-20230708024848-22f825814995 // indirect + github.com/shurcooL/highlight_go v0.0.0-20230708025100-33e05792540a // indirect + github.com/shurcooL/octicon v0.0.0-20230705024016-66bff059edb8 // indirect github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect - github.com/smartystreets/assertions v1.13.0 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect github.com/smtp2go-oss/smtp2go-go v1.0.2 // indirect github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d // indirect github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e // indirect github.com/sqlitebrowser/blackfriday v9.0.0+incompatible // indirect github.com/sqlitebrowser/github_flavored_markdown v0.0.0-20190120045821-b8cf8f054e47 // indirect - golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b // indirect - golang.org/x/net v0.7.0 // indirect - golang.org/x/sys v0.5.0 // indirect - golang.org/x/text v0.8.0 // indirect + go.uber.org/atomic v1.11.0 // indirect + golang.org/x/crypto v0.18.0 // indirect + golang.org/x/net v0.20.0 // indirect + golang.org/x/sync v0.6.0 // indirect + golang.org/x/sys v0.16.0 // indirect + golang.org/x/text v0.14.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 3af1728..029f1a2 100644 --- a/go.sum +++ b/go.sum @@ -1,82 +1,107 @@ -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/aquilax/truncate v1.0.0 h1:UgIGS8U/aZ4JyOJ2h3xcF5cSQ06+gGBnjxH2RUHJe0U= github.com/aquilax/truncate v1.0.0/go.mod h1:BeMESIDMlvlS3bmg4BVvBbbZUNwWtS8uzYPAKXwwhLw= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= -github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b h1:L/QXpzIa3pOvUGt1D1lA5KjYhPBAN/3iWdP7xeFS9F0= -github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= +github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous= +github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= +github.com/containerd/containerd v1.7.11 h1:lfGKw3eU35sjV0aG2eYZTiwFEY1pCzxdzicHP3SZILw= +github.com/containerd/containerd v1.7.11/go.mod h1:5UluHxHTX2rdvYuZ5OJTC5m/KJNs0Zs9wVoJm9zf5ZE= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= 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= -github.com/go-ini/ini v1.56.0 h1:6HjxSjqdmgnujDPhlzR4a44lxK3w03WPN8te0SoUSeM= -github.com/go-ini/ini v1.56.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= -github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.3.0 h1:nZU+7q+yJoFmwvNgv/LnPUkwPal62+b2xXj0AU1Es7o= -github.com/go-playground/validator/v10 v10.3.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= -github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= -github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= -github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= +github.com/dhui/dktest v0.4.0 h1:z05UmuXZHO/bgj/ds2bGMBu8FI4WA+Ag/m3ghL+om7M= +github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= +github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= +github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= +github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.16.0 h1:x+plE831WK4vaKHO/jpgUGsvLKIqRRkz6M78GuJAfGE= +github.com/go-playground/validator/v10 v10.16.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/golang-migrate/migrate/v4 v4.17.0 h1:rd40H3QXU0AA4IoLllFcEAEo9dYKRHYND2gB4p7xcaU= +github.com/golang-migrate/migrate/v4 v4.17.0/go.mod h1:+Cp2mtLP4/aXDTKb9wmXYitdrNx2HGs45rbWAo6OsKM= github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= -github.com/gwenn/gosqlite v0.0.0-20200521090053-24878be1a237 h1:RY/HYWiI6K/HL8ePZYpgvMGf4wX3/FgGxgE8kPh8vDM= -github.com/gwenn/gosqlite v0.0.0-20200521090053-24878be1a237/go.mod h1:WBYs9HfQGOYDCz7rFwMk7aHkbTTB0cUkQe3pZQARvIg= +github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= +github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0= +github.com/gwenn/gosqlite v0.0.0-20230220182433-af75c85b9faf h1:lmqo4Osg1zQAq3ZOa5NACDlkiLCk3zAVEoGytyzkKPo= +github.com/gwenn/gosqlite v0.0.0-20230220182433-af75c85b9faf/go.mod h1:WBYs9HfQGOYDCz7rFwMk7aHkbTTB0cUkQe3pZQARvIg= github.com/gwenn/yacr v0.0.0-20200110180258-a66d8c42d0ff/go.mod h1:5SNcBGxZ5OaJAMJCSI/x3V7SGsvXqbwnwP/sHZLgYsw= -github.com/gwenn/yacr v0.0.0-20200112083327-bbe82c1f4d60 h1:JX4Yy6S9U/f3Jix82M58NLIAFeW/UjBFVrnYn5GS4X8= -github.com/gwenn/yacr v0.0.0-20200112083327-bbe82c1f4d60/go.mod h1:Ps/gikIXcn2rRmeP0HQ9EvUYJrfrjAi51Wg8acsrkP0= -github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc= -github.com/jackc/pgx v2.11.0+incompatible h1:IgFLUrzrhJj8mxbK44ZYExGVnjtfV4+TOkerb/XERV8= -github.com/jackc/pgx v2.11.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/gwenn/yacr v0.0.0-20230220182143-2858410e8872 h1:AVWCyogAAzN3k+VEp01cNceW9X/Gd7SODLfeVP0ZI0s= +github.com/gwenn/yacr v0.0.0-20230220182143-2858410e8872/go.mod h1:Ps/gikIXcn2rRmeP0HQ9EvUYJrfrjAi51Wg8acsrkP0= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa h1:s+4MhCQ6YrzisK6hFJUX53drDT4UsSW3DEhKn0ifuHw= +github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa/go.mod h1:a/s9Lp5W7n/DD0VrVoyJ00FbP2ytTPDVOivvn2bMlds= +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-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA= +github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.5.1 h1:5I9etrGkLrN+2XPCsi6XLlV5DITbSL/xBZdmAxFcXPI= +github.com/jackc/pgx/v5 v5.5.1/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA= +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/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= -github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= +github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/microcosm-cc/bluemonday v1.0.16 h1:kHmAq2t7WPWLjiGvzKa5o3HzSfahUKiOq7fAPUiMNIc= github.com/microcosm-cc/bluemonday v1.0.16/go.mod h1:Z0r70sCuXHig8YpBzCc5eGHAap2K7e/u082ZUpDRRqM= github.com/minio/minio-go v6.0.14+incompatible h1:fnV+GD28LeqdN6vT2XdGKW8Qe/IfjJDswNVuni6km9o= github.com/minio/minio-go v6.0.14+incompatible/go.mod h1:7guKYtitv8dktvNUGrhzmNlA5wrAABTQXCoesZdFQO8= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 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/rabbitmq/amqp091-go v1.7.0 h1:V5CF5qPem5OGSnEo8BoSbsDGwejg6VUJsKEdneaoTUo= -github.com/rabbitmq/amqp091-go v1.7.0/go.mod h1:wfClAtY0C7bOHxd3GjmF26jEHn+rR/0B3+YV+Vn9/NI= +github.com/rabbitmq/amqp091-go v1.9.0 h1:qrQtyzB4H8BQgEuJwhmVQqVHB9O4+MNDJCCAcpc3Aoo= +github.com/rabbitmq/amqp091-go v1.9.0/go.mod h1:+jPrT9iY2eLjRaMSRHUhc3z14E/l85kv/f+6luSD3pc= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/russross/blackfriday v2.0.0+incompatible h1:cBXrhZNUf9C+La9/YpS+UHpUT8YD6Td9ZMSU9APFcsk= -github.com/segmentio/ksuid v1.0.3 h1:FoResxvleQwYiPAVKe1tMUlEirodZqlqglIuFsdDntY= -github.com/segmentio/ksuid v1.0.3/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= -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/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470 h1:qb9IthCFBmROJ6YBS31BEMeSYjOscSiG+EO+JVNTz64= github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636 h1:aSISeOcal5irEhJd1M+IrApc0PdcN7e7Aj4yuEnOrfQ= github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041 h1:llrF3Fs4018ePo4+G/HV/uQUqEI1HMDjCeOf2V6puPc= -github.com/shurcooL/highlight_diff v0.0.0-20181222201841-111da2e7d480 h1:KaKXZldeYH73dpQL+Nr38j1r5BgpAYQjYvENOUpIZDQ= -github.com/shurcooL/highlight_diff v0.0.0-20181222201841-111da2e7d480/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= -github.com/shurcooL/highlight_go v0.0.0-20191220051317-782971ddf21b h1:rBIwpb5ggtqf0uZZY5BPs1sL7njUMM7I8qD2jiou70E= -github.com/shurcooL/highlight_go v0.0.0-20191220051317-782971ddf21b/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= -github.com/shurcooL/octicon v0.0.0-20191102190552-cbb32d6a785c h1:p3w+lTqXulfa3aDeycxmcLJDNxyUB89gf2/XqqK3eO0= -github.com/shurcooL/octicon v0.0.0-20191102190552-cbb32d6a785c/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= +github.com/shurcooL/highlight_diff v0.0.0-20230708024848-22f825814995 h1:/6Fa0HAouqks/nlr3C3sv7KNDqutP3CM/MYz225uO28= +github.com/shurcooL/highlight_diff v0.0.0-20230708024848-22f825814995/go.mod h1:eqklBUMsamqZbxXhhr6GafgswFTa5Aq12VQ0I2lnCR8= +github.com/shurcooL/highlight_go v0.0.0-20230708025100-33e05792540a h1:aMmA4ghJXuzwIS/mEK+bf7U2WZECRxa3sPgR4QHj8Hw= +github.com/shurcooL/highlight_go v0.0.0-20230708025100-33e05792540a/go.mod h1:kLtotffsKtKsCupV8wNnNwQQHBccB1Oy5VSg8P409Go= +github.com/shurcooL/octicon v0.0.0-20230705024016-66bff059edb8 h1:W5meM/5DP0Igf+pS3Se363Y2DoDv9LUuZgQ24uG9LNY= +github.com/shurcooL/octicon v0.0.0-20230705024016-66bff059edb8/go.mod h1:hWBWTvIJ918VxbNOk2hxQg1/5j1M9yQI1Kp8d9qrOq8= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/smartystreets/assertions v1.13.0 h1:Dx1kYM01xsSqKPno3aqLnrwac2LetPvN23diwyr69Qs= -github.com/smartystreets/assertions v1.13.0/go.mod h1:wDmR7qL282YbGsPy6H/yAsesrxfxaaSlJazyFLYVFx8= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smtp2go-oss/smtp2go-go v1.0.2 h1:vXkqx9kyoQIuetyV3nm40b+OZevihhgb78X4vA/u2fs= github.com/smtp2go-oss/smtp2go-go v1.0.2/go.mod h1:lkv36awQXRBWAvnd517FFESKvne8465KCu90lPThcEY= github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d h1:yKm7XZV6j9Ev6lojP2XaIshpT4ymkqhMeSghO5Ps00E= @@ -85,63 +110,50 @@ github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e h1:qpG github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/sqlitebrowser/blackfriday v9.0.0+incompatible h1:ddH/UyzasooYgGIblVU4R8DdmBuJ7QXLvSqX/0chZv4= github.com/sqlitebrowser/blackfriday v9.0.0+incompatible/go.mod h1:/zga9sqpWzcewuI83AO5JZwe9+6F9GgPDdqqdNNEL/0= -github.com/sqlitebrowser/dbhub.io v0.1.1 h1:Lnm29SWWAc4pcE+d5tA58QTY9/2pnH546FR+aYT5gio= -github.com/sqlitebrowser/dbhub.io v0.1.1/go.mod h1:YD/BP8fgop8s3yRSLA7kjx4N+pWYU6Z353On+ZGrm58= +github.com/sqlitebrowser/dbhub.io v0.2.1 h1:dnNU4EH/KxSJhaaYWDr48Bo0f5c+a26bmf5YFVW//js= +github.com/sqlitebrowser/dbhub.io v0.2.1/go.mod h1:1a4m1T8DgJx4j9eNcDx3LKnz5N+leelikyAimlsmgJU= github.com/sqlitebrowser/github_flavored_markdown v0.0.0-20190120045821-b8cf8f054e47 h1:s0+Ea95n1LrsKh6rtclU/9Qb2/5ofvnfnR7gDDiFTw8= github.com/sqlitebrowser/github_flavored_markdown v0.0.0-20190120045821-b8cf8f054e47/go.mod h1:8vPIKi5FslxCXEgfQxrFtWfdclGy6VWAc9NA1ZTYCJg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +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.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b h1:Qwe1rC8PSniVfAFPFJeyUkB+zcysC3RgJBAGk7eqBEU= -golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= +golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -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/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +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-20201119102817-f84b799fce68/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.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -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= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -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/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -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-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg= 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/inconshreveable/log15.v2 v2.0.0-20200109203555-b30bc20e4fd1 h1:iiHuQZCNgYPmFQxd3BBN/Nc5+dAwzZuq5y40s20oQw0= -gopkg.in/ini.v1 v1.46.0 h1:VeDZbLYGaupuvIrsYCEOe/L/2Pcs5n7hdO1ZTjporag= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=