github.com/daixiang0/gci@v0.13.4/pkg/config/config.go (about)

     1  package config
     2  
     3  import (
     4  	"sort"
     5  	"strings"
     6  
     7  	"gopkg.in/yaml.v3"
     8  
     9  	"github.com/daixiang0/gci/pkg/section"
    10  )
    11  
    12  var defaultOrder = map[string]int{
    13  	section.StandardType:    0,
    14  	section.DefaultType:     1,
    15  	section.CustomType:      2,
    16  	section.BlankType:       3,
    17  	section.DotType:         4,
    18  	section.AliasType:       5,
    19  	section.LocalModuleType: 6,
    20  }
    21  
    22  type BoolConfig struct {
    23  	NoInlineComments bool `yaml:"no-inlineComments"`
    24  	NoPrefixComments bool `yaml:"no-prefixComments"`
    25  	Debug            bool `yaml:"-"`
    26  	SkipGenerated    bool `yaml:"skipGenerated"`
    27  	SkipVendor       bool `yaml:"skipVendor"`
    28  	CustomOrder      bool `yaml:"customOrder"`
    29  }
    30  
    31  type Config struct {
    32  	BoolConfig
    33  	Sections          section.SectionList
    34  	SectionSeparators section.SectionList
    35  }
    36  
    37  type YamlConfig struct {
    38  	Cfg                     BoolConfig `yaml:",inline"`
    39  	SectionStrings          []string   `yaml:"sections"`
    40  	SectionSeparatorStrings []string   `yaml:"sectionseparators"`
    41  
    42  	// Since history issue, Golangci-lint needs Analyzer to run and GCI add an Analyzer layer to integrate.
    43  	// The ModPath param is only from analyzer.go, no need to set it in all other places.
    44  	ModPath string `yaml:"-"`
    45  }
    46  
    47  func (g YamlConfig) Parse() (*Config, error) {
    48  	var err error
    49  
    50  	sections, err := section.Parse(g.SectionStrings)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  	if sections == nil {
    55  		sections = section.DefaultSections()
    56  	}
    57  	if err := configureSections(sections, g.ModPath); err != nil {
    58  		return nil, err
    59  	}
    60  
    61  	// if default order sorted sections
    62  	if !g.Cfg.CustomOrder {
    63  		sort.Slice(sections, func(i, j int) bool {
    64  			sectionI, sectionJ := sections[i].Type(), sections[j].Type()
    65  
    66  			if strings.Compare(sectionI, sectionJ) == 0 {
    67  				return strings.Compare(sections[i].String(), sections[j].String()) < 0
    68  			}
    69  			return defaultOrder[sectionI] < defaultOrder[sectionJ]
    70  		})
    71  	}
    72  
    73  	sectionSeparators, err := section.Parse(g.SectionSeparatorStrings)
    74  	if err != nil {
    75  		return nil, err
    76  	}
    77  	if sectionSeparators == nil {
    78  		sectionSeparators = section.DefaultSectionSeparators()
    79  	}
    80  
    81  	return &Config{g.Cfg, sections, sectionSeparators}, nil
    82  }
    83  
    84  func ParseConfig(in string) (*Config, error) {
    85  	config := YamlConfig{}
    86  
    87  	err := yaml.Unmarshal([]byte(in), &config)
    88  	if err != nil {
    89  		return nil, err
    90  	}
    91  
    92  	gciCfg, err := config.Parse()
    93  	if err != nil {
    94  		return nil, err
    95  	}
    96  
    97  	return gciCfg, nil
    98  }
    99  
   100  // configureSections now only do golang module path finding.
   101  // Since history issue, Golangci-lint needs Analyzer to run and GCI add an Analyzer layer to integrate.
   102  // The path param is from analyzer.go, in all other places should pass empty string.
   103  func configureSections(sections section.SectionList, path string) error {
   104  	for _, sec := range sections {
   105  		switch s := sec.(type) {
   106  		case *section.LocalModule:
   107  			if err := s.Configure(path); err != nil {
   108  				return err
   109  			}
   110  		}
   111  	}
   112  	return nil
   113  }