github.com/replit/upm@v0.0.0-20240423230255-9ce4fc3ea24c/test-suite/utils/upm.go (about) 1 package testUtils 2 3 import ( 4 "encoding/json" 5 "strings" 6 7 "github.com/replit/upm/internal/api" 8 ) 9 10 func (bt *BackendT) UpmAdd(pkgs ...string) { 11 beforeSpecDeps := bt.UpmListSpecFile() 12 13 var beforeLockDeps []api.PkgInfo 14 if bt.Backend.QuirksIsReproducible() { 15 beforeLockDeps = bt.UpmListLockFile() 16 } 17 18 args := []string{ 19 "--lang", 20 bt.Backend.Name, 21 "add", 22 } 23 _, err := bt.Exec( 24 "upm", 25 append(args, pkgs...)..., 26 ) 27 28 if err != nil { 29 bt.Fail("upm failed to add: %v", err) 30 } 31 32 afterSpecDeps := bt.UpmListSpecFile() 33 var afterLockDeps []api.PkgInfo 34 35 if bt.Backend.QuirksIsReproducible() { 36 afterLockDeps = bt.UpmListLockFile() 37 if len(beforeLockDeps) >= len(afterLockDeps) { 38 bt.Fail("expected more deps in lock file after add (before %d, after %d)", len(beforeLockDeps), len(afterLockDeps)) 39 } 40 } 41 42 if len(beforeSpecDeps) >= len(afterSpecDeps) { 43 bt.Fail("expected more deps in lock file after add (before %d, after %d)", len(beforeSpecDeps), len(afterSpecDeps)) 44 } 45 46 for pkg := range bt.Backend.NormalizePackageArgs(pkgs) { 47 if bt.Backend.QuirksIsReproducible() { 48 found := false 49 for _, dep := range afterLockDeps { 50 if bt.Backend.NormalizePackageName(api.PkgName(dep.Name)) == pkg { 51 found = true 52 break 53 } 54 } 55 if !found { 56 bt.Fail("expected %s in lock file after add", pkg) 57 } 58 } 59 60 found := false 61 for _, dep := range afterSpecDeps { 62 if bt.Backend.NormalizePackageName(api.PkgName(dep.Name)) == pkg { 63 found = true 64 break 65 } 66 } 67 if !found { 68 bt.Fail("expected %s in spec file after add", pkg) 69 } 70 } 71 } 72 73 func (bt *BackendT) UpmGuess(expect ...string) { 74 out, err := bt.Exec( 75 "upm", 76 "--lang", 77 bt.Backend.Name, 78 "guess", 79 ) 80 81 if err != nil { 82 bt.Fail("upm failed to guess: %v", err) 83 } 84 85 guesses := strings.Split(strings.TrimSpace(out.Stdout), "\n") 86 for len(guesses) > 0 { 87 guess := guesses[0] 88 guesses = guesses[1:] 89 if guess == "" { 90 continue 91 } 92 93 found := false 94 for ii, expected := range expect { 95 if guess == expected { 96 found = true 97 expect = append(expect[:ii], expect[ii+1:]...) 98 break 99 } 100 } 101 102 if !found { 103 bt.Fail("unexpected guess %s", guess) 104 } 105 } 106 107 if len(expect) != 0 { 108 bt.Fail("expected guesses %v", expect) 109 } 110 } 111 112 func (bt *BackendT) UpmInfo(pkg string) { 113 out, err := bt.Exec( 114 "upm", 115 "--lang", 116 bt.Backend.Name, 117 "info", 118 "--format", 119 "json", 120 pkg, 121 ) 122 123 if err != nil { 124 bt.Fail("upm failed to get info: %v", err) 125 } 126 127 var info api.PkgInfo 128 err = json.NewDecoder(strings.NewReader(out.Stdout)).Decode(&info) 129 if err != nil { 130 bt.Fail("failed to decode json: %v", err) 131 } 132 133 if info.Name != pkg { 134 bt.Fail("expected info for %s, got %s", pkg, info.Name) 135 } 136 } 137 138 func (bt *BackendT) UpmInstall() { 139 _, err := bt.Exec( 140 "upm", 141 "--lang", 142 bt.Backend.Name, 143 "install", 144 ) 145 146 if err != nil { 147 bt.Fail("upm failed to install: %v", err) 148 } 149 } 150 151 func normalizePackageNames(bt *BackendT, pkgs []api.PkgInfo) []api.PkgInfo { 152 for idx, pkg := range pkgs { 153 out := (string)(bt.Backend.NormalizePackageName(api.PkgName(pkg.Name))) 154 if pkgs[idx].Name != out { 155 bt.t.Log("Inconsistently normalized package name in results: ", pkgs[idx].Name, "did not equal", out) 156 } 157 pkgs[idx].Name = out 158 } 159 return pkgs 160 } 161 162 func (bt *BackendT) UpmListLockFile() []api.PkgInfo { 163 out, err := bt.Exec( 164 "upm", 165 "--lang", 166 bt.Backend.Name, 167 "list", 168 "--all", 169 "--format", 170 "json", 171 ) 172 173 if err != nil { 174 bt.Fail("upm failed to list: %v", err) 175 } 176 177 var results []api.PkgInfo 178 err = json.NewDecoder(strings.NewReader(out.Stdout)).Decode(&results) 179 if err != nil { 180 bt.Fail("failed to decode json: %v", err) 181 } 182 183 return normalizePackageNames(bt, results) 184 } 185 186 func (bt *BackendT) UpmListSpecFile() []api.PkgInfo { 187 out, err := bt.Exec( 188 "upm", 189 "--lang", 190 bt.Backend.Name, 191 "list", 192 "--format", 193 "json", 194 ) 195 196 if err != nil { 197 bt.Fail("upm failed to list: %v", err) 198 } 199 200 var results []api.PkgInfo 201 err = json.NewDecoder(strings.NewReader(out.Stdout)).Decode(&results) 202 if err != nil { 203 bt.Fail("failed to decode json: %v", err) 204 } 205 206 return normalizePackageNames(bt, results) 207 } 208 209 func (bt *BackendT) UpmLock() { 210 _, err := bt.Exec( 211 "upm", 212 "--lang", 213 bt.Backend.Name, 214 "lock", 215 ) 216 217 if err != nil { 218 bt.Fail("upm failed to lock: %v", err) 219 } 220 } 221 222 func (bt *BackendT) UpmPackageDir() string { 223 out, err := bt.Exec( 224 "upm", 225 "--lang", 226 bt.Backend.Name, 227 "show-package-dir", 228 ) 229 230 if err != nil { 231 bt.Fail("upm failed to show package dir: %v", err) 232 } 233 234 return strings.TrimSpace(out.Stdout) 235 } 236 237 func (bt *BackendT) UpmRemove(pkgs ...string) { 238 beforeSpecDeps := bt.UpmListSpecFile() 239 240 if len(beforeSpecDeps) < len(pkgs) { 241 bt.Fail("expected deps to be in spec file before remove %v", pkgs) 242 } 243 244 specsExpectedToStay := []string{} 245 246 for _, dep := range beforeSpecDeps { 247 removing := false 248 for _, pkg := range pkgs { 249 if dep.Name == pkg { 250 removing = true 251 break 252 } 253 } 254 255 if !removing { 256 specsExpectedToStay = append(specsExpectedToStay, dep.Name) 257 } 258 } 259 260 args := []string{ 261 "--lang", 262 bt.Backend.Name, 263 "remove", 264 } 265 _, err := bt.Exec( 266 "upm", 267 append(args, pkgs...)..., 268 ) 269 270 if err != nil { 271 bt.Fail("upm failed to remove: %v", err) 272 } 273 274 afterLockDeps := bt.UpmListLockFile() 275 afterSpecDeps := bt.UpmListSpecFile() 276 277 if len(beforeSpecDeps) <= len(afterSpecDeps) { 278 bt.Fail("expected fewer deps in spec file after remove (before %d, after %d)", len(beforeSpecDeps), len(afterSpecDeps)) 279 } 280 281 for _, pkg := range pkgs { 282 if bt.Backend.QuirksIsReproducible() { 283 for _, dep := range afterLockDeps { 284 if dep.Name == pkg { 285 bt.Fail("expected %s not in lock file after remove", pkg) 286 } 287 } 288 } 289 290 for _, dep := range afterSpecDeps { 291 if dep.Name == pkg { 292 bt.Fail("expected %s not in spec file after remove", pkg) 293 } 294 } 295 } 296 297 for _, afterDep := range afterSpecDeps { 298 for ii, beforeDep := range specsExpectedToStay { 299 if afterDep.Name == beforeDep { 300 specsExpectedToStay = append(specsExpectedToStay[:ii], specsExpectedToStay[ii+1:]...) 301 break 302 } 303 } 304 } 305 306 if len(specsExpectedToStay) != 0 { 307 bt.Fail("upm removed %v from spec file", specsExpectedToStay) 308 } 309 } 310 311 func (bt *BackendT) UpmSearch(query, expectName string) { 312 out, err := bt.Exec( 313 "upm", 314 "--lang", 315 bt.Backend.Name, 316 "search", 317 "--format", 318 "json", 319 query, 320 ) 321 322 if err != nil { 323 bt.t.Fatalf("upm failed to search: %v", err) 324 } 325 326 var results []api.PkgInfo 327 err = json.NewDecoder(strings.NewReader(out.Stdout)).Decode(&results) 328 if err != nil { 329 bt.Fail("failed to decode json: %v", err) 330 } 331 332 found := false 333 for _, result := range results { 334 if result.Name == expectName { 335 found = true 336 break 337 } 338 } 339 340 if !found { 341 bt.Fail("expected %s in search results for query %s", expectName, query) 342 } 343 } 344 345 func (bt *BackendT) UpmWhichLanguage() { 346 out, err := bt.Exec("upm", "which-language") 347 if err != nil { 348 bt.Fail("upm failed to detect language: %v", err) 349 } 350 351 detected := strings.TrimSpace(out.Stdout) 352 if detected != bt.Backend.Name { 353 bt.Fail("expected %s, got %s", bt.Backend.Name, detected) 354 } 355 } 356 357 func (bt *BackendT) UpmInstallReplitNixSystemDependencies() { 358 _, err := bt.Exec( 359 "upm", 360 "--lang", 361 bt.Backend.Name, 362 "install-replit-nix-system-dependencies", 363 ) 364 365 if err != nil { 366 bt.Fail("upm failed to install-replit-nix-system-dependencies: %v", err) 367 } 368 }