graphql-engine/cli/pkg/metadata/project_metadata.go
Aravind K P c7ac1ede3f cli: add migrate and metadata packages
>

### Description
>
This PR adds two new packages which implement the CLI requirements specified in RFC:https://github.com/hasura/lux/blob/cloud/docs/rfcs/20210614_github_integration.md

1. `pkg/metadata`

![image](https://user-images.githubusercontent.com/8335904/122384828-b4757d80-cf89-11eb-9e21-ef116fb928e9.png)

2. `pkg/migrate`

![image](https://user-images.githubusercontent.com/8335904/122510554-68771700-d023-11eb-9f5d-046d2c0cf18a.png)

### Changelog

- [x] `CHANGELOG.md` is updated with user-facing content relevant to this PR. If no changelog is required, then add the `no-changelog-required` label.

### Affected components

- [x] CLI

https://github.com/hasura/graphql-engine-mono/pull/1598

GitOrigin-RevId: 0e2bce498386c5aae68dbca0fe383a6afff9d1a9
2021-06-18 06:25:14 +00:00

114 lines
2.8 KiB
Go

package metadata
import (
"bytes"
"encoding/json"
"fmt"
"io"
"github.com/hasura/graphql-engine/cli/v2/commands"
"github.com/hasura/graphql-engine/cli/v2/internal/metadataobject"
"github.com/spf13/viper"
"github.com/hasura/graphql-engine/cli/v2"
)
type ProjectMetadata struct {
ec *cli.ExecutionContext
}
// Parse metadata in project as JSON
func (p *ProjectMetadata) Parse() (io.Reader, error) {
metadataHandler := metadataobject.NewHandlerFromEC(p.ec)
jsonMetadata, err := metadataHandler.MakeJSONMetadata()
if err != nil {
return nil, fmt.Errorf("parsing project metadata to json failed: %w", err)
}
return bytes.NewReader(jsonMetadata), nil
}
// Apply metadata from in the project and provide raw response from hge server
func (p *ProjectMetadata) Apply() (io.Reader, error) {
metadataHandler := metadataobject.NewHandlerFromEC(p.ec)
if p.ec.Config.Version == cli.V2 {
r, err := metadataHandler.V1ApplyMetadata()
if err != nil {
return nil, err
}
return r, nil
}
if p.ec.Config.Version >= cli.V3 {
replaceMetadataResponse, err := metadataHandler.V2ApplyMetadata()
if err != nil {
return nil, err
}
b := new(bytes.Buffer)
if err := json.NewEncoder(b).Encode(replaceMetadataResponse); err != nil {
return nil, fmt.Errorf("encoding json reponse from server: %w", err)
}
return b, nil
}
return nil, nil
}
// Reload metadata on hge server and provides raw response from hge server
func (p *ProjectMetadata) Reload() (io.Reader, error) {
metadataHandler := metadataobject.NewHandlerFromEC(p.ec)
return metadataHandler.ReloadMetadata()
}
// Diff will return the differences between metadata in the project (in JSON) and on the server
func (p *ProjectMetadata) Diff() (io.Reader, error) {
w := new(bytes.Buffer)
opts := &commands.MetadataDiffOptions{
EC: p.ec,
Output: w,
DisableColor: true,
}
if err := opts.Run(); err != nil {
return nil, err
}
return w, nil
}
type ProjectMetadataOption func(*ProjectMetadata)
func WithAdminSecret(adminSecret string) ProjectMetadataOption {
return func(m *ProjectMetadata) {
m.ec.Viper.Set("admin_secret", adminSecret)
}
}
func WithEndpoint(endpoint string) ProjectMetadataOption {
return func(m *ProjectMetadata) {
m.ec.Viper.Set("endpoint", endpoint)
}
}
func NewProjectMetadata(projectDirectory string, opts ...ProjectMetadataOption) (*ProjectMetadata, error) {
ec := cli.NewExecutionContext()
ec.ExecutionDirectory = projectDirectory
ec.Viper = viper.New()
ec.IsTerminal = false
ec.Stdout = io.Discard
ec.Stderr = io.Discard
if err := ec.Prepare(); err != nil {
return nil, err
}
p := &ProjectMetadata{ec}
for _, opt := range opts {
opt(p)
}
if err := ec.Validate(); err != nil {
return nil, err
}
if ec.Config.Version <= cli.V1 {
return nil, fmt.Errorf("config %v is not supported", ec.Config.Version)
}
return p, nil
}