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 }