github.com/speakeasy-api/sdk-gen-config@v1.14.2/lint/lint.go (about)

     1  package lint
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io/fs"
     7  	"os"
     8  
     9  	"github.com/daveshanley/vacuum/model"
    10  	"github.com/speakeasy-api/sdk-gen-config/workspace"
    11  	"gopkg.in/yaml.v3"
    12  )
    13  
    14  const (
    15  	LintVersion = "1.0.0"
    16  )
    17  
    18  const (
    19  	lintFile = "lint.yaml"
    20  )
    21  
    22  type Ruleset struct {
    23  	Rulesets []string               `yaml:"rulesets"`
    24  	Rules    map[string]*model.Rule `yaml:"rules"`
    25  }
    26  
    27  type Lint struct {
    28  	Version        string             `yaml:"lintVersion"`
    29  	DefaultRuleset string             `yaml:"defaultRuleset"`
    30  	Rulesets       map[string]Ruleset `yaml:"rulesets"`
    31  }
    32  
    33  func Load(searchDirs []string) (*Lint, string, error) {
    34  	var res *workspace.FindWorkspaceResult
    35  
    36  	dirsToSearch := map[string]bool{}
    37  
    38  	for _, dir := range searchDirs {
    39  		dirsToSearch[dir] = true
    40  	}
    41  
    42  	// Allow searching in the user's home directory
    43  	homeDir, err := os.UserHomeDir()
    44  	if err == nil {
    45  		dirsToSearch[homeDir] = false
    46  	}
    47  
    48  	for dir, allowRecursive := range dirsToSearch {
    49  		var err error
    50  
    51  		res, err = workspace.FindWorkspace(dir, workspace.FindWorkspaceOptions{
    52  			FindFile:  lintFile,
    53  			Recursive: allowRecursive,
    54  		})
    55  		if err != nil {
    56  			if !errors.Is(err, fs.ErrNotExist) {
    57  				return nil, "", err
    58  			}
    59  			continue
    60  		}
    61  
    62  		break
    63  	}
    64  	if res == nil || res.Data == nil {
    65  		return nil, "", fs.ErrNotExist
    66  	}
    67  
    68  	type lintHeader struct {
    69  		Version string `yaml:"lintVersion"`
    70  	}
    71  
    72  	var header lintHeader
    73  	if err := yaml.Unmarshal(res.Data, &header); err != nil {
    74  		return nil, "", fmt.Errorf("failed to unmarshal lint.yaml: %w", err)
    75  	}
    76  
    77  	if header.Version != LintVersion {
    78  		return nil, "", fmt.Errorf("unsupported lint version: %s", header.Version)
    79  	}
    80  
    81  	var lint Lint
    82  	if err := yaml.Unmarshal(res.Data, &lint); err != nil {
    83  		return nil, "", fmt.Errorf("failed to unmarshal lint.yaml: %w", err)
    84  	}
    85  
    86  	return &lint, res.Path, nil
    87  }