From 5b67bdab4fe424d0642c025af1e84c28702dd856 Mon Sep 17 00:00:00 2001 From: Jannik Clausen <12862103+masseelch@users.noreply.github.com> Date: Tue, 5 Jul 2022 12:29:15 +0200 Subject: [PATCH] dialect/sql/schema: atlas engine is now default (#2698) * atlas engine is default, enabled diff by replay * Apply suggestions from code review * docs * apply CR --- .golangci.yml | 4 + dialect/sql/schema/atlas.go | 766 ++++++++++++------ dialect/sql/schema/atlas_test.go | 33 - dialect/sql/schema/migrate.go | 280 ++----- dialect/sql/schema/migrate_test.go | 94 +-- dialect/sql/schema/mysql_test.go | 2 +- dialect/sql/schema/postgres_test.go | 2 +- dialect/sql/schema/sqlite_test.go | 2 +- doc/md/versioned-migrations.md | 296 +++---- .../dialect/sql/feature/migrate_diff.tmpl | 11 + entc/integration/customid/customid_test.go | 6 +- entc/integration/integration_test.go | 2 - entc/integration/migrate/migrate_test.go | 102 ++- .../migrate/versioned/migrate/migrate.go | 12 + .../migrate/versioned/migrate/schema.go | 4 +- .../migrate/versioned/schema/group.go | 6 +- .../multischema/multischema_test.go | 3 +- go.mod | 8 +- go.sum | 670 +-------------- 19 files changed, 828 insertions(+), 1475 deletions(-) delete mode 100644 dialect/sql/schema/atlas_test.go diff --git a/.golangci.yml b/.golangci.yml index 8335b6ef5..5f14c9d96 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -69,3 +69,7 @@ issues: - path: entc/gen/graph.go linters: - gocritic + - path: entc/integration/multischema/multischema_test.go + linters: + - staticcheck + text: SA1019 diff --git a/dialect/sql/schema/atlas.go b/dialect/sql/schema/atlas.go index 838aa1a48..4599ba9a1 100644 --- a/dialect/sql/schema/atlas.go +++ b/dialect/sql/schema/atlas.go @@ -6,23 +6,227 @@ package schema import ( "context" + "crypto/md5" "database/sql" "errors" "fmt" - "io/fs" - "io/ioutil" + "net/url" "sort" "strings" "ariga.io/atlas/sql/migrate" "ariga.io/atlas/sql/schema" + "ariga.io/atlas/sql/sqlclient" "ariga.io/atlas/sql/sqltool" - "entgo.io/ent/dialect" entsql "entgo.io/ent/dialect/sql" "entgo.io/ent/schema/field" ) +// Atlas atlas migration engine. +type Atlas struct { + atDriver migrate.Driver + sqlDialect sqlDialect + + legacy bool // if the legacy migration engine instead of Atlas should be used + withFixture bool // deprecated: with fks rename fixture + sum bool // deprecated: sum file generation will be required + + universalID bool // global unique ids + dropColumns bool // drop deleted columns + dropIndexes bool // drop deleted indexes + withForeignKeys bool // with foreign keys + mode Mode + hooks []Hook // hooks to apply before creation + diffHooks []DiffHook // diff hooks to run when diffing current and desired + applyHook []ApplyHook // apply hooks to run when applying the plan + skip ChangeKind // what changes to skip and not apply + dir migrate.Dir // the migration directory to read from + fmt migrate.Formatter // how to format the plan into migration files + + driver dialect.Driver // driver passed in when not using an atlas URL + url *url.URL // url of database connection + dialect string // Ent dialect to use when generating migration files + + types []string // pre-existing pk range allocation for global unique id +} + +// Diff compares the state read from a database connection or migration directory with the state defined by the Ent +// schema. Changes will be written to new migration files. +func Diff(ctx context.Context, u, name string, tables []*Table, opts ...MigrateOption) (err error) { + m, err := NewMigrateURL(u, opts...) + if err != nil { + return err + } + return m.NamedDiff(ctx, name, tables...) +} + +// NewMigrate creates a new Atlas form the given dialect.Driver. +func NewMigrate(drv dialect.Driver, opts ...MigrateOption) (*Atlas, error) { + a := &Atlas{driver: drv, withForeignKeys: true, mode: ModeInspect, sum: true} + for _, opt := range opts { + opt(a) + } + a.dialect = a.driver.Dialect() + if err := a.init(); err != nil { + return nil, err + } + return a, nil +} + +// NewMigrateURL create a new Atlas from the given url. +func NewMigrateURL(u string, opts ...MigrateOption) (*Atlas, error) { + parsed, err := url.Parse(u) + if err != nil { + return nil, err + } + a := &Atlas{url: parsed, withForeignKeys: true, mode: ModeInspect, sum: true} + for _, opt := range opts { + opt(a) + } + if a.dialect == "" { + a.dialect = parsed.Scheme + } + if err := a.init(); err != nil { + return nil, err + } + return a, nil +} + +// Create creates all schema resources in the database. It works in an "append-only" +// mode, which means, it only creates tables, appends columns to tables or modifies column types. +// +// Column can be modified by turning into a NULL from NOT NULL, or having a type conversion not +// resulting data altering. From example, changing varchar(255) to varchar(120) is invalid, but +// changing varchar(120) to varchar(255) is valid. For more info, see the convert function below. +func (a *Atlas) Create(ctx context.Context, tables ...*Table) (err error) { + a.setupTables(tables) + var creator Creator = CreateFunc(a.create) + if a.legacy { + m, err := a.legacyMigrate() + if err != nil { + return err + } + creator = CreateFunc(m.create) + } + for i := len(a.hooks) - 1; i >= 0; i-- { + creator = a.hooks[i](creator) + } + return creator.Create(ctx, tables...) +} + +// Diff compares the state read from the connected database with the state defined by Ent. +// Changes will be written to migration files by the configured Planner. +func (a *Atlas) Diff(ctx context.Context, tables ...*Table) error { + return a.NamedDiff(ctx, "changes", tables...) +} + +// NamedDiff compares the state read from the connected database with the state defined by Ent. +// Changes will be written to migration files by the configured Planner. +func (a *Atlas) NamedDiff(ctx context.Context, name string, tables ...*Table) error { + if a.dir == nil { + return errors.New("no migration directory given") + } + opts := []migrate.PlannerOption{migrate.WithFormatter(a.fmt)} + if a.sum { + // Validate the migration directory before proceeding. + if err := migrate.Validate(a.dir); err != nil { + return fmt.Errorf("validating migration directory: %w", err) + } + } else { + opts = append(opts, migrate.DisableChecksum()) + } + a.setupTables(tables) + // Set up connections. + if a.driver != nil { + var err error + a.sqlDialect, err = a.entDialect(a.driver) + if err != nil { + return err + } + a.atDriver, err = a.sqlDialect.atOpen(a.sqlDialect) + if err != nil { + return err + } + } else { + c, err := sqlclient.OpenURL(ctx, a.url) + if err != nil { + return err + } + defer c.Close() + a.sqlDialect, err = a.entDialect(entsql.OpenDB(a.dialect, c.DB)) + if err != nil { + return err + } + a.atDriver = c.Driver + } + defer func() { + a.sqlDialect = nil + a.atDriver = nil + }() + if err := a.sqlDialect.init(ctx, a.sqlDialect); err != nil { + return err + } + if a.universalID { + tables = append(tables, NewTable(TypeTable). + AddPrimary(&Column{Name: "id", Type: field.TypeUint, Increment: true}). + AddColumn(&Column{Name: "type", Type: field.TypeString, Unique: true}), + ) + } + switch a.mode { + case ModeInspect: + // Do nothing here, simply inspect later on. + case ModeReplay: + // We consider a database clean if there are no tables in the connected schema. + s, err := a.atDriver.InspectSchema(ctx, "", nil) + if err != nil { + return err + } + if len(s.Tables) > 0 { + return migrate.ErrNotClean + } + // Clean up once done. + defer func() { + // We clean a database by dropping all tables inside the connected schema. + s, err = a.atDriver.InspectSchema(ctx, "", nil) + if err != nil { + return + } + tbls := make([]schema.Change, len(s.Tables)) + for i, t := range s.Tables { + tbls[i] = &schema.DropTable{T: t} + } + if err2 := a.atDriver.ApplyChanges(ctx, tbls); err2 != nil { + if err != nil { + err = fmt.Errorf("%v: %w", err2, err) + return + } + err = err2 + return + } + }() + // Replay the migration directory on the database. + ex, err := migrate.NewExecutor(a.atDriver, a.dir, &migrate.NopRevisionReadWriter{}) + if err != nil { + return err + } + if err := ex.ExecuteN(ctx, 0); err != nil && !errors.Is(err, migrate.ErrNoPendingFiles) { + return err + } + default: + return fmt.Errorf("unknown migration mode: %q", a.mode) + } + plan, err := a.plan(ctx, a.sqlDialect, name, tables) + if err != nil { + return err + } + // Skip if the plan has no changes. + if len(plan.Changes) == 0 { + return nil + } + return migrate.NewPlanner(nil, a.dir, opts...).WritePlan(plan) +} + type ( // Differ is the interface that wraps the Diff method. Differ interface { @@ -59,8 +263,8 @@ func (f DiffFunc) Diff(current, desired *schema.Schema) ([]schema.Change, error) // }) // func WithDiffHook(hooks ...DiffHook) MigrateOption { - return func(m *Migrate) { - m.atlas.diff = append(m.atlas.diff, hooks...) + return func(a *Atlas) { + a.diffHooks = append(a.diffHooks, hooks...) } } @@ -70,8 +274,8 @@ func WithDiffHook(hooks ...DiffHook) MigrateOption { // SkipChanges(schema.DropTable|schema.DropColumn) // func WithSkipChanges(skip ChangeKind) MigrateOption { - return func(m *Migrate) { - m.atlas.skip = skip + return func(a *Atlas) { + a.skip = skip } } @@ -237,146 +441,180 @@ func (f ApplyFunc) Apply(ctx context.Context, conn dialect.ExecQuerier, plan *mi // }) // func WithApplyHook(hooks ...ApplyHook) MigrateOption { - return func(m *Migrate) { - m.atlas.apply = append(m.atlas.apply, hooks...) + return func(a *Atlas) { + a.applyHook = append(a.applyHook, hooks...) } } -// WithAtlas is an opt-in option for v0.10 indicates the migration -// should be executed using Atlas engine (i.e. https://atlasgo.io). -// Note, in future versions, this option is going to be replaced -// from opt-in to opt-out and the deprecation of this package. +// WithAtlas is an opt-out option for v0.11 indicating the migration +// should be executed using the deprecated legacy engine. +// Note, in future versions, this option is going to be removed +// and the Atlas (https://atlasgo.io) based migration engine should be used. +// +// Deprecated: The legacy engine will be removed. func WithAtlas(b bool) MigrateOption { - return func(m *Migrate) { - m.atlas.enabled = b + return func(a *Atlas) { + a.legacy = !b } } // WithDir sets the atlas migration directory to use to store migration files. func WithDir(dir migrate.Dir) MigrateOption { - return func(m *Migrate) { - m.atlas.dir = dir + return func(a *Atlas) { + a.dir = dir } } // WithFormatter sets atlas formatter to use to write changes to migration files. func WithFormatter(fmt migrate.Formatter) MigrateOption { - return func(m *Migrate) { - m.atlas.fmt = fmt + return func(a *Atlas) { + a.fmt = fmt } } -// WithSumFile instructs atlas to generate a migration directory integrity sum file as well. -func WithSumFile() MigrateOption { - return func(m *Migrate) { - m.atlas.genSum = true +// WithDialect configures the Ent dialect to use when migrating for an Atlas supported dialect flavor. +// As an example, Ent can work with TiDB in MySQL dialect and Atlas can handle TiDB migrations. +func WithDialect(d string) MigrateOption { + return func(a *Atlas) { + a.dialect = d } } -// WithUniversalID instructs atlas to use a file based type store when -// global unique ids are enabled. For more information see the setupAtlas method on Migrate. +// WithSumFile instructs atlas to generate a migration directory integrity sum file. // -// ATTENTION: -// The file based PK range store is not backward compatible, since the allocated ranges were computed -// dynamically when computing the diff between a deployed database and the current schema. In cases where there -// exist multiple deployments, the allocated ranges for the same type might be different from each other, -// depending on when the deployment took part. -func WithUniversalID() MigrateOption { - return func(m *Migrate) { - m.universalID = true - m.atlas.typeStoreConsent = true +// Deprecated: generating the sum file is now opt-out. This method will be removed in future versions. +func WithSumFile() MigrateOption { + return func(a *Atlas) {} +} + +// DisableChecksum instructs atlas to skip migration directory integrity sum file generation. +// +// Deprecated: generating the sum file will no longer be optional in future versions. +func DisableChecksum() MigrateOption { + return func(a *Atlas) { + a.sum = false } } -type ( - // atlasOptions describes the options for atlas. - atlasOptions struct { - enabled bool - diff []DiffHook - apply []ApplyHook - skip ChangeKind - dir migrate.Dir - fmt migrate.Formatter - genSum bool - typeStoreConsent bool +// WithMigrationMode instructs atlas how to compute the current state of the schema. This can be done by either +// replaying (ModeReplay) the migration directory on the connected database, or by inspecting (ModeInspect) the +// connection. Currently, ModeReplay is opt-in, and ModeInspect is the default. In future versions, ModeReplay will +// become the default behavior. This option has no effect when using online migrations. +func WithMigrationMode(mode Mode) MigrateOption { + return func(a *Atlas) { + a.mode = mode } +} - // atBuilder must be implemented by the different drivers in - // order to convert a dialect/sql/schema to atlas/sql/schema. - atBuilder interface { - atOpen(dialect.ExecQuerier) (migrate.Driver, error) - atTable(*Table, *schema.Table) - atTypeC(*Column, *schema.Column) error - atUniqueC(*Table, *Column, *schema.Table, *schema.Column) - atIncrementC(*schema.Table, *schema.Column) - atIncrementT(*schema.Table, int64) - atIndex(*Index, *schema.Table, *schema.Index) error - atTypeRangeSQL(t ...string) string - } +// Mode to compute the current state. +type Mode uint + +const ( + // ModeReplay computes the current state by replaying the migration directory on the connected database. + ModeReplay = iota + // ModeInspect computes the current state by inspecting the connected database. + ModeInspect ) -var errConsent = errors.New("sql/schema: use WithUniversalID() instead of WithGlobalUniqueID(true) when using WithDir(): https://entgo.io/docs/migrate#universal-ids") +// StateReader returns an atlas migrate.StateReader returning the state as described by the Ent table slice. +func (a *Atlas) StateReader(tables ...*Table) migrate.StateReaderFunc { + return func(context.Context) (*schema.Realm, error) { + ts, err := a.tables(tables) + if err != nil { + return nil, err + } + return &schema.Realm{Schemas: []*schema.Schema{{Tables: ts}}}, nil + } +} -func (m *Migrate) setupAtlas() error { - // Using one of the Atlas options, opt-in to Atlas migration. - if !m.atlas.enabled && (m.atlas.skip != NoChange || len(m.atlas.diff) > 0 || len(m.atlas.apply) > 0) || m.atlas.dir != nil { - m.atlas.enabled = true - } - if !m.atlas.enabled { - return nil - } - if m.withFixture { - return errors.New("sql/schema: WithFixture(true) does not work in Atlas migration") - } +// atBuilder must be implemented by the different drivers in +// order to convert a dialect/sql/schema to atlas/sql/schema. +type atBuilder interface { + atOpen(dialect.ExecQuerier) (migrate.Driver, error) + atTable(*Table, *schema.Table) + atTypeC(*Column, *schema.Column) error + atUniqueC(*Table, *Column, *schema.Table, *schema.Column) + atIncrementC(*schema.Table, *schema.Column) + atIncrementT(*schema.Table, int64) + atIndex(*Index, *schema.Table, *schema.Index) error + atTypeRangeSQL(t ...string) string +} + +// init initializes the configuration object based on the options passed in. +func (a *Atlas) init() error { skip := DropIndex | DropColumn - if m.atlas.skip != NoChange { - skip = m.atlas.skip + if a.skip != NoChange { + skip = a.skip } - if m.dropIndexes { + if a.dropIndexes { skip &= ^DropIndex } - if m.dropColumns { + if a.dropColumns { skip &= ^DropColumn } if skip != NoChange { - m.atlas.diff = append(m.atlas.diff, filterChanges(skip)) + a.diffHooks = append(a.diffHooks, filterChanges(skip)) } - if !m.withForeignKeys { - m.atlas.diff = append(m.atlas.diff, withoutForeignKeys) + if !a.withForeignKeys { + a.diffHooks = append(a.diffHooks, withoutForeignKeys) } - if m.atlas.dir != nil && m.atlas.fmt == nil { - m.atlas.fmt = sqltool.GolangMigrateFormatter + if a.dir != nil && a.fmt == nil { + a.fmt = sqltool.GolangMigrateFormatter } - if m.universalID && m.atlas.dir != nil { - // If global unique ids and a migration directory is given, enable the file based type store for pk ranges. - m.typeStore = &dirTypeStore{dir: m.atlas.dir} - // To guard the user against a possible bug due to backward incompatibility, the file based type store must - // be enabled by an option. For more information see the comment of WithUniversalID function. - if !m.atlas.typeStoreConsent { - return errConsent + if a.mode == ModeReplay { + // ModeReplay requires a migration directory. + if a.dir == nil { + return errors.New("sql/schema: WithMigrationMode(ModeReplay) requires versioned migrations: WithDir()") + } + // ModeReplay requires sum file generation. + if !a.sum { + return errors.New("sql/schema: WithMigrationMode(ModeReplay) requires migration directory integrity file") } - m.atlas.diff = append(m.atlas.diff, m.ensureTypeTable) } return nil } -func (m *Migrate) atCreate(ctx context.Context, tables ...*Table) error { +// create is the Atlas engine based online migration. +func (a *Atlas) create(ctx context.Context, tables ...*Table) (err error) { + if a.universalID { + tables = append(tables, NewTable(TypeTable). + AddPrimary(&Column{Name: "id", Type: field.TypeUint, Increment: true}). + AddColumn(&Column{Name: "type", Type: field.TypeString, Unique: true}), + ) + } + if a.driver != nil { + a.sqlDialect, err = a.entDialect(a.driver) + if err != nil { + return err + } + } else { + c, err := sqlclient.OpenURL(ctx, a.url) + if err != nil { + return err + } + defer c.Close() + a.sqlDialect, err = a.entDialect(entsql.OpenDB(a.dialect, c.DB)) + if err != nil { + return err + } + } + defer func() { a.sqlDialect = nil }() // Open a transaction for backwards compatibility, // even if the migration is not transactional. - tx, err := m.Tx(ctx) + tx, err := a.sqlDialect.Tx(ctx) if err != nil { return err } + if err := a.sqlDialect.init(ctx, tx); err != nil { + return err + } + a.atDriver, err = a.sqlDialect.atOpen(tx) + if err != nil { + return err + } + defer func() { a.atDriver = nil }() if err := func() error { - if err := m.init(ctx, tx); err != nil { - return err - } - if m.universalID { - if err := m.types(ctx, tx); err != nil { - return err - } - } - plan, err := m.atDiff(ctx, tx, "", tables...) + plan, err := a.plan(ctx, tx, "changes", tables) if err != nil { return err } @@ -392,22 +630,25 @@ func (m *Migrate) atCreate(ctx context.Context, tables ...*Table) error { } return nil }) - for i := len(m.atlas.apply) - 1; i >= 0; i-- { - applier = m.atlas.apply[i](applier) + for i := len(a.applyHook) - 1; i >= 0; i-- { + applier = a.applyHook[i](applier) } return applier.Apply(ctx, tx, plan) }(); err != nil { - return rollback(tx, err) + err = fmt.Errorf("sql/schema: %w", err) + if rerr := tx.Rollback(); rerr != nil { + err = fmt.Errorf("%w: %v", err, rerr) + } + return err } return tx.Commit() } -func (m *Migrate) atDiff(ctx context.Context, conn dialect.ExecQuerier, name string, tables ...*Table) (*migrate.Plan, error) { - drv, err := m.atOpen(conn) - if err != nil { - return nil, err - } - current, err := drv.InspectSchema(ctx, "", &schema.InspectOptions{ +// plan creates the current state by inspecting the connected database, computing the current state of the Ent schema +// and proceeds to diff the changes to create a migration plan. +// before diffing. +func (a *Atlas) plan(ctx context.Context, conn dialect.ExecQuerier, name string, tables []*Table) (*migrate.Plan, error) { + current, err := a.atDriver.InspectSchema(ctx, "", &schema.InspectOptions{ Tables: func() (t []string) { for i := range tables { t = append(t, tables[i].Name) @@ -418,21 +659,55 @@ func (m *Migrate) atDiff(ctx context.Context, conn dialect.ExecQuerier, name str if err != nil { return nil, err } - tt, err := m.aTables(ctx, m, conn, tables) + var types []string + if a.universalID { + // Fetch pre-existing type allocations. + exists, err := a.sqlDialect.tableExist(ctx, conn, TypeTable) + if err != nil { + return nil, err + } + if exists { + rows := &entsql.Rows{} + query, args := entsql.Dialect(a.dialect). + Select("type").From(entsql.Table(TypeTable)).OrderBy(entsql.Asc("id")).Query() + if err := conn.Query(ctx, query, args, rows); err != nil { + return nil, fmt.Errorf("query types table: %w", err) + } + defer rows.Close() + a.types = nil + if err := entsql.ScanSlice(rows, &a.types); err != nil { + return nil, err + } + } + types = a.types + } + desired, err := a.StateReader(tables...).ReadState(ctx) if err != nil { return nil, err } // Diff changes. - var differ Differ = DiffFunc(drv.SchemaDiff) - for i := len(m.atlas.diff) - 1; i >= 0; i-- { - differ = m.atlas.diff[i](differ) - } - changes, err := differ.Diff(current, &schema.Schema{Name: current.Name, Attrs: current.Attrs, Tables: tt}) + changes, err := (&diffDriver{a.atDriver, a.diffHooks}).SchemaDiff(current, &schema.Schema{ + Name: current.Name, + Attrs: current.Attrs, + Tables: desired.Schemas[0].Tables, + }) if err != nil { return nil, err } // Plan changes. - return drv.PlanChanges(ctx, name, changes) + plan, err := a.atDriver.PlanChanges(ctx, name, changes) + if err != nil { + return nil, err + } + // Insert new types. + newTypes := a.types[len(types):] + if len(newTypes) > 0 { + plan.Changes = append(plan.Changes, &migrate.Change{ + Cmd: a.sqlDialect.atTypeRangeSQL(newTypes...), + Comment: fmt.Sprintf("add pk ranges for %s tables", strings.Join(newTypes, ",")), + }) + } + return plan, nil } type db struct{ dialect.ExecQuerier } @@ -453,28 +728,29 @@ func (d *db) ExecContext(ctx context.Context, query string, args ...interface{}) return r, nil } -func (m *Migrate) aTables(ctx context.Context, b atBuilder, conn dialect.ExecQuerier, tables1 []*Table) ([]*schema.Table, error) { - tables2 := make([]*schema.Table, len(tables1)) - for i, t1 := range tables1 { - t2 := schema.NewTable(t1.Name) - b.atTable(t1, t2) - if m.universalID { - r, err := m.pkRange(ctx, conn, t1) +// tables converts an Ent table slice to an atlas table slice +func (a *Atlas) tables(tables []*Table) ([]*schema.Table, error) { + ts := make([]*schema.Table, len(tables)) + for i, et := range tables { + at := schema.NewTable(et.Name) + a.sqlDialect.atTable(et, at) + if a.universalID && et.Name != TypeTable { + r, err := a.pkRange(et) if err != nil { return nil, err } - b.atIncrementT(t2, r) + a.sqlDialect.atIncrementT(at, r) } - if err := m.aColumns(b, t1, t2); err != nil { + if err := a.aColumns(et, at); err != nil { return nil, err } - if err := m.aIndexes(b, t1, t2); err != nil { + if err := a.aIndexes(et, at); err != nil { return nil, err } - tables2[i] = t2 + ts[i] = at } - for i, t1 := range tables1 { - t2 := tables2[i] + for i, t1 := range tables { + t2 := ts[i] for _, fk1 := range t1.ForeignKeys { fk2 := schema.NewForeignKey(fk1.Symbol). SetTable(t2). @@ -488,7 +764,7 @@ func (m *Migrate) aTables(ctx context.Context, b atBuilder, conn dialect.ExecQue fk2.AddColumns(c2) } var refT *schema.Table - for _, t2 := range tables2 { + for _, t2 := range ts { if t2.Name == fk1.RefTable.Name { refT = t2 break @@ -508,17 +784,17 @@ func (m *Migrate) aTables(ctx context.Context, b atBuilder, conn dialect.ExecQue t2.AddForeignKeys(fk2) } } - return tables2, nil + return ts, nil } -func (m *Migrate) aColumns(b atBuilder, t1 *Table, t2 *schema.Table) error { - for _, c1 := range t1.Columns { +func (a *Atlas) aColumns(et *Table, at *schema.Table) error { + for _, c1 := range et.Columns { c2 := schema.NewColumn(c1.Name). SetNull(c1.Nullable) if c1.Collation != "" { c2.SetCollation(c1.Collation) } - if err := b.atTypeC(c1, c2); err != nil { + if err := a.sqlDialect.atTypeC(c1, c2); err != nil { return err } if c1.Default != nil && c1.supportDefault() { @@ -530,106 +806,128 @@ func (m *Migrate) aColumns(b atBuilder, t1 *Table, t2 *schema.Table) error { } c2.SetDefault(&schema.RawExpr{X: x}) } - if c1.Unique && (len(t1.PrimaryKey) != 1 || t1.PrimaryKey[0] != c1) { - b.atUniqueC(t1, c1, t2, c2) + if c1.Unique && (len(et.PrimaryKey) != 1 || et.PrimaryKey[0] != c1) { + a.sqlDialect.atUniqueC(et, c1, at, c2) } if c1.Increment { - b.atIncrementC(t2, c2) + a.sqlDialect.atIncrementC(at, c2) } - t2.AddColumns(c2) + at.AddColumns(c2) } return nil } -func (m *Migrate) aIndexes(b atBuilder, t1 *Table, t2 *schema.Table) error { +func (a *Atlas) aIndexes(et *Table, at *schema.Table) error { // Primary-key index. - pk := make([]*schema.Column, 0, len(t1.PrimaryKey)) - for _, c1 := range t1.PrimaryKey { - c2, ok := t2.Column(c1.Name) + pk := make([]*schema.Column, 0, len(et.PrimaryKey)) + for _, c1 := range et.PrimaryKey { + c2, ok := at.Column(c1.Name) if !ok { return fmt.Errorf("unexpected primary-key column: %q", c1.Name) } pk = append(pk, c2) } - t2.SetPrimaryKey(schema.NewPrimaryKey(pk...)) + at.SetPrimaryKey(schema.NewPrimaryKey(pk...)) // Rest of indexes. - for _, idx1 := range t1.Indexes { + for _, idx1 := range et.Indexes { idx2 := schema.NewIndex(idx1.Name). SetUnique(idx1.Unique) - if err := b.atIndex(idx1, t2, idx2); err != nil { + if err := a.sqlDialect.atIndex(idx1, at, idx2); err != nil { return err } desc := descIndexes(idx1) for _, p := range idx2.Parts { p.Desc = desc[p.C.Name] } - t2.AddIndexes(idx2) + at.AddIndexes(idx2) } return nil } -func (m *Migrate) ensureTypeTable(next Differ) Differ { - return DiffFunc(func(current, desired *schema.Schema) ([]schema.Change, error) { - // If there is a types table but no types file yet, the user most likely - // switched from online migration to migration files. - if len(m.dbTypeRanges) == 0 { - var ( - at = schema.NewTable(TypeTable) - et = NewTable(TypeTable). - AddPrimary(&Column{Name: "id", Type: field.TypeUint, Increment: true}). - AddColumn(&Column{Name: "type", Type: field.TypeString, Unique: true}) - ) - m.atTable(et, at) - if err := m.aColumns(m, et, at); err != nil { - return nil, err +// setupTables ensures the table is configured properly, like table columns +// are linked to their indexes, and PKs columns are defined. +func (a *Atlas) setupTables(tables []*Table) { + for _, t := range tables { + if t.columns == nil { + t.columns = make(map[string]*Column, len(t.Columns)) + } + for _, c := range t.Columns { + t.columns[c.Name] = c + } + for _, idx := range t.Indexes { + idx.Name = a.symbol(idx.Name) + for _, c := range idx.Columns { + c.indexes.append(idx) } - if err := m.aIndexes(m, et, at); err != nil { - return nil, err + } + for _, pk := range t.PrimaryKey { + c := t.columns[pk.Name] + c.Key = PrimaryKey + pk.Key = PrimaryKey + } + for _, fk := range t.ForeignKeys { + fk.Symbol = a.symbol(fk.Symbol) + for i := range fk.Columns { + fk.Columns[i].foreign = fk } - desired.Tables = append(desired.Tables, at) } - // If there is a drift between the types stored in the database and the ones stored in the file, - // stop diffing, as this is potentially destructive. This will most likely happen on the first diffing - // after moving from online-migration to versioned migrations if the "old" ent types are not in sync with - // the deterministic ones computed by the new engine. - if len(m.dbTypeRanges) > 0 && len(m.fileTypeRanges) > 0 && !equal(m.fileTypeRanges, m.dbTypeRanges) { - return nil, fmt.Errorf( - "type allocation range drift detected: %v <> %v: see %s for more information", - m.dbTypeRanges, m.fileTypeRanges, - "https://entgo.io/docs/versioned-migrations#moving-from-auto-migration-to-versioned-migrations", - ) - } - changes, err := next.Diff(current, desired) - if err != nil { - return nil, err - } - if len(m.dbTypeRanges) > 0 && len(m.fileTypeRanges) == 0 { - // Override the types file created in the diff process with the "old" allocated types ranges. - if err := m.typeStore.(*dirTypeStore).save(m.dbTypeRanges); err != nil { - return nil, err - } - // Change the type range allocations since they will be added to the migration files when - // writing the migration plan to migration files. - m.typeRanges = m.dbTypeRanges - } - return changes, nil - }) + } } -func setAtChecks(t1 *Table, t2 *schema.Table) { - if check := t1.Annotation.Check; check != "" { - t2.AddChecks(&schema.Check{ +// symbol makes sure the symbol length is not longer than the maxlength in the dialect. +func (a *Atlas) symbol(name string) string { + size := 64 + if a.dialect == dialect.Postgres { + size = 63 + } + if len(name) <= size { + return name + } + return fmt.Sprintf("%s_%x", name[:size-33], md5.Sum([]byte(name))) +} + +// entDialect returns the Ent dialect as configured by the dialect option. +func (a *Atlas) entDialect(drv dialect.Driver) (sqlDialect, error) { + switch a.dialect { + case dialect.MySQL: + return &MySQL{Driver: drv}, nil + case dialect.SQLite: + return &SQLite{Driver: drv, WithForeignKeys: a.withForeignKeys}, nil + case dialect.Postgres: + return &Postgres{Driver: drv}, nil + default: + return nil, fmt.Errorf("sql/schema: unsupported dialect %q", a.dialect) + } +} + +func (a *Atlas) pkRange(et *Table) (int64, error) { + idx := indexOf(a.types, et.Name) + // If the table re-created, re-use its range from + // the past. Otherwise, allocate a new id-range. + if idx == -1 { + if len(a.types) > MaxTypes { + return 0, fmt.Errorf("max number of types exceeded: %d", MaxTypes) + } + idx = len(a.types) + a.types = append(a.types, et.Name) + } + return int64(idx << 32), nil +} + +func setAtChecks(et *Table, at *schema.Table) { + if check := et.Annotation.Check; check != "" { + at.AddChecks(&schema.Check{ Expr: check, }) } - if checks := t1.Annotation.Checks; len(t1.Annotation.Checks) > 0 { + if checks := et.Annotation.Checks; len(et.Annotation.Checks) > 0 { names := make([]string, 0, len(checks)) for name := range checks { names = append(names, name) } sort.Strings(names) for _, name := range names { - t2.AddChecks(&schema.Check{ + at.AddChecks(&schema.Check{ Name: name, Expr: checks[name], }) @@ -654,61 +952,49 @@ func descIndexes(idx *Index) map[string]bool { return descs } -const entTypes = ".ent_types" - -// dirTypeStore stores and read pk information from a text file stored alongside generated versioned migrations. -// This behaviour is enabled automatically when using versioned migrations. -type dirTypeStore struct { - dir migrate.Dir +// driver decorates the atlas migrate.Driver and adds "diff hooking" and functionality. +type diffDriver struct { + migrate.Driver + hooks []DiffHook // hooks to apply } -const atlasDirective = "atlas:sum ignore\n" - -// load the types from the types file. -func (s *dirTypeStore) load(context.Context, dialect.ExecQuerier) ([]string, error) { - f, err := s.dir.Open(entTypes) - if err != nil && !errors.Is(err, fs.ErrNotExist) { - return nil, fmt.Errorf("reading types file: %w", err) - } - if errors.Is(err, fs.ErrNotExist) { - return nil, nil - } - defer f.Close() - c, err := ioutil.ReadAll(f) - if err != nil { - return nil, fmt.Errorf("reading types file: %w", err) - } - return strings.Split(strings.TrimPrefix(string(c), atlasDirective), ","), nil +// RealmDiff creates the diff between two realms. Since Ent does not care about Realms, +// not even schema changes, calling this method raises an error. +func (r *diffDriver) RealmDiff(_, _ *schema.Realm) ([]schema.Change, error) { + return nil, errors.New("sqlDialect does not support working with realms") } -// add a new type entry to the types file. -func (s *dirTypeStore) add(ctx context.Context, conn dialect.ExecQuerier, t string) error { - ts, err := s.load(ctx, conn) - if err != nil { - return fmt.Errorf("adding type %q: %w", t, err) +// SchemaDiff creates the diff between two schemas, but includes "diff hooks". +func (r *diffDriver) SchemaDiff(from, to *schema.Schema) ([]schema.Change, error) { + var d Differ = DiffFunc(r.Driver.SchemaDiff) + for i := len(r.hooks) - 1; i >= 0; i-- { + d = r.hooks[i](d) } - return s.save(append(ts, t)) + return d.Diff(from, to) } -// save takes the given allocation range and writes them to the types file. -// The types file will be overridden. -func (s *dirTypeStore) save(ts []string) error { - if err := s.dir.WriteFile(entTypes, []byte(atlasDirective+strings.Join(ts, ","))); err != nil { - return fmt.Errorf("writing types file: %w", err) +// legacyMigrate returns a configured legacy migration engine (before Atlas) to keep backwards compatibility. +// +// Deprecated: Will be removed alongside legacy migration support. +func (a *Atlas) legacyMigrate() (*Migrate, error) { + m := &Migrate{ + universalID: a.universalID, + dropColumns: a.dropColumns, + dropIndexes: a.dropIndexes, + withFixture: a.withFixture, + withForeignKeys: a.withForeignKeys, + hooks: a.hooks, + atlas: a, } - return nil -} - -var _ typeStore = (*dirTypeStore)(nil) - -func equal(s1, s2 []string) bool { - if len(s1) != len(s2) { - return false - } - for i := range s1 { - if s1[i] != s2[i] { - return false - } - } - return true + switch a.dialect { + case dialect.MySQL: + m.sqlDialect = &MySQL{Driver: a.driver} + case dialect.SQLite: + m.sqlDialect = &SQLite{Driver: a.driver, WithForeignKeys: a.withForeignKeys} + case dialect.Postgres: + m.sqlDialect = &Postgres{Driver: a.driver} + default: + return nil, fmt.Errorf("sql/schema: unsupported dialect %q", a.dialect) + } + return m, nil } diff --git a/dialect/sql/schema/atlas_test.go b/dialect/sql/schema/atlas_test.go deleted file mode 100644 index 4d4b79429..000000000 --- a/dialect/sql/schema/atlas_test.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2019-present Facebook Inc. All rights reserved. -// This source code is licensed under the Apache 2.0 license found -// in the LICENSE file in the root directory of this source tree. - -package schema - -import ( - "context" - "os" - "path/filepath" - "testing" - - "ariga.io/atlas/sql/migrate" - "github.com/stretchr/testify/require" -) - -func TestDirTypeStore(t *testing.T) { - ex := []string{"a", "b", "c"} - p := t.TempDir() - d, err := migrate.NewLocalDir(p) - require.NoError(t, err) - - s := &dirTypeStore{d} - require.NoError(t, s.save(ex)) - require.FileExists(t, filepath.Join(p, entTypes)) - c, err := os.ReadFile(filepath.Join(p, entTypes)) - require.NoError(t, err) - require.Contains(t, string(c), atlasDirective) - - ac, err := s.load(context.Background(), nil) - require.NoError(t, err) - require.Equal(t, ex, ac) -} diff --git a/dialect/sql/schema/migrate.go b/dialect/sql/schema/migrate.go index fd623464d..b666feb24 100644 --- a/dialect/sql/schema/migrate.go +++ b/dialect/sql/schema/migrate.go @@ -6,13 +6,9 @@ package schema import ( "context" - "crypto/md5" - "errors" "fmt" "math" - "strings" - "ariga.io/atlas/sql/migrate" "entgo.io/ent/dialect" "entgo.io/ent/dialect/sql" "entgo.io/ent/schema/field" @@ -21,57 +17,61 @@ import ( const ( // TypeTable defines the table name holding the type information. TypeTable = "ent_types" + // MaxTypes defines the max number of types can be created when // defining universal ids. The left 16-bits are reserved. MaxTypes = math.MaxUint16 ) -// MigrateOption allows for managing schema configuration using functional options. -type MigrateOption func(*Migrate) +// MigrateOption allows configuring Atlas using functional arguments. +type MigrateOption func(*Atlas) // WithGlobalUniqueID sets the universal ids options to the migration. // Defaults to false. func WithGlobalUniqueID(b bool) MigrateOption { - return func(m *Migrate) { - m.universalID = b + return func(a *Atlas) { + a.universalID = b } } // WithDropColumn sets the columns dropping option to the migration. // Defaults to false. func WithDropColumn(b bool) MigrateOption { - return func(m *Migrate) { - m.dropColumns = b + return func(a *Atlas) { + a.dropColumns = b } } // WithDropIndex sets the indexes dropping option to the migration. // Defaults to false. func WithDropIndex(b bool) MigrateOption { - return func(m *Migrate) { - m.dropIndexes = b + return func(a *Atlas) { + a.dropIndexes = b } } // WithFixture sets the foreign-key renaming option to the migration when upgrading -// ent from v0.1.0 (issue-#285). Defaults to false. +// sqlDialect from v0.1.0 (issue-#285). Defaults to false. +// +// Deprecated: This option is no longer needed with the Atlas based +// migration engine, which now is the default. func WithFixture(b bool) MigrateOption { - return func(m *Migrate) { - m.withFixture = b + return func(a *Atlas) { + a.withFixture = b } } // WithForeignKeys enables creating foreign-key in ddl. Defaults to true. func WithForeignKeys(b bool) MigrateOption { - return func(m *Migrate) { - m.withForeignKeys = b + return func(a *Atlas) { + a.withForeignKeys = b } } // WithHooks adds a list of hooks to the schema migration. func WithHooks(hooks ...Hook) MigrateOption { - return func(m *Migrate) { - m.hooks = append(m.hooks, hooks...) + return func(a *Atlas) { + a.hooks = append(a.hooks, hooks...) } } @@ -105,42 +105,19 @@ func (f CreateFunc) Create(ctx context.Context, tables ...*Table) error { } // Migrate runs the migration logic for the SQL dialects. +// +// Deprecated: Use the new Atlas struct instead. type Migrate struct { sqlDialect - universalID bool // global unique ids. - dropColumns bool // drop deleted columns. - dropIndexes bool // drop deleted indexes. - withFixture bool // with fks rename fixture. - withForeignKeys bool // with foreign keys - atlas *atlasOptions // migrate with atlas. - typeRanges []string // types order by their range. - hooks []Hook // hooks to apply before creation - typeStore typeStore // the typeStore to read and save type ranges - fileTypeRanges []string // used internally by ensureTypeTable hook - dbTypeRanges []string // used internally by ensureTypeTable hook -} + atlas *Atlas // Atlas this Migrate is based on -// NewMigrate create a migration structure for the given SQL driver. -func NewMigrate(d dialect.Driver, opts ...MigrateOption) (*Migrate, error) { - m := &Migrate{withForeignKeys: true, atlas: &atlasOptions{}} - for _, opt := range opts { - opt(m) - } - switch d.Dialect() { - case dialect.MySQL: - m.sqlDialect = &MySQL{Driver: d} - case dialect.SQLite: - m.sqlDialect = &SQLite{Driver: d, WithForeignKeys: m.withForeignKeys} - case dialect.Postgres: - m.sqlDialect = &Postgres{Driver: d} - default: - return nil, fmt.Errorf("sql/schema: unsupported dialect %q", d.Dialect()) - } - m.typeStore = &dbTypeStore{m.sqlDialect} - if err := m.setupAtlas(); err != nil { - return nil, err - } - return m, nil + universalID bool // global unique ids + dropColumns bool // drop deleted columns + dropIndexes bool // drop deleted indexes + withFixture bool // with fks rename fixture + withForeignKeys bool // with foreign keys + typeRanges []string // types order by their range + hooks []Hook // hooks to apply before creation } // Create creates all schema resources in the database. It works in an "append-only" @@ -155,82 +132,12 @@ func NewMigrate(d dialect.Driver, opts ...MigrateOption) (*Migrate, error) { func (m *Migrate) Create(ctx context.Context, tables ...*Table) error { m.setupTables(tables) var creator Creator = CreateFunc(m.create) - if m.atlas.enabled { - creator = CreateFunc(m.atCreate) - } for i := len(m.hooks) - 1; i >= 0; i-- { creator = m.hooks[i](creator) } return creator.Create(ctx, tables...) } -// Diff compares the state read from the connected database with the state defined by Ent. -// Changes will be written to migration files by the configured Planner. -func (m *Migrate) Diff(ctx context.Context, tables ...*Table) error { - return m.NamedDiff(ctx, "changes", tables...) -} - -// NamedDiff compares the state read from the connected database with the state defined by Ent. -// Changes will be written to migration files by the configured Planner. -func (m *Migrate) NamedDiff(ctx context.Context, name string, tables ...*Table) error { - if m.atlas.dir == nil { - return errors.New("no migration directory given") - } - opts := []migrate.PlannerOption{ - migrate.WithFormatter(m.atlas.fmt), - } - if m.atlas.genSum { - // Validate the migration directory before proceeding. - if err := migrate.Validate(m.atlas.dir); err != nil { - return fmt.Errorf("validating migration directory: %w", err) - } - } else { - opts = append(opts, migrate.DisableChecksum()) - } - if err := m.init(ctx, m); err != nil { - return err - } - if m.universalID { - if err := m.types(ctx, m); err != nil { - return err - } - m.fileTypeRanges = m.typeRanges - ex, err := m.tableExist(ctx, m, TypeTable) - if err != nil { - return err - } - if ex { - m.dbTypeRanges, err = (&dbTypeStore{m}).load(ctx, m) - if err != nil { - return err - } - } - defer func() { - m.fileTypeRanges = nil - m.dbTypeRanges = nil - }() - } - m.setupTables(tables) - plan, err := m.atDiff(ctx, m, name, tables...) - if err != nil { - return err - } - if m.universalID { - newTypes := m.typeRanges[len(m.dbTypeRanges):] - if len(newTypes) > 0 { - plan.Changes = append(plan.Changes, &migrate.Change{ - Cmd: m.atTypeRangeSQL(newTypes...), - Comment: fmt.Sprintf("add pk ranges for %s tables", strings.Join(newTypes, ",")), - }) - } - } - // Skip if the plan has no changes. - if len(plan.Changes) == 0 { - return nil - } - return migrate.NewPlanner(nil, m.atlas.dir, opts...).WritePlan(plan) -} - func (m *Migrate) create(ctx context.Context, tables ...*Table) error { tx, err := m.Tx(ctx) if err != nil { @@ -328,7 +235,7 @@ func (m *Migrate) txCreate(ctx context.Context, tx dialect.Tx, tables ...*Table) return nil } -// apply applies changes on the given table. +// apply changes on the given table. func (m *Migrate) apply(ctx context.Context, tx dialect.Tx, table string, change *changes) error { // Constraints should be dropped before dropping columns, because if a column // is a part of multi-column constraints (like, unique index), ALTER TABLE @@ -419,7 +326,7 @@ func (m *Migrate) changeSet(curr, new *Table) (*changes, error) { case c1.Unique && !c2.Unique: // Make sure the table does not have unique index for this column // before adding it to the changeset, because there are 2 ways to - // configure uniqueness on ent.Field (using the Unique modifier or + // configure uniqueness on sqlDialect.Field (using the Unique modifier or // adding rule on the Indexes option). if idx, ok := curr.index(c1.Name); !ok || !idx.Unique { change.index.add.append(&Index{ @@ -580,10 +487,30 @@ func (m *Migrate) verify(ctx context.Context, tx dialect.Tx, t *Table) error { return vr.verifyRange(ctx, tx, t, int64(id<<32)) } -// types loads the type list from the type store. -func (m *Migrate) types(ctx context.Context, tx dialect.ExecQuerier) (err error) { - m.typeRanges, err = m.typeStore.load(ctx, tx) - return +// types loads the type list from the type store. It will create the types table, if it does not exist yet. +func (m *Migrate) types(ctx context.Context, tx dialect.ExecQuerier) error { + exists, err := m.tableExist(ctx, tx, TypeTable) + if err != nil { + return err + } + if !exists { + t := NewTable(TypeTable). + AddPrimary(&Column{Name: "id", Type: field.TypeUint, Increment: true}). + AddColumn(&Column{Name: "type", Type: field.TypeString, Unique: true}) + query, args := m.tBuilder(t).Query() + if err := tx.Exec(ctx, query, args, nil); err != nil { + return fmt.Errorf("create types table: %w", err) + } + return nil + } + rows := &sql.Rows{} + query, args := sql.Dialect(m.Dialect()). + Select("type").From(sql.Table(TypeTable)).OrderBy(sql.Asc("id")).Query() + if err := tx.Query(ctx, query, args, rows); err != nil { + return fmt.Errorf("query types table: %w", err) + } + defer rows.Close() + return sql.ScanSlice(rows, &m.typeRanges) } func (m *Migrate) allocPKRange(ctx context.Context, conn dialect.ExecQuerier, t *Table) error { @@ -602,8 +529,9 @@ func (m *Migrate) pkRange(ctx context.Context, conn dialect.ExecQuerier, t *Tabl if len(m.typeRanges) > MaxTypes { return 0, fmt.Errorf("max number of types exceeded: %d", MaxTypes) } - if err := m.typeStore.add(ctx, conn, t.Name); err != nil { - return 0, fmt.Errorf("store type range: %w", err) + query, args := sql.Dialect(m.Dialect()).Insert(TypeTable).Columns("type").Values(t.Name).Query() + if err := conn.Exec(ctx, query, args, nil); err != nil { + return 0, fmt.Errorf("insert into ent_types: %w", err) } id = len(m.typeRanges) m.typeRanges = append(m.typeRanges, t.Name) @@ -641,45 +569,7 @@ func (m *Migrate) fkColumn(ctx context.Context, tx dialect.Tx, fk *ForeignKey) ( // setup ensures the table is configured properly, like table columns // are linked to their indexes, and PKs columns are defined. -func (m *Migrate) setupTables(tables []*Table) { - for _, t := range tables { - if t.columns == nil { - t.columns = make(map[string]*Column, len(t.Columns)) - } - for _, c := range t.Columns { - t.columns[c.Name] = c - } - for _, idx := range t.Indexes { - idx.Name = m.symbol(idx.Name) - for _, c := range idx.Columns { - c.indexes.append(idx) - } - } - for _, pk := range t.PrimaryKey { - c := t.columns[pk.Name] - c.Key = PrimaryKey - pk.Key = PrimaryKey - } - for _, fk := range t.ForeignKeys { - fk.Symbol = m.symbol(fk.Symbol) - for i := range fk.Columns { - fk.Columns[i].foreign = fk - } - } - } -} - -// symbol makes sure the symbol length is not longer than the maxlength in the dialect. -func (m *Migrate) symbol(name string) string { - size := 64 - if m.Dialect() == dialect.Postgres { - size = 63 - } - if len(name) <= size { - return name - } - return fmt.Sprintf("%s_%x", name[:size-33], md5.Sum([]byte(name))) -} +func (m *Migrate) setupTables(tables []*Table) { m.atlas.setupTables(tables) } // rollback calls to tx.Rollback and wraps the given error with the rollback error if occurred. func rollback(tx dialect.Tx, err error) error { @@ -747,55 +637,3 @@ type fkRenamer interface { type verifyRanger interface { verifyRange(context.Context, dialect.Tx, *Table, int64) error } - -// typeStore wraps methods for loading and storing pk range information for types. -type typeStore interface { - load(context.Context, dialect.ExecQuerier) ([]string, error) - add(context.Context, dialect.ExecQuerier, string) error -} - -// dbTypeStore stores and read pk information in a database table. -// This is the "old" behaviour before the typeStore interface was added. -type dbTypeStore struct { - drv sqlDialect -} - -// load the types from the database. If the table does not exist, it will be created. -func (s *dbTypeStore) load(ctx context.Context, conn dialect.ExecQuerier) ([]string, error) { - exists, err := s.drv.tableExist(ctx, conn, TypeTable) - if err != nil { - return nil, err - } - if !exists { - t := NewTable(TypeTable). - AddPrimary(&Column{Name: "id", Type: field.TypeUint, Increment: true}). - AddColumn(&Column{Name: "type", Type: field.TypeString, Unique: true}) - query, args := s.drv.tBuilder(t).Query() - if err := conn.Exec(ctx, query, args, nil); err != nil { - return nil, fmt.Errorf("create types table: %w", err) - } - return nil, nil - } - rows := &sql.Rows{} - query, args := sql.Dialect(s.drv.Dialect()). - Select("type").From(sql.Table(TypeTable)).OrderBy(sql.Asc("id")).Query() - if err := conn.Query(ctx, query, args, rows); err != nil { - return nil, fmt.Errorf("query types table: %w", err) - } - defer rows.Close() - var types []string - return types, sql.ScanSlice(rows, &types) -} - -// add a new type entry to the database table. since load is called first, -// there is no need to check for the tables' existence. -func (s *dbTypeStore) add(ctx context.Context, conn dialect.ExecQuerier, t string) error { - query, args := sql.Dialect(s.drv.Dialect()). - Insert(TypeTable).Columns("type").Values(t).Query() - if err := conn.Exec(ctx, query, args, nil); err != nil { - return fmt.Errorf("insert into ent_types: %w", err) - } - return nil -} - -var _ typeStore = (*dbTypeStore)(nil) diff --git a/dialect/sql/schema/migrate_test.go b/dialect/sql/schema/migrate_test.go index 2b4a6d060..8a375e5e0 100644 --- a/dialect/sql/schema/migrate_test.go +++ b/dialect/sql/schema/migrate_test.go @@ -16,10 +16,9 @@ import ( "ariga.io/atlas/sql/migrate" "ariga.io/atlas/sql/schema" - "entgo.io/ent/schema/field" - "entgo.io/ent/dialect" "entgo.io/ent/dialect/sql" + "entgo.io/ent/schema/field" "github.com/DATA-DOG/go-sqlmock" "github.com/stretchr/testify/require" @@ -42,7 +41,7 @@ func TestMigrateHookOmitTable(t *testing.T) { return CreateFunc(func(ctx context.Context, tables ...*Table) error { return next.Create(ctx, tables[1]) }) - })) + }), WithAtlas(false)) require.NoError(t, err) err = m.Create(context.Background(), tables...) require.NoError(t, err) @@ -67,13 +66,15 @@ func TestMigrateHookAddTable(t *testing.T) { return CreateFunc(func(ctx context.Context, tables ...*Table) error { return next.Create(ctx, tables[0], &Table{Name: "pets"}) }) - })) + }), WithAtlas(false)) require.NoError(t, err) err = m.Create(context.Background(), tables...) require.NoError(t, err) } func TestMigrate_Diff(t *testing.T) { + ctx := context.Background() + db, err := sql.Open(dialect.SQLite, "file:test?mode=memory&_fk=1") require.NoError(t, err) @@ -83,11 +84,11 @@ func TestMigrate_Diff(t *testing.T) { m, err := NewMigrate(db, WithDir(d)) require.NoError(t, err) - require.NoError(t, m.Diff(context.Background(), &Table{Name: "users"})) + require.NoError(t, m.Diff(ctx, &Table{Name: "users"})) v := time.Now().UTC().Format("20060102150405") requireFileEqual(t, filepath.Join(p, v+"_changes.up.sql"), "-- create \"users\" table\nCREATE TABLE `users` (, PRIMARY KEY ());\n") requireFileEqual(t, filepath.Join(p, v+"_changes.down.sql"), "-- reverse: create \"users\" table\nDROP TABLE `users`;\n") - require.NoFileExists(t, filepath.Join(p, "atlas.sum")) + require.FileExists(t, filepath.Join(p, migrate.HashFileName)) // Test integrity file. p = t.TempDir() @@ -95,14 +96,13 @@ func TestMigrate_Diff(t *testing.T) { require.NoError(t, err) m, err = NewMigrate(db, WithDir(d), WithSumFile()) require.NoError(t, err) - require.NoError(t, m.Diff(context.Background(), &Table{Name: "users"})) + require.NoError(t, m.Diff(ctx, &Table{Name: "users"})) requireFileEqual(t, filepath.Join(p, v+"_changes.up.sql"), "-- create \"users\" table\nCREATE TABLE `users` (, PRIMARY KEY ());\n") requireFileEqual(t, filepath.Join(p, v+"_changes.down.sql"), "-- reverse: create \"users\" table\nDROP TABLE `users`;\n") - require.FileExists(t, filepath.Join(p, "atlas.sum")) + require.FileExists(t, filepath.Join(p, migrate.HashFileName)) require.NoError(t, d.WriteFile("tmp.sql", nil)) - require.ErrorIs(t, m.Diff(context.Background(), &Table{Name: "users"}), migrate.ErrChecksumMismatch) + require.ErrorIs(t, m.Diff(ctx, &Table{Name: "users"}), migrate.ErrChecksumMismatch) - // Test type store. idCol := []*Column{{Name: "id", Type: field.TypeInt, Increment: true}} p = t.TempDir() d, err = migrate.NewLocalDir(p) @@ -115,22 +115,19 @@ func TestMigrate_Diff(t *testing.T) { ) require.NoError(t, err) - // If using global unique ID and versioned migrations, - // consent for the file based type store has to be given explicitly. - _, err = NewMigrate(db, WithDir(d), WithGlobalUniqueID(true)) - require.ErrorIs(t, err, errConsent) - require.Contains(t, err.Error(), "WithUniversalID") - require.Contains(t, err.Error(), "WithGlobalUniqueID") - require.Contains(t, err.Error(), "WithDir") - - m, err = NewMigrate(db, WithFormatter(f), WithDir(d), WithUniversalID(), WithSumFile()) + m, err = NewMigrate(db, WithFormatter(f), WithDir(d), WithGlobalUniqueID(true)) require.NoError(t, err) - require.IsType(t, &dirTypeStore{}, m.typeStore) - require.NoError(t, m.Diff(context.Background(), + require.NoError(t, m.Diff(ctx, &Table{Name: "users", Columns: idCol, PrimaryKey: idCol}, - &Table{Name: "groups", Columns: idCol, PrimaryKey: idCol, Indexes: []*Index{{Name: "short", Columns: idCol}, {Name: "long_" + strings.Repeat("_", 60), Columns: idCol}}}, + &Table{ + Name: "groups", + Columns: idCol, + PrimaryKey: idCol, + Indexes: []*Index{ + {Name: "short", Columns: idCol}, + {Name: "long_" + strings.Repeat("_", 60), Columns: idCol}, + }}, )) - requireFileEqual(t, filepath.Join(p, ".ent_types"), atlasDirective+"users,groups") changesSQL := strings.Join([]string{ "CREATE TABLE `users` (`id` integer NOT NULL PRIMARY KEY AUTOINCREMENT);", "CREATE TABLE `groups` (`id` integer NOT NULL PRIMARY KEY AUTOINCREMENT);", @@ -143,17 +140,10 @@ func TestMigrate_Diff(t *testing.T) { }, "\n") requireFileEqual(t, filepath.Join(p, "changes.sql"), changesSQL) - // types file cannot be part of the sum file. - require.FileExists(t, filepath.Join(p, "atlas.sum")) - sum, err := os.ReadFile(filepath.Join(p, "atlas.sum")) - require.NoError(t, err) - require.NotContains(t, string(sum), ".ent_types") - // Adding another node will result in a new entry to the TypeTable (without actually creating it). - _, err = db.ExecContext(context.Background(), changesSQL, nil, nil) + _, err = db.ExecContext(ctx, changesSQL, nil, nil) require.NoError(t, err) - require.NoError(t, m.NamedDiff(context.Background(), "changes_2", &Table{Name: "pets", Columns: idCol, PrimaryKey: idCol})) - requireFileEqual(t, filepath.Join(p, ".ent_types"), atlasDirective+"users,groups,pets") + require.NoError(t, m.NamedDiff(ctx, "changes_2", &Table{Name: "pets", Columns: idCol, PrimaryKey: idCol})) requireFileEqual(t, filepath.Join(p, "changes_2.sql"), strings.Join([]string{ "CREATE TABLE `pets` (`id` integer NOT NULL PRIMARY KEY AUTOINCREMENT);", @@ -161,48 +151,8 @@ func TestMigrate_Diff(t *testing.T) { "INSERT INTO `ent_types` (`type`) VALUES ('pets');", "", }, "\n")) - // types file cannot be part of the sum file. - require.FileExists(t, filepath.Join(p, "atlas.sum")) - sum, err = os.ReadFile(filepath.Join(p, "atlas.sum")) - require.NoError(t, err) - require.NotContains(t, string(sum), ".ent_types") - // Checksum will be updated as well. require.NoError(t, migrate.Validate(d)) - - // Running diff against an existing database without having a types file yet - // will result in the types file respect the "old" order of pk allocations. - switchAllocs := func(one, two string) { - for _, stmt := range []string{ - "DELETE FROM `ent_types`;", - fmt.Sprintf("INSERT INTO `ent_types` (`type`) VALUES ('%s'), ('%s');", one, two), - } { - _, err = db.ExecContext(context.Background(), stmt) - require.NoError(t, err) - } - } - switchAllocs("groups", "users") - p = t.TempDir() - d, err = migrate.NewLocalDir(p) - require.NoError(t, err) - m, err = NewMigrate(db, WithFormatter(f), WithDir(d), WithUniversalID()) - require.NoError(t, err) - - require.NoError(t, m.Diff(context.Background(), - &Table{Name: "users", Columns: idCol, PrimaryKey: idCol}, - &Table{Name: "groups", Columns: idCol, PrimaryKey: idCol}, - )) - requireFileEqual(t, filepath.Join(p, ".ent_types"), atlasDirective+"groups,users") - require.NoFileExists(t, filepath.Join(p, "changes.sql")) - - // Drifts in the types file and types database will be detected, - switchAllocs("users", "groups") - require.ErrorContains(t, m.Diff(context.Background()), fmt.Sprintf( - "type allocation range drift detected: %v <> %v: see %s for more information", - []string{"users", "groups"}, - []string{"groups", "users"}, - "https://entgo.io/docs/versioned-migrations#moving-from-auto-migration-to-versioned-migrations", - )) } func requireFileEqual(t *testing.T, name, contents string) { diff --git a/dialect/sql/schema/mysql_test.go b/dialect/sql/schema/mysql_test.go index f8d1a8d87..e048a697f 100644 --- a/dialect/sql/schema/mysql_test.go +++ b/dialect/sql/schema/mysql_test.go @@ -1362,7 +1362,7 @@ func TestMySQL_Create(t *testing.T) { db, mock, err := sqlmock.New() require.NoError(t, err) tt.before(mysqlMock{mock}) - migrate, err := NewMigrate(sql.OpenDB("mysql", db), tt.options...) + migrate, err := NewMigrate(sql.OpenDB("mysql", db), append(tt.options, WithAtlas(false))...) require.NoError(t, err) err = migrate.Create(context.Background(), tt.tables...) require.Equal(t, tt.wantErr, err != nil, err) diff --git a/dialect/sql/schema/postgres_test.go b/dialect/sql/schema/postgres_test.go index 2ce9b69a0..d7bdd60b2 100644 --- a/dialect/sql/schema/postgres_test.go +++ b/dialect/sql/schema/postgres_test.go @@ -997,7 +997,7 @@ func TestPostgres_Create(t *testing.T) { db, mock, err := sqlmock.New() require.NoError(t, err) tt.before(pgMock{mock}) - migrate, err := NewMigrate(sql.OpenDB("postgres", db), tt.options...) + migrate, err := NewMigrate(sql.OpenDB("postgres", db), append(tt.options, WithAtlas(false))...) require.NoError(t, err) err = migrate.Create(context.Background(), tt.tables...) require.Equal(t, tt.wantErr, err != nil, err) diff --git a/dialect/sql/schema/sqlite_test.go b/dialect/sql/schema/sqlite_test.go index 38a92631f..c59d2db9a 100644 --- a/dialect/sql/schema/sqlite_test.go +++ b/dialect/sql/schema/sqlite_test.go @@ -437,7 +437,7 @@ func TestSQLite_Create(t *testing.T) { db, mock, err := sqlmock.New() require.NoError(t, err) tt.before(sqliteMock{mock}) - migrate, err := NewMigrate(sql.OpenDB("sqlite3", db), tt.options...) + migrate, err := NewMigrate(sql.OpenDB("sqlite3", db), append(tt.options, WithAtlas(false))...) require.NoError(t, err) err = migrate.Create(context.Background(), tt.tables...) require.Equal(t, tt.wantErr, err != nil, err) diff --git a/doc/md/versioned-migrations.md b/doc/md/versioned-migrations.md index d2c79b818..dc35f3e1c 100644 --- a/doc/md/versioned-migrations.md +++ b/doc/md/versioned-migrations.md @@ -8,18 +8,27 @@ applying the computed changes directly to the database, it will generate a set o necessary SQL statements to migrate the database. These files can then be edited to your needs and be applied by any tool you like (like golang-migrate, Flyway, liquibase). -![atlas-versioned-migration-process](https://entgo.io/images/assets/migrate-atlas-versioned.png) - ## Generating Versioned Migration Files -### From Client +As mentioned above, versioned migrations do only work, if the new Atlas based migration engine is used. Migration files +are generated by computing the difference between two **states**. We call the state reflected by your Ent schema the ** +desired** state, and the last state before your most recent changes the **current** state. There are two ways for Ent to +determine the current state: -If you want to use an instantiated Ent client to create new migration files, you have to enable the versioned -migrations feature flag in order to have Ent make the necessary changes to the generated code. Depending on how you -execute the Ent code generator, you have to use one of the two options: +1. Replay the existing migration directory and inspect the schema (default) +2. Connect to an existing database and inspect the schema -1. If you are using the default go generate configuration, simply add the `--feature sql/versioned-migration` to - the `ent/generate.go` file as follows: +We emphasize to use the first option, as it has the advantage for you to not have to connect to a production database to +create a diff. In addition, this approach also works, if you have multiple deployments in different migration states. +The first step is to enable the versioned migration feature by passing in the `sql/versioned-migration` feature flag. +Depending on how you execute the Ent code generator, you have to use one of the two options: + +![atlas-versioned-migration-process](https://entgo.io/images/assets/migrate-atlas-replay.png) + +#### With Ent CLI + +If you are using the default go generate configuration, simply add the `--feature sql/versioned-migration` to +the `ent/generate.go` file as follows: ```go package ent @@ -27,8 +36,10 @@ package ent //go:generate go run -mod=mod entgo.io/ent/cmd/ent generate --feature sql/versioned-migration ./schema ``` -2. If you are using the code generation package (e.g. if you are using an Ent extension), add the feature flag as - follows: +#### With entc package + +If you are using the code generation package (e.g. if you are using an Ent extension), add the feature flag as +follows: ```go //go:build ignore @@ -43,108 +54,59 @@ import ( ) func main() { - err := entc.Generate("./schema", &gen.Config{}, entc.FeatureNames("sql/versioned-migration")) + err := entc.Generate("./schema", &gen.Config{}, entc.FeatureNames(gen.FeatureVersionedMigration.Name)) if err != nil { log.Fatalf("running ent codegen: %v", err) } } ``` -After regenerating the project, there will be an extra `Diff` method on the Ent client that you can use to inspect the -connected database, compare it with the schema definitions and create SQL statements needed to migrate the database to -the graph. +After regenerating the project, you have two ways to generate new migration files. First, there will be a new top-level +method in the generated `migrate` package: `NamedDiff`. All you have to do is provide an Atlas +[dev database](https://atlasgo.io/dev-database) URL for the desired database dialect. ```go package main import ( - "context" - "log" + "context" + "log" - "/ent" + "/ent/migrate" - "ariga.io/atlas/sql/migrate" - "entgo.io/ent/dialect/sql/schema" - _ "github.com/go-sql-driver/mysql" + atlas "ariga.io/atlas/sql/migrate" + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/sql/schema" + _ "github.com/go-sql-driver/mysql" ) func main() { - client, err := ent.Open("mysql", "root:pass@tcp(localhost:3306)/test") - if err != nil { - log.Fatalf("failed connecting to mysql: %v", err) - } - defer client.Close() ctx := context.Background() // Create a local migration directory. - dir, err := migrate.NewLocalDir("migrations") + dir, err := atlas.NewLocalDir("migrations") if err != nil { log.Fatalf("failed creating atlas migration directory: %v", err) } // Write migration diff. - err = client.Schema.Diff(ctx, schema.WithDir(dir)) - // You can use the following method to give the migration files a name. - // err = client.Schema.NamedDiff(ctx, "migration_name", schema.WithDir(dir)) + opts := []schema.MigrateOption{ + schema.WithDir(dir), // provide migration directory + schema.WithMigrationMode(schema.ModeReplay), // provide migration mode + schema.WithDialect(dialect.MySQL), // Ent dialect to use + } + // Generate migrations using Atlas support for TiDB (note the Ent dialect option passed above). + err = migrate.NamedDiff(ctx, "tidb://user:pass@localhost:3306/ent_dev", "my_migration", opts...) if err != nil { - log.Fatalf("failed creating schema resources: %v", err) + log.Fatalf("failed generating migration file: %v", err) } } ``` -You can then create a new set of migration files by simply calling `go run -mod=mod main.go`. +You can then generate a new set of migration files by simply calling `go run -mod=mod main.go`. -### From Graph - -You can also generate new migration files without an instantiated Ent client. This can be useful if you want to make the -migration file creation part of a go generate workflow. Note, that in this case enabling the feature flag is optional. - -```go -package main - -import ( - "context" - "log" - - "ariga.io/atlas/sql/migrate" - "entgo.io/ent/dialect/sql" - "entgo.io/ent/dialect/sql/schema" - "entgo.io/ent/entc" - "entgo.io/ent/entc/gen" -) - -func main() { - // Load the graph. - graph, err := entc.LoadGraph("./schema", &gen.Config{}) - if err != nil { - log.Fatalln(err) - } - tbls, err := graph.Tables() - if err != nil { - log.Fatalln(err) - } - // Create a local migration directory. - d, err := migrate.NewLocalDir("migrations") - if err != nil { - log.Fatalln(err) - } - // Open connection to the database. - dlct, err := sql.Open("mysql", "root:pass@tcp(localhost:3306)/test") - if err != nil { - log.Fatalln(err) - } - // Inspect it and compare it with the graph. - m, err := schema.NewMigrate(dlct, schema.WithDir(d)) - if err != nil { - log.Fatalln(err) - } - if err := m.Diff(context.Background(), tbls...); err != nil { - log.Fatalln(err) - } - // You can use the following method to give the migration files a name. - // if err := m.NamedDiff(context.Background(), "migration_name", tbls...); err != nil { - // log.Fatalln(err) - // } -} -``` +:::info Note +If you want to inspect an existing database and compute the diff against your Ent schema, pass in the `ModeInspect` +migration mode. +::: ## Apply Migrations @@ -165,18 +127,11 @@ versioned migration, you need to take some extra steps. ### Create an initial migration file reflecting the currently deployed state -To do this make sure your schema definition is in sync with your deployed version. Then spin up an empty database and +To do this make sure your schema definition is in sync with your deployed version(s). Then spin up an empty database and run the diff command once as described above. This will create the statements needed to create the current state of -your schema graph. -If you happened to have [universal IDs](migrate.md#universal-ids) enabled before, the above command will create a -file called `.ent_types` containing a list of schema names similar to the following: - -```text title=".ent_types" -atlas.sum ignore -users,groups -``` -Once that has been created, one of the migration files will contain statements to create a table called -`ent_types`, as well as some inserts to it: +your schema graph. If you happened to have [universal IDs](migrate.md#universal-ids) enabled before, any deployment will +have a special database table named `ent_types`. The above command will create the necessary SQL statements to create +that table as well as its contents (similar to the following): ```sql CREATE TABLE `users` (`id` integer NOT NULL PRIMARY KEY AUTOINCREMENT); @@ -188,7 +143,7 @@ INSERT INTO `ent_types` (`type`) VALUES ('users'), ('groups'); ``` In order to ensure to not break existing code, make sure the contents of that file are equal to the contents in the -table present in the database you created the diff from. For example, if you consider the `.ent_types` file from +table present in the database you created the diff from. For example, if you consider the migration file from above (`users,groups`) but your deployed table looks like the one below (`groups,users`): | id | type | @@ -196,14 +151,14 @@ above (`users,groups`) but your deployed table looks like the one below (`groups | 1 | groups | | 2 | users | -You can see, that the order differs. In that case, you have to manually change both the entries in the -`.ent_types` file, as well in the generated migrations file. As a safety feature, Ent will warn you about type -drifts if you attempt to run a migration diff. +You can see, that the order differs. In that case, you have to manually change both the entries in the generated +migration file. ### Configure the tool you use to manage migrations to consider this file as applied In case of `golang-migrate` this can be done by forcing your database version as -described [here](https://github.com/golang-migrate/migrate/blob/master/GETTING_STARTED.md#forcing-your-database-version). +described [here](https://github.com/golang-migrate/migrate/blob/master/GETTING_STARTED.md#forcing-your-database-version) +. ## Use a Custom Formatter @@ -217,73 +172,62 @@ following four: 4. [Liquibase](https://www.liquibase.org/) :::note -You need to have the latest master of Ent installed for this to be working. +You need to have the latest master of Ent installed for this to be working. ```shell go get -u entgo.io/ent@master ``` + ::: ```go package main import ( - "context" - "log" - "strings" - "text/template" - "time" + "context" + "log" - "ariga.io/atlas/sql/migrate" - "ariga.io/atlas/sql/sqltool" - "entgo.io/ent/dialect/sql" - "entgo.io/ent/dialect/sql/schema" - "entgo.io/ent/entc" - "entgo.io/ent/entc/gen" + "/ent/migrate" + + atlas "ariga.io/atlas/sql/migrate" + "ariga.io/atlas/sql/sqltool" + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/sql/schema" + _ "github.com/go-sql-driver/mysql" ) func main() { - // Load the graph. - graph, err := entc.LoadGraph("/.schema", &gen.Config{}) - if err != nil { - log.Fatalln(err) - } - tbls, err := graph.Tables() - if err != nil { - log.Fatalln(err) - } - // Create a local migration directory. - d, err := migrate.NewLocalDir("migrations") - if err != nil { - log.Fatalln(err) - } - // Open connection to the database. - dlct, err := sql.Open("mysql", "root:pass@tcp(localhost:3306)/test") - if err != nil { - log.Fatalln(err) - } - // Inspect it and compare it with the graph. - m, err := schema.NewMigrate(dlct, schema.WithDir(d), - // highlight-start - // Chose one of the below. - schema.WithFormatter(sqltool.GolangMigrateFormatter), - schema.WithFormatter(sqltool.GooseFormatter), - schema.WithFormatter(sqltool.FlywayFormatter), - schema.WithFormatter(sqltool.LiquibaseFormatter), - // highlight-end - ) - if err != nil { - log.Fatalln(err) - } - if err := m.Diff(context.Background(), tbls...); err != nil { - log.Fatalln(err) - } + ctx := context.Background() + // Create a local migration directory. + dir, err := atlas.NewLocalDir("migrations") + if err != nil { + log.Fatalf("failed creating atlas migration directory: %v", err) + } + // Write migration diff. + opts := []schema.MigrateOption{ + schema.WithDir(dir), // provide migration directory + schema.WithMigrationMode(schema.ModeReplay), // provide migration mode + schema.WithDialect(dialect.MySQL), // Ent dialect to use + // highlight-start + // Choose one of the below. + schema.WithFormatter(sqltool.GolangMigrateFormatter), + schema.WithFormatter(sqltool.GooseFormatter), + schema.WithFormatter(sqltool.FlywayFormatter), + schema.WithFormatter(sqltool.LiquibaseFormatter), + // highlight-end + } + // Generate migrations using Atlas support for TiDB (note the Ent dialect option passed above). + err = migrate.NamedDiff(ctx, "tidb://user:pass@localhost:3306/ent_dev", "my_migration", opts...) + if err != nil { + log.Fatalf("failed generating migration file: %v", err) + } } ``` ### Note for using golang-migrate -If you use golang-migrate with MySQL, you need to add the `multiStatements` parameter to `true` as in the example below and then take the DSN we used in the documents with the param applied. +If you use golang-migrate with MySQL, you need to add the `multiStatements` parameter to `true` as in the example below +and then take the DSN we used in the documents with the param applied. ``` "user:password@tcp(host:port)/dbname?multiStatements=true" @@ -360,58 +304,10 @@ Please note, that you need to have the Atlas CLI installed in your system for th the [installation instructions](https://atlasgo.io/cli/getting-started/setting-up#install-the-cli) before proceeding. ::: -The first step is to tell the migration engine to create a sum file by using the `schema.WithSumFile()` option: - -```go -package main - -import ( - "context" - "log" - - "ariga.io/atlas/sql/migrate" - "ariga.io/atlas/sql/sqltool" - "entgo.io/ent/dialect/sql" - "entgo.io/ent/dialect/sql/schema" - "entgo.io/ent/entc" - "entgo.io/ent/entc/gen" -) - -func main() { - // Load the graph. - graph, err := entc.LoadGraph("/.schema", &gen.Config{}) - if err != nil { - log.Fatalln(err) - } - tbls, err := graph.Tables() - if err != nil { - log.Fatalln(err) - } - // Create a local migration directory. - d, err := migrate.NewLocalDir("migrations") - if err != nil { - log.Fatalln(err) - } - // Open connection to the database. - dlct, err := sql.Open("mysql", "root:pass@tcp(localhost:3306)/test") - if err != nil { - log.Fatalln(err) - } - // Inspect it and compare it with the graph. - m, err := schema.NewMigrate(dlct, schema.WithDir(d), - // highlight-start - // Enable the Atlas Migration Directory Integrity File. - schema.WithSumFile(), - // highlight-end - ) - if err != nil { - log.Fatalln(err) - } - if err := m.Diff(context.Background(), tbls...); err != nil { - log.Fatalln(err) - } -} -``` +In previous versions of Ent, the integrity file was opt-in. But we think this is a very important feature that provides +great value and safety to migrations. Therefore, generation of the sum file is now the default behavior and in the +future we might even remove the option to disable this feature. For now, if you really want to remove integrity file +generation, use the `schema.DisableChecksum()` option. In addition to the usual `.sql` migration files the migration directory will contain the `atlas.sum` file. Every time you let Ent generate a new migration file, this file is updated for you. However, every manual change made to the diff --git a/entc/gen/template/dialect/sql/feature/migrate_diff.tmpl b/entc/gen/template/dialect/sql/feature/migrate_diff.tmpl index 9fa3a732e..4e354c668 100644 --- a/entc/gen/template/dialect/sql/feature/migrate_diff.tmpl +++ b/entc/gen/template/dialect/sql/feature/migrate_diff.tmpl @@ -7,6 +7,17 @@ in the LICENSE file in the root directory of this source tree. {{/* gotype: entgo.io/ent/entc/gen.Graph */}} {{ define "migrate/diff" }} +// Diff compares the state read from a database connection or migration directory with +// the state defined by the Ent schema. Changes will be written to new migration files. +func Diff(ctx context.Context, url string, opts ...schema.MigrateOption) error { + return NamedDiff(ctx, url, "changes", opts...) +} + +// NamedDiff compares the state read from a database connection or migration directory with +// the state defined by the Ent schema. Changes will be written to new named migration files. +func NamedDiff(ctx context.Context, url, name string, opts ...schema.MigrateOption) error { + return schema.Diff(ctx, url, name, Tables, opts...) +} // Diff creates a migration file containing the statements to resolve the diff // between the Ent schema and the connected database. func (s *Schema) Diff(ctx context.Context, opts ...schema.MigrateOption) error { diff --git a/entc/integration/customid/customid_test.go b/entc/integration/customid/customid_test.go index 9eb5acd63..313132176 100644 --- a/entc/integration/customid/customid_test.go +++ b/entc/integration/customid/customid_test.go @@ -51,7 +51,7 @@ func TestMySQL(t *testing.T) { cfg.DBName = "custom_id" client, err := ent.Open("mysql", cfg.FormatDSN()) require.NoError(t, err, "connecting to custom_id database") - err = client.Schema.Create(context.Background(), schema.WithHooks(clearDefault, skipBytesID), schema.WithAtlas(true)) + err = client.Schema.Create(context.Background(), schema.WithHooks(clearDefault, skipBytesID)) require.NoError(t, err) CustomID(t, client) }) @@ -75,7 +75,7 @@ func TestPostgres(t *testing.T) { defer db.Exec("DROP SCHEMA custom_id CASCADE") client := ent.NewClient(ent.Driver(entsql.OpenDB(dialect.Postgres, db))) - err = client.Schema.Create(context.Background(), schema.WithAtlas(true), schema.WithDiffHook(expectOnePetsIndex)) + err = client.Schema.Create(context.Background(), schema.WithDiffHook(expectOnePetsIndex)) require.NoError(t, err) CustomID(t, client) BytesID(t, client) @@ -87,7 +87,7 @@ func TestSQLite(t *testing.T) { client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1") require.NoError(t, err) defer client.Close() - require.NoError(t, client.Schema.Create(context.Background(), schema.WithHooks(clearDefault)), schema.WithAtlas(true)) + require.NoError(t, client.Schema.Create(context.Background(), schema.WithHooks(clearDefault))) CustomID(t, client) BytesID(t, client) } diff --git a/entc/integration/integration_test.go b/entc/integration/integration_test.go index 67cad5f45..f1c26d201 100644 --- a/entc/integration/integration_test.go +++ b/entc/integration/integration_test.go @@ -116,7 +116,6 @@ func TestPostgres(t *testing.T) { var ( opts = enttest.WithMigrateOptions( - sqlschema.WithAtlas(true), migrate.WithDropIndex(true), migrate.WithDropColumn(true), ) @@ -1872,7 +1871,6 @@ func NoSchemaChanges(t *testing.T, client *ent.Client) { tables, migrate.WithDropIndex(true), migrate.WithDropColumn(true), - sqlschema.WithAtlas(true), ) require.NoError(t, err) } diff --git a/entc/integration/migrate/migrate_test.go b/entc/integration/migrate/migrate_test.go index f4396a283..20c45b67f 100644 --- a/entc/integration/migrate/migrate_test.go +++ b/entc/integration/migrate/migrate_test.go @@ -6,17 +6,21 @@ package migrate import ( "bufio" + "bytes" "context" "errors" "fmt" "io/fs" "math" + "os" "path/filepath" "strconv" "strings" "testing" "text/template" + "ariga.io/atlas/sql/migrate" + atlas "ariga.io/atlas/sql/schema" "ariga.io/atlas/sql/sqltool" "entgo.io/ent/dialect" "entgo.io/ent/dialect/sql" @@ -31,9 +35,7 @@ import ( "entgo.io/ent/entc/integration/migrate/entv2/predicate" "entgo.io/ent/entc/integration/migrate/entv2/user" "entgo.io/ent/entc/integration/migrate/versioned" - - "ariga.io/atlas/sql/migrate" - atlas "ariga.io/atlas/sql/schema" + vmigrate "entgo.io/ent/entc/integration/migrate/versioned/migrate" _ "github.com/go-sql-driver/mysql" _ "github.com/lib/pq" _ "github.com/mattn/go-sqlite3" @@ -67,10 +69,16 @@ func TestMySQL(t *testing.T) { require.NoError(t, err, root.Exec(ctx, "DROP DATABASE IF EXISTS versioned_migrate", []interface{}{}, new(sql.Result))) require.NoError(t, root.Exec(ctx, "CREATE DATABASE IF NOT EXISTS versioned_migrate", []interface{}{}, new(sql.Result))) defer root.Exec(ctx, "DROP DATABASE IF EXISTS versioned_migrate", []interface{}{}, new(sql.Result)) + require.NoError(t, err, root.Exec(ctx, "DROP DATABASE IF EXISTS versioned_migrate_dev", []interface{}{}, new(sql.Result))) + require.NoError(t, root.Exec(ctx, "CREATE DATABASE IF NOT EXISTS versioned_migrate_dev", []interface{}{}, new(sql.Result))) + defer root.Exec(ctx, "DROP DATABASE IF EXISTS versioned_migrate_dev", []interface{}{}, new(sql.Result)) vdrv, err := sql.Open("mysql", fmt.Sprintf("root:pass@tcp(localhost:%d)/versioned_migrate?parseTime=True", port)) require.NoError(t, err, "connecting to versioned migrate database") defer vdrv.Close() - Versioned(t, vdrv, versioned.NewClient(versioned.Driver(vdrv))) + Versioned(t, vdrv, + fmt.Sprintf("mysql://root:pass@localhost:%d/versioned_migrate_dev?parseTime=True", port), + versioned.NewClient(versioned.Driver(vdrv)), + ) }) } } @@ -108,7 +116,13 @@ func TestPostgres(t *testing.T) { require.NoError(t, root.Exec(ctx, "DROP DATABASE IF EXISTS versioned_migrate", []interface{}{}, new(sql.Result))) require.NoError(t, root.Exec(ctx, "CREATE DATABASE versioned_migrate", []interface{}{}, new(sql.Result))) defer root.Exec(ctx, "DROP DATABASE versioned_migrate", []interface{}{}, new(sql.Result)) - Versioned(t, vdrv, versioned.NewClient(versioned.Driver(vdrv))) + require.NoError(t, root.Exec(ctx, "DROP DATABASE IF EXISTS versioned_migrate_dev", []interface{}{}, new(sql.Result))) + require.NoError(t, root.Exec(ctx, "CREATE DATABASE versioned_migrate_dev", []interface{}{}, new(sql.Result))) + defer root.Exec(ctx, "DROP DATABASE versioned_migrate_dev", []interface{}{}, new(sql.Result)) + Versioned(t, vdrv, + fmt.Sprintf("postgres://postgres:pass@localhost:%d/versioned_migrate_dev?sslmode=disable&search_path=public", port), + versioned.NewClient(versioned.Driver(vdrv)), + ) }) } } @@ -179,7 +193,7 @@ func TestSQLite(t *testing.T) { vdrv, err := sql.Open("sqlite3", "file:versioned_ent?mode=memory&cache=shared&_fk=1") require.NoError(t, err) defer vdrv.Close() - Versioned(t, vdrv, versioned.NewClient(versioned.Driver(vdrv))) + Versioned(t, vdrv, "sqlite3://file?mode=memory&cache=shared&_fk=1", versioned.NewClient(versioned.Driver(vdrv))) } func TestStorageKey(t *testing.T) { @@ -188,41 +202,41 @@ func TestStorageKey(t *testing.T) { require.Equal(t, "user_friend_id2", migratev2.FriendsTable.ForeignKeys[1].Symbol) } -func Versioned(t *testing.T, drv sql.ExecQuerier, client *versioned.Client) { +func Versioned(t *testing.T, drv sql.ExecQuerier, devURL string, client *versioned.Client) { ctx := context.Background() p := t.TempDir() dir, err := migrate.NewLocalDir(p) require.NoError(t, err) require.NoError(t, client.Schema.Diff(ctx, schema.WithDir(dir))) - require.Equal(t, 2, countFiles(t, dir)) + require.Equal(t, 3, countFiles(t, dir)) p = t.TempDir() dir, err = migrate.NewLocalDir(p) require.NoError(t, err) require.NoError(t, client.Schema.Diff(ctx, schema.WithDir(dir), schema.WithFormatter(sqltool.GooseFormatter))) - require.Equal(t, 1, countFiles(t, dir)) - - p = t.TempDir() - dir, err = migrate.NewLocalDir(p) - require.NoError(t, err) - require.NoError(t, client.Schema.Diff(ctx, schema.WithDir(dir), schema.WithFormatter(sqltool.FlywayFormatter))) require.Equal(t, 2, countFiles(t, dir)) p = t.TempDir() dir, err = migrate.NewLocalDir(p) require.NoError(t, err) - require.NoError(t, client.Schema.Diff(ctx, schema.WithDir(dir), schema.WithFormatter(sqltool.LiquibaseFormatter))) - require.Equal(t, 1, countFiles(t, dir)) + require.NoError(t, client.Schema.Diff(ctx, schema.WithDir(dir), schema.WithFormatter(sqltool.FlywayFormatter))) + require.Equal(t, 3, countFiles(t, dir)) p = t.TempDir() dir, err = migrate.NewLocalDir(p) require.NoError(t, err) - require.NoError(t, client.Schema.Diff(ctx, schema.WithDir(dir), schema.WithSumFile())) - require.Equal(t, 3, countFiles(t, dir)) - require.FileExists(t, filepath.Join(p, "atlas.sum")) + require.NoError(t, client.Schema.Diff(ctx, schema.WithDir(dir), schema.WithFormatter(sqltool.LiquibaseFormatter))) + require.Equal(t, 2, countFiles(t, dir)) - // GlobalUniqueID with drift check. + p = t.TempDir() + dir, err = migrate.NewLocalDir(p) + require.NoError(t, err) + require.NoError(t, client.Schema.Diff(ctx, schema.WithDir(dir))) + require.Equal(t, 3, countFiles(t, dir)) + require.FileExists(t, filepath.Join(p, migrate.HashFileName)) + + // UniversalID with drift check. p = t.TempDir() dir, err = migrate.NewLocalDir(p) require.NoError(t, err) @@ -233,7 +247,7 @@ func Versioned(t *testing.T, drv sql.ExecQuerier, client *versioned.Client) { require.NoError(t, err) opts := []schema.MigrateOption{ schema.WithDir(dir), - schema.WithUniversalID(), + schema.WithGlobalUniqueID(true), schema.WithFormatter(format), } @@ -245,7 +259,7 @@ func Versioned(t *testing.T, drv sql.ExecQuerier, client *versioned.Client) { files, err := dir.Files() require.NoError(t, err) for _, f := range files { - sc := bufio.NewScanner(f) + sc := bufio.NewScanner(bytes.NewReader(f.Bytes())) for sc.Scan() { if sc.Text() != "" { _, err := drv.ExecContext(ctx, sc.Text()) @@ -257,15 +271,49 @@ func Versioned(t *testing.T, drv sql.ExecQuerier, client *versioned.Client) { // Diff again - there should not be a new file. require.NoError(t, client.Schema.NamedDiff(ctx, "second", opts...)) require.Equal(t, 2, countFiles(t, dir)) + + // Replay Diff requires sum file. + require.NoError(t, os.Remove(filepath.Join(p, migrate.HashFileName))) + opts = append(opts, schema.WithMigrationMode(schema.ModeReplay)) + require.ErrorIs(t, client.Schema.Diff(ctx, opts...), migrate.ErrChecksumNotFound) + + // Invalid sum file errors. + require.NoError(t, migrate.WriteSumFile(dir, migrate.HashFile{})) + require.ErrorIs(t, client.Schema.Diff(ctx, opts...), migrate.ErrChecksumMismatch) + + // Diffing by replaying on the current connection -> not clean. + hf, err := migrate.HashSum(dir) + require.NoError(t, err) + require.NoError(t, migrate.WriteSumFile(dir, hf)) + require.ErrorIs(t, client.Schema.Diff(ctx, opts...), migrate.ErrNotClean) + + // Diffing by replaying should not create new files. + require.Equal(t, 2, countFiles(t, dir)) + require.NoError(t, vmigrate.Diff(ctx, devURL, opts...)) + require.Equal(t, 2, countFiles(t, dir)) + + // Creating an empty and creating a diff by replay results in the same files. + p2 := t.TempDir() + dir2, err := migrate.NewLocalDir(p2) + require.NoError(t, err) + *dir = *dir2 + require.Equal(t, 0, countFiles(t, dir)) + require.NoError(t, vmigrate.Diff(ctx, devURL, opts...)) + require.Equal(t, 2, countFiles(t, dir)) + f1, err := os.ReadFile(filepath.Join(p, "first.sql")) + require.NoError(t, err) + f2, err := os.ReadFile(filepath.Join(p2, "changes.sql")) + require.NoError(t, err) + require.Equal(t, string(f1), string(f2)) } func V1ToV2(t *testing.T, dialect string, clientv1 *entv1.Client, clientv2 *entv2.Client) { ctx := context.Background() // Run migration and execute queries on v1. - require.NoError(t, clientv1.Schema.Create(ctx, migratev1.WithGlobalUniqueID(true), schema.WithAtlas(false))) + require.NoError(t, clientv1.Schema.Create(ctx, migratev1.WithGlobalUniqueID(true))) SanityV1(t, dialect, clientv1) - require.NoError(t, clientv1.Schema.Create(ctx, migratev1.WithGlobalUniqueID(true), schema.WithAtlas(true))) + require.NoError(t, clientv1.Schema.Create(ctx, migratev1.WithGlobalUniqueID(true))) // Ensure migration to Atlas works with global unique ids. // Create 2 records, delete first one, and create another two after migration. @@ -275,8 +323,8 @@ func V1ToV2(t *testing.T, dialect string, clientv1 *entv1.Client, clientv2 *entv clientv1.Conversion.DeleteOne(c1).ExecX(ctx) // Run migration and execute queries on v2. - require.NoError(t, clientv2.Schema.Create(ctx, migratev2.WithGlobalUniqueID(true), migratev2.WithDropIndex(true), migratev2.WithDropColumn(true), schema.WithAtlas(true), schema.WithDiffHook(renameTokenColumn), schema.WithApplyHook(fillNulls(dialect)))) - require.NoError(t, clientv2.Schema.Create(ctx, migratev2.WithGlobalUniqueID(true), migratev2.WithDropIndex(true), migratev2.WithDropColumn(true), schema.WithAtlas(true)), "should not create additional resources on multiple runs") + require.NoError(t, clientv2.Schema.Create(ctx, migratev2.WithGlobalUniqueID(true), migratev2.WithDropIndex(true), migratev2.WithDropColumn(true), schema.WithDiffHook(renameTokenColumn), schema.WithApplyHook(fillNulls(dialect)))) + require.NoError(t, clientv2.Schema.Create(ctx, migratev2.WithGlobalUniqueID(true), migratev2.WithDropIndex(true), migratev2.WithDropColumn(true)), "should not create additional resources on multiple runs") SanityV2(t, dialect, clientv2) clientv2.Conversion.CreateBulk(clientv2.Conversion.Create(), clientv2.Conversion.Create(), clientv2.Conversion.Create()).ExecX(ctx) @@ -515,7 +563,7 @@ func TimePrecision(t *testing.T, drv *sql.Driver, query string) { } func idRange(t *testing.T, id, l, h int) { - require.Truef(t, id > l && id < h, "id %s should be between %d to %d", id, l, h) + require.Truef(t, id > l && id < h, "id %d should be between %d to %d", id, l, h) } func countFiles(t *testing.T, d migrate.Dir) int { diff --git a/entc/integration/migrate/versioned/migrate/migrate.go b/entc/integration/migrate/versioned/migrate/migrate.go index 811fe1fc2..76d4cf2c0 100644 --- a/entc/integration/migrate/versioned/migrate/migrate.go +++ b/entc/integration/migrate/versioned/migrate/migrate.go @@ -58,6 +58,18 @@ func Create(ctx context.Context, s *Schema, tables []*schema.Table, opts ...sche return migrate.Create(ctx, tables...) } +// Diff compares the state read from a database connection or migration directory with +// the state defined by the Ent schema. Changes will be written to new migration files. +func Diff(ctx context.Context, url string, opts ...schema.MigrateOption) error { + return NamedDiff(ctx, url, "changes", opts...) +} + +// NamedDiff compares the state read from a database connection or migration directory with +// the state defined by the Ent schema. Changes will be written to new named migration files. +func NamedDiff(ctx context.Context, url, name string, opts ...schema.MigrateOption) error { + return schema.Diff(ctx, url, name, Tables, opts...) +} + // Diff creates a migration file containing the statements to resolve the diff // between the Ent schema and the connected database. func (s *Schema) Diff(ctx context.Context, opts ...schema.MigrateOption) error { diff --git a/entc/integration/migrate/versioned/migrate/schema.go b/entc/integration/migrate/versioned/migrate/schema.go index 4c141acfe..1de01a4e2 100644 --- a/entc/integration/migrate/versioned/migrate/schema.go +++ b/entc/integration/migrate/versioned/migrate/schema.go @@ -46,7 +46,9 @@ var ( func init() { VersionedGroupsTable.Annotation = &entsql.Annotation{ - Table: "versioned_groups", + Table: "versioned_groups", + Charset: "ascii", + Collation: "ascii_general_ci", } VersionedUsersTable.Annotation = &entsql.Annotation{ Table: "versioned_users", diff --git a/entc/integration/migrate/versioned/schema/group.go b/entc/integration/migrate/versioned/schema/group.go index 974399268..4e6da8864 100644 --- a/entc/integration/migrate/versioned/schema/group.go +++ b/entc/integration/migrate/versioned/schema/group.go @@ -26,6 +26,10 @@ func (Group) Fields() []ent.Field { // Annotations of the Group. func (Group) Annotations() []schema.Annotation { return []schema.Annotation{ - entsql.Annotation{Table: "versioned_groups"}, + entsql.Annotation{ + Table: "versioned_groups", + Charset: "ascii", + Collation: "ascii_general_ci", + }, } } diff --git a/entc/integration/multischema/multischema_test.go b/entc/integration/multischema/multischema_test.go index 5ac33f7cb..5be6872de 100644 --- a/entc/integration/multischema/multischema_test.go +++ b/entc/integration/multischema/multischema_test.go @@ -11,6 +11,7 @@ import ( "entgo.io/ent/dialect" "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/schema" "entgo.io/ent/entc/integration/multischema/ent" "entgo.io/ent/entc/integration/multischema/ent/group" "entgo.io/ent/entc/integration/multischema/ent/migrate" @@ -109,7 +110,7 @@ func TestMySQL(t *testing.T) { func setupSchema(t *testing.T, drv *sql.Driver) { client := ent.NewClient(ent.Driver(&rewriter{drv})) - err := client.Schema.Create(context.Background(), migrate.WithForeignKeys(false)) + err := client.Schema.Create(context.Background(), migrate.WithForeignKeys(false), schema.WithAtlas(false)) require.NoError(t, err) } diff --git a/go.mod b/go.mod index c960f4240..0c568a257 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module entgo.io/ent go 1.17 require ( - ariga.io/atlas v0.4.3-0.20220618160942-1080fa97c763 + ariga.io/atlas v0.4.3-0.20220630091711-40a31231fd1a github.com/DATA-DOG/go-sqlmock v1.5.0 github.com/go-openapi/inflect v0.19.0 github.com/go-sql-driver/mysql v1.6.0 @@ -16,12 +16,12 @@ require ( github.com/mitchellh/mapstructure v1.5.0 github.com/modern-go/reflect2 v1.0.2 github.com/olekukonko/tablewriter v0.0.5 - github.com/spf13/cobra v1.5.0 + github.com/spf13/cobra v1.4.0 github.com/stretchr/objx v0.2.0 // indirect github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942 go.opencensus.io v0.23.0 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - golang.org/x/tools v0.1.12-0.20220624134725-2994e99415f5 + golang.org/x/tools v0.1.9-0.20211216111533-8d383106f7e7 ) require ( @@ -38,7 +38,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/zclconf/go-cty v1.8.0 // indirect - golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect + golang.org/x/mod v0.5.1 // indirect golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect diff --git a/go.sum b/go.sum index 551bffb40..186fd9dfc 100644 --- a/go.sum +++ b/go.sum @@ -1,822 +1,182 @@ -ariga.io/atlas v0.3.8-0.20220424181913-f64001131c0e/go.mod h1:2aAhlHuY8tr7rPNz2MgOBTJB/cVjK0sv1VvTIqeYSws= -ariga.io/atlas v0.3.8-0.20220502090649-c495296ad28c/go.mod h1:URT1boACQmnulqRF07NkSOEkzx/OmO/48AmVX7pPaJg= -ariga.io/atlas v0.4.3-0.20220618160942-1080fa97c763 h1:WhS0COXnLACMTcosfmEVtuwgeuqvjObsE1i9joPx7Qs= -ariga.io/atlas v0.4.3-0.20220618160942-1080fa97c763/go.mod h1:10hc2LWRcvk2SFtdakSD6YKm5wp9DmzcOb6aepwYiG4= +ariga.io/atlas v0.4.3-0.20220630091711-40a31231fd1a h1:HRN6ciwXQwIVOfR5NigwJZJlGn/v+pleBOo/20gLYok= +ariga.io/atlas v0.4.3-0.20220630091711-40a31231fd1a/go.mod h1:10hc2LWRcvk2SFtdakSD6YKm5wp9DmzcOb6aepwYiG4= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM= -cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -entgo.io/ent v0.10.2-0.20220428114225-0c8f9a977c99/go.mod h1:rUH4yiUVADR2XHnv0ZERDnwF/YjR42m3Qra6CZ4ZxBA= -entgo.io/ent v0.10.2-0.20220502113020-4ac82f5bb3f0/go.mod h1:Zh61BPvB+cL6VWEyN8f1YoDacrMjQf2KDlDeX26xq2k= 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/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= -github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8= github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= -github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0= github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= -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-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -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/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= -github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -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= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4= github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/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.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 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= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -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/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.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -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= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= -github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= -github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl/v2 v2.10.0 h1:1S1UnuhDGlv3gRFV4+0EdwB+znNP5HmcGbIqwnSCByg= github.com/hashicorp/hcl/v2 v2.10.0/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= -github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= -github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= -github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= -github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -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/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 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/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= -github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.5 h1:J+gdV2cUmX7ZqL2B0lFcW0m+egaHC2V3lpO8nWxyYiQ= github.com/lib/pq v1.10.5/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= -github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-sqlite3 v1.14.10/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.13 h1:1tj15ngiFfcZzii7yd82foL+ks+ouQcj8j/TPq3fk1I= github.com/mattn/go-sqlite3 v1.14.13/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -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= -github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -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/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= 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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -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.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4= +github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= -github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= -github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 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/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM= 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 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= 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.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942 h1:t0lM6y/M5IiUZyvbBTcngso8SZEZICH7is9B6g/obVU= github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= github.com/zclconf/go-cty v1.8.0 h1:s4AvqaeQzJIu3ndv4gVIhplVD0krU+bgrcLSVUnaWuA= github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= -go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -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-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -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-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 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= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 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= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 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/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -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.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/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= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 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-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -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-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 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= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -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-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -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= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/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-20181122145206-62eef0e2fa9b/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-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-20190502175342-a43fa875dd82/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-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/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-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/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-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -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.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -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/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/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-20190907020128-2ca718005c18/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-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/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.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.9-0.20211216111533-8d383106f7e7 h1:M1gcVrIb2lSn2FIL19DG0+/b8nNVKJ7W7b4WcAGZAYM= golang.org/x/tools v0.1.9-0.20211216111533-8d383106f7e7/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.1.12-0.20220624134725-2994e99415f5 h1:SfOpSlEWRCf4u/1Wfj4JpRaZUMkpXFZmFqiK4Wi83vg= -golang.org/x/tools v0.1.12-0.20220624134725-2994e99415f5/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= -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.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= -google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -825,37 +185,13 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -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 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= 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/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -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= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/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.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/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.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -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=