123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- package bundler
- import (
- "context"
- "errors"
- "fmt"
- "log/slog"
- "os"
- "strings"
- "google.golang.org/protobuf/proto"
- "github.com/sqlc-dev/sqlc/internal/config"
- "github.com/sqlc-dev/sqlc/internal/info"
- "github.com/sqlc-dev/sqlc/internal/plugin"
- "github.com/sqlc-dev/sqlc/internal/quickdb"
- pb "github.com/sqlc-dev/sqlc/internal/quickdb/v1"
- )
- var ErrNoProject = errors.New(`project uploads require a cloud project
- If you don't have a project, you can create one from the sqlc Cloud
- dashboard at https://dashboard.sqlc.dev/. If you have a project, ensure
- you've set its id as the value of the "project" field within the "cloud"
- section of your sqlc configuration. The id will look similar to
- "01HA8TWGMYPHK0V2GGMB3R2TP9".`)
- var ErrNoAuthToken = errors.New(`project uploads require an auth token
- If you don't have an auth token, you can create one from the sqlc Cloud
- dashboard at https://dashboard.sqlc.dev/. If you have an auth token, ensure
- you've set it as the value of the SQLC_AUTH_TOKEN environment variable.`)
- type Uploader struct {
- configPath string
- config *config.Config
- dir string
- client pb.QuickClient
- }
- type QuerySetArchive struct {
- Name string
- Queries []string
- Schema []string
- Request *plugin.GenerateRequest
- }
- func NewUploader(configPath, dir string, conf *config.Config) *Uploader {
- return &Uploader{
- configPath: configPath,
- config: conf,
- dir: dir,
- }
- }
- func (up *Uploader) Validate() error {
- if up.config.Cloud.Project == "" {
- return ErrNoProject
- }
- if up.config.Cloud.AuthToken == "" {
- return ErrNoAuthToken
- }
- if up.client == nil {
- client, err := quickdb.NewClientFromConfig(up.config.Cloud)
- if err != nil {
- return fmt.Errorf("client init failed: %w", err)
- }
- up.client = client
- }
- return nil
- }
- var envvars = []string{
- "GITHUB_REPOSITORY",
- "GITHUB_REF",
- "GITHUB_REF_NAME",
- "GITHUB_REF_TYPE",
- "GITHUB_SHA",
- }
- func annotate() map[string]string {
- labels := map[string]string{}
- for _, ev := range envvars {
- key := strings.ReplaceAll(strings.ToLower(ev), "_", ".")
- labels[key] = os.Getenv(ev)
- }
- return labels
- }
- func BuildRequest(ctx context.Context, dir, configPath string, results []*QuerySetArchive, tags []string) (*pb.UploadArchiveRequest, error) {
- conf, err := readFile(dir, configPath)
- if err != nil {
- return nil, err
- }
- res := &pb.UploadArchiveRequest{
- SqlcVersion: info.Version,
- Config: conf,
- Tags: tags,
- Annotations: annotate(),
- }
- for i, result := range results {
- schema, err := readFiles(dir, result.Schema)
- if err != nil {
- return nil, err
- }
- queries, err := readFiles(dir, result.Queries)
- if err != nil {
- return nil, err
- }
- name := result.Name
- if name == "" {
- name = fmt.Sprintf("queryset_%d", i)
- }
- genreq, err := proto.Marshal(result.Request)
- if err != nil {
- return nil, err
- }
- res.QuerySets = append(res.QuerySets, &pb.QuerySet{
- Name: name,
- Schema: schema,
- Queries: queries,
- CodegenRequest: &pb.File{
- Name: "codegen_request.pb",
- Contents: genreq,
- },
- })
- }
- return res, nil
- }
- func (up *Uploader) buildRequest(ctx context.Context, results []*QuerySetArchive, tags []string) (*pb.UploadArchiveRequest, error) {
- return BuildRequest(ctx, up.dir, up.configPath, results, tags)
- }
- func (up *Uploader) DumpRequestOut(ctx context.Context, result []*QuerySetArchive) error {
- req, err := up.buildRequest(ctx, result, []string{})
- if err != nil {
- return err
- }
- slog.Info("config", "file", req.Config.Name, "bytes", len(req.Config.Contents))
- for _, qs := range req.QuerySets {
- slog.Info("codegen_request", "queryset", qs.Name, "file", "codegen_request.pb")
- for _, file := range qs.Schema {
- slog.Info("schema", "queryset", qs.Name, "file", file.Name, "bytes", len(file.Contents))
- }
- for _, file := range qs.Queries {
- slog.Info("query", "queryset", qs.Name, "file", file.Name, "bytes", len(file.Contents))
- }
- }
- return nil
- }
- func (up *Uploader) Upload(ctx context.Context, result []*QuerySetArchive, tags []string) error {
- if err := up.Validate(); err != nil {
- return err
- }
- req, err := up.buildRequest(ctx, result, tags)
- if err != nil {
- return err
- }
- if _, err := up.client.UploadArchive(ctx, req); err != nil {
- return fmt.Errorf("upload error: %w", err)
- }
- return nil
- }
|