-
Notifications
You must be signed in to change notification settings - Fork 2.7k
/
seed_apply.go
124 lines (108 loc) · 3.65 KB
/
seed_apply.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package commands
import (
stderrors "errors"
"fmt"
"io/fs"
"github.com/hasura/graphql-engine/cli/v2"
"github.com/hasura/graphql-engine/cli/v2/internal/errors"
"github.com/hasura/graphql-engine/cli/v2/internal/metadatautil"
"github.com/hasura/graphql-engine/cli/v2/seed"
"github.com/spf13/afero"
"github.com/spf13/cobra"
)
type SeedApplyOptions struct {
EC *cli.ExecutionContext
Driver *seed.Driver
// seed file to apply
FileNames []string
Source cli.Source
}
func newSeedApplyCmd(ec *cli.ExecutionContext) *cobra.Command {
opts := SeedApplyOptions{
EC: ec,
}
cmd := &cobra.Command{
Use: "apply",
Short: "Apply seed data",
Long: `Run this command by passing the seed files you want to apply as arguments. If no arguments are passed, all the seed files in the seeds directory will be applied.
Further reading:
- https://hasura.io/docs/latest/migrations-metadata-seeds/manage-seeds/
`,
Example: ` # Apply all seeds on the database:
hasura seed apply
# Apply only a particular file:
hasura seed apply --file 1234_add_some_seed_data.sql --database-name default`,
SilenceUsage: false,
PreRunE: func(cmd *cobra.Command, args []string) error {
op := genOpName(cmd, "PreRunE")
if ec.Config.Version < cli.V3 {
return nil
}
if err := validateConfigV3FlagsWithAll(cmd, ec); err != nil {
return errors.E(op, err)
}
if ec.AllDatabases {
return nil
}
if err := validateSourceInfo(ec); err != nil {
return errors.E(op, err)
}
// check if seed ops are supported for the database
if !seed.IsSeedsSupported(ec.Source.Kind) {
return errors.E(op, fmt.Errorf("seed operations on database '%s' of kind '%s' is not supported", ec.Source.Name, ec.Source.Kind))
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
op := genOpName(cmd, "RunE")
opts.Driver = getSeedDriver(ec, ec.Config.Version)
if err := opts.Run(); err != nil {
return errors.E(op, fmt.Errorf("operation failed \n%w", err))
}
return nil
},
}
cmd.Flags().StringArrayVarP(&opts.FileNames, "file", "f", []string{}, "seed file to apply")
cmd.Flags().BoolVar(&opts.EC.AllDatabases, "all-databases", false, "set this flag to attempt to apply seeds on all databases present on server")
return cmd
}
func (o *SeedApplyOptions) Run() error {
var op errors.Op = "commands.SeedApplyOptions.Run"
o.EC.Spin("Applying seeds...")
defer o.EC.Spinner.Stop()
if o.EC.AllDatabases && o.EC.Config.Version >= cli.V3 {
sourcesAndKind, err := metadatautil.GetSourcesAndKind(o.EC.APIClient.V1Metadata.ExportMetadata)
if err != nil {
return errors.E(op, fmt.Errorf("got error while getting the sources list : %v", err))
}
for _, source := range sourcesAndKind {
o.Source = cli.Source(source)
err := o.ApplyOnSource()
if err != nil {
// skip error if no seed files are specified and no seeds are present
if len(o.FileNames) > 0 || !stderrors.Is(err, fs.ErrNotExist) {
return errors.E(op, fmt.Errorf("error while applying seeds for database '%s': %v", o.Source.Name, err))
} else {
o.EC.Logger.Infof("No seed data to plant for database: %s", o.Source.Name)
}
} else {
o.EC.Logger.Infof("Seed data planted for database: %s", o.Source.Name)
}
}
} else {
o.Source = o.EC.Source
if err := o.ApplyOnSource(); err != nil {
return errors.E(op, err)
}
o.EC.Logger.Info("Seeds planted")
}
return nil
}
func (o *SeedApplyOptions) ApplyOnSource() error {
var op errors.Op = "commands.SeedApplyOptions.ApplyOnSource"
fs := afero.NewOsFs()
if err := o.Driver.ApplySeedsToDatabase(fs, o.EC.SeedsDirectory, o.FileNames, o.Source); err != nil {
return errors.E(op, err)
}
return nil
}