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

     1  package config
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  )
     7  
     8  var ErrFailedUpgrade = errors.New("failed to upgrade config")
     9  
    10  type UpgradeFunc func(target, template, oldVersion, newVersion string, cfg map[string]any) (map[string]any, error)
    11  
    12  func upgrade(currentVersion string, cfg map[string]any, lockFile map[string]any, uf UpgradeFunc) (map[string]any, map[string]any, error) {
    13  	if currentVersion == "" {
    14  		var err error
    15  		currentVersion, cfg, err = upgradeToV100(cfg, uf)
    16  		if err != nil {
    17  			return nil, nil, err
    18  		}
    19  	}
    20  
    21  	if currentVersion == v1 {
    22  		var err error
    23  		currentVersion, cfg, lockFile, err = upgradeToV200(cfg, uf)
    24  		if err != nil {
    25  			return nil, nil, err
    26  		}
    27  	}
    28  
    29  	// Put upgrade logic for future versions here, also upgrade incrementally between versions
    30  
    31  	if currentVersion != Version {
    32  		return nil, nil, ErrFailedUpgrade
    33  	}
    34  
    35  	return cfg, lockFile, nil
    36  }
    37  
    38  func upgradeToV100(cfg map[string]any, uf UpgradeFunc) (string, map[string]any, error) {
    39  	generation := map[string]any{}
    40  	upgraded := map[string]any{
    41  		"configVersion": v1,
    42  		"generation":    generation,
    43  	}
    44  
    45  	if mgmtAny, ok := cfg["management"]; ok {
    46  		mgmt, ok := mgmtAny.(map[string]any)
    47  		if !ok {
    48  			return "", nil, fmt.Errorf("%w: management is not a map", ErrFailedUpgrade)
    49  		}
    50  
    51  		upgraded["management"] = map[string]any{
    52  			"docChecksum":      mgmt["openapi-checksum"],
    53  			"docVersion":       mgmt["openapi-version"],
    54  			"speakeasyVersion": mgmt["speakeasy-version"],
    55  		}
    56  		delete(cfg, "management")
    57  	}
    58  
    59  	if commentsAny, ok := cfg["comments"]; ok {
    60  		comments, ok := commentsAny.(map[string]any)
    61  		if !ok {
    62  			return "", nil, fmt.Errorf("%w: comments is not a map", ErrFailedUpgrade)
    63  		}
    64  
    65  		generation["comments"] = map[string]any{
    66  			"disableComments":                 comments["disabled"],
    67  			"omitDescriptionIfSummaryPresent": comments["omitdescriptionifsummarypresent"],
    68  		}
    69  		delete(cfg, "comments")
    70  	}
    71  
    72  	baseServerURL, ok := cfg["baseserverurl"]
    73  	if ok {
    74  		generation["baseServerUrl"] = baseServerURL
    75  		delete(cfg, "baseserverurl")
    76  	}
    77  
    78  	sdkClassName, ok := cfg["sdkclassname"]
    79  	if ok {
    80  		generation["sdkClassName"] = sdkClassName
    81  		delete(cfg, "sdkclassname")
    82  	}
    83  
    84  	tagNamespacingDisabled, ok := cfg["tagnamespacingdisabled"]
    85  	if ok {
    86  		generation["tagNamespacingDisabled"] = tagNamespacingDisabled
    87  		delete(cfg, "tagnamespacingdisabled")
    88  	}
    89  
    90  	// Remaining keys are language configs
    91  	for lang, langCfgAny := range cfg {
    92  		langCfg, ok := langCfgAny.(map[string]any)
    93  		if !ok {
    94  			return "", nil, fmt.Errorf("%w: %s is not a map", ErrFailedUpgrade, lang)
    95  		}
    96  
    97  		langCfg, err := uf(lang, lang, "", v1, langCfg)
    98  		if err != nil {
    99  			return "", nil, err
   100  		}
   101  
   102  		upgraded[lang] = langCfg
   103  	}
   104  
   105  	return v1, upgraded, nil
   106  }
   107  
   108  func upgradeToV200(cfg map[string]any, uf UpgradeFunc) (string, map[string]any, map[string]any, error) {
   109  	upgradedConfig := map[string]any{
   110  		"configVersion": v2,
   111  	}
   112  
   113  	newLockFile := map[string]any{
   114  		"lockVersion": v2,
   115  		"id":          getUUID(),
   116  	}
   117  
   118  	delete(cfg, "configVersion")
   119  
   120  	management := map[string]any{}
   121  	if mgmt, ok := cfg["management"]; ok {
   122  		management, ok = mgmt.(map[string]any)
   123  		if !ok {
   124  			return "", nil, nil, fmt.Errorf("%w: management is not a map", ErrFailedUpgrade)
   125  		}
   126  		delete(cfg, "management")
   127  	}
   128  
   129  	if features, ok := cfg["features"]; ok {
   130  		newLockFile["features"] = features
   131  		delete(cfg, "features")
   132  	}
   133  
   134  	if generation, ok := cfg["generation"]; ok {
   135  		genMap, ok := generation.(map[string]any)
   136  		if !ok {
   137  			return "", nil, nil, fmt.Errorf("%w: generation is not a map", ErrFailedUpgrade)
   138  		}
   139  
   140  		if repoURL, ok := genMap["repoURL"]; ok {
   141  			management["repoURL"] = repoURL
   142  			delete(genMap, "repoURL")
   143  		}
   144  
   145  		delete(genMap, "comments")
   146  		delete(genMap, "singleTagPerOp")
   147  		delete(genMap, "tagNamespacingDisabled")
   148  
   149  		upgradedConfig["generation"] = genMap
   150  		delete(cfg, "generation")
   151  	}
   152  
   153  	// Remaining keys are language configs
   154  	for lang, langCfgAny := range cfg {
   155  		langCfg, ok := langCfgAny.(map[string]any)
   156  		if !ok {
   157  			return "", nil, nil, fmt.Errorf("%w: %s is not a map", ErrFailedUpgrade, lang)
   158  		}
   159  
   160  		if published, ok := langCfg["published"]; ok {
   161  			management["published"] = published
   162  			delete(langCfg, "published")
   163  		}
   164  
   165  		if repoSubDirectory, ok := langCfg["repoSubDirectory"]; ok {
   166  			management["repoSubDirectory"] = repoSubDirectory
   167  			delete(langCfg, "repoSubDirectory")
   168  		}
   169  
   170  		if installationURL, ok := langCfg["installationURL"]; ok {
   171  			management["installationURL"] = installationURL
   172  			delete(langCfg, "installationURL")
   173  		}
   174  
   175  		if version, ok := langCfg["version"]; ok {
   176  			management["releaseVersion"] = version
   177  		}
   178  
   179  		langCfg, err := uf(lang, lang, v1, v2, langCfg)
   180  		if err != nil {
   181  			return "", nil, nil, err
   182  		}
   183  
   184  		upgradedConfig[lang] = langCfg
   185  	}
   186  
   187  	if len(management) > 0 {
   188  		newLockFile["management"] = management
   189  	}
   190  
   191  	return v2, upgradedConfig, newLockFile, nil
   192  }