github.com/niko0xdev/gqlgen@v0.17.55-0.20240120102243-2ecff98c3e37/codegen/config/exec.go (about)

     1  package config
     2  
     3  import (
     4  	"fmt"
     5  	"go/types"
     6  	"path/filepath"
     7  	"strings"
     8  
     9  	"github.com/niko0xdev/gqlgen/internal/code"
    10  )
    11  
    12  type ExecConfig struct {
    13  	Package string     `yaml:"package,omitempty"`
    14  	Layout  ExecLayout `yaml:"layout,omitempty"` // Default: single-file
    15  
    16  	// Only for single-file layout:
    17  	Filename string `yaml:"filename,omitempty"`
    18  
    19  	// Only for follow-schema layout:
    20  	FilenameTemplate string `yaml:"filename_template,omitempty"` // String template with {name} as placeholder for base name.
    21  	DirName          string `yaml:"dir"`
    22  }
    23  
    24  type ExecLayout string
    25  
    26  var (
    27  	// Write all generated code to a single file.
    28  	ExecLayoutSingleFile ExecLayout = "single-file"
    29  	// Write generated code to a directory, generating one Go source file for each GraphQL schema file.
    30  	ExecLayoutFollowSchema ExecLayout = "follow-schema"
    31  )
    32  
    33  func (r *ExecConfig) Check() error {
    34  	if r.Layout == "" {
    35  		r.Layout = ExecLayoutSingleFile
    36  	}
    37  
    38  	switch r.Layout {
    39  	case ExecLayoutSingleFile:
    40  		if r.Filename == "" {
    41  			return fmt.Errorf("filename must be specified when using single-file layout")
    42  		}
    43  		if !strings.HasSuffix(r.Filename, ".go") {
    44  			return fmt.Errorf("filename should be path to a go source file when using single-file layout")
    45  		}
    46  		r.Filename = abs(r.Filename)
    47  	case ExecLayoutFollowSchema:
    48  		if r.DirName == "" {
    49  			return fmt.Errorf("dir must be specified when using follow-schema layout")
    50  		}
    51  		r.DirName = abs(r.DirName)
    52  	default:
    53  		return fmt.Errorf("invalid layout %s", r.Layout)
    54  	}
    55  
    56  	if strings.ContainsAny(r.Package, "./\\") {
    57  		return fmt.Errorf("package should be the output package name only, do not include the output filename")
    58  	}
    59  
    60  	if r.Package == "" && r.Dir() != "" {
    61  		r.Package = code.NameForDir(r.Dir())
    62  	}
    63  
    64  	return nil
    65  }
    66  
    67  func (r *ExecConfig) ImportPath() string {
    68  	if r.Dir() == "" {
    69  		return ""
    70  	}
    71  	return code.ImportPathForDir(r.Dir())
    72  }
    73  
    74  func (r *ExecConfig) Dir() string {
    75  	switch r.Layout {
    76  	case ExecLayoutSingleFile:
    77  		if r.Filename == "" {
    78  			return ""
    79  		}
    80  		return filepath.Dir(r.Filename)
    81  	case ExecLayoutFollowSchema:
    82  		return abs(r.DirName)
    83  	default:
    84  		panic("invalid layout " + r.Layout)
    85  	}
    86  }
    87  
    88  func (r *ExecConfig) Pkg() *types.Package {
    89  	if r.Dir() == "" {
    90  		return nil
    91  	}
    92  	return types.NewPackage(r.ImportPath(), r.Package)
    93  }
    94  
    95  func (r *ExecConfig) IsDefined() bool {
    96  	return r.Filename != "" || r.DirName != ""
    97  }