github.com/google/osv-scalibr@v0.4.1/guidedremediation/internal/manifest/python/poetry_test.go (about) 1 // Copyright 2025 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package python 16 17 import ( 18 "os" 19 "path/filepath" 20 "testing" 21 22 "deps.dev/util/resolve" 23 "deps.dev/util/resolve/dep" 24 "github.com/google/go-cmp/cmp" 25 "github.com/google/osv-scalibr/fs" 26 "github.com/google/osv-scalibr/guidedremediation/internal/manifest" 27 "github.com/google/osv-scalibr/guidedremediation/result" 28 ) 29 30 func TestReadPoetry(t *testing.T) { 31 fsys := fs.DirFS("./testdata/poetry") 32 poetryRW, _ := GetPoetryReadWriter() 33 got, err := poetryRW.Read("pyproject.toml", fsys) 34 if err != nil { 35 t.Fatalf("error reading manifest: %v", err) 36 } 37 38 var optionalType dep.Type 39 optionalType.AddAttr(dep.Opt, "") 40 41 want := testManifest{ 42 FilePath: "pyproject.toml", 43 Root: resolve.Version{ 44 VersionKey: resolve.VersionKey{ 45 PackageKey: resolve.PackageKey{ 46 System: resolve.PyPI, 47 Name: "my-project", 48 }, 49 VersionType: resolve.Concrete, 50 Version: "1.2.3", 51 }, 52 }, 53 System: resolve.PyPI, 54 Requirements: []resolve.RequirementVersion{ 55 { 56 VersionKey: resolve.VersionKey{ 57 PackageKey: resolve.PackageKey{ 58 System: resolve.PyPI, 59 Name: "requests", 60 }, 61 Version: "~=2.25.1", 62 VersionType: resolve.Requirement, 63 }, 64 }, 65 { 66 VersionKey: resolve.VersionKey{ 67 PackageKey: resolve.PackageKey{ 68 System: resolve.PyPI, 69 Name: "numpy", 70 }, 71 Version: "==1.22.0", 72 VersionType: resolve.Requirement, 73 }, 74 }, 75 { 76 VersionKey: resolve.VersionKey{ 77 PackageKey: resolve.PackageKey{ 78 System: resolve.PyPI, 79 Name: "django", 80 }, 81 Version: ">2.1,<3.0", 82 VersionType: resolve.Requirement, 83 }, 84 }, 85 { 86 VersionKey: resolve.VersionKey{ 87 PackageKey: resolve.PackageKey{ 88 System: resolve.PyPI, 89 Name: "django", 90 }, 91 Version: ">2.0,<3.0", 92 VersionType: resolve.Requirement, 93 }, 94 }, 95 { 96 VersionKey: resolve.VersionKey{ 97 PackageKey: resolve.PackageKey{ 98 System: resolve.PyPI, 99 Name: "pytest", 100 }, 101 Version: ">=6.2.5", 102 VersionType: resolve.Requirement, 103 }, 104 Type: optionalType, 105 }, 106 { 107 VersionKey: resolve.VersionKey{ 108 PackageKey: resolve.PackageKey{ 109 System: resolve.PyPI, 110 Name: "black", 111 }, 112 Version: "==22.3.0", 113 VersionType: resolve.Requirement, 114 }, 115 Type: optionalType, 116 }, 117 }, 118 Groups: map[manifest.RequirementKey][]string{ 119 manifest.RequirementKey(resolve.PackageKey{System: resolve.PyPI, Name: "pytest"}): {"dev"}, 120 manifest.RequirementKey(resolve.PackageKey{System: resolve.PyPI, Name: "black"}): {"dev"}, 121 }, 122 } 123 checkManifest(t, "Manifest", got, want) 124 } 125 126 func TestWritePoetry(t *testing.T) { 127 rw, _ := GetPoetryReadWriter() 128 fsys := fs.DirFS("./testdata/poetry") 129 manif, err := rw.Read("pyproject.toml", fsys) 130 if err != nil { 131 t.Fatalf("error reading manifest: %v", err) 132 } 133 134 patches := []result.Patch{ 135 { 136 PackageUpdates: []result.PackageUpdate{ 137 { 138 Name: "requests", 139 VersionFrom: "~=2.25.1", 140 VersionTo: ">=2.26.0,<3.0.0", 141 }, 142 }, 143 }, 144 { 145 PackageUpdates: []result.PackageUpdate{ 146 { 147 Name: "black", 148 VersionFrom: "==22.3.0", 149 VersionTo: "==23.0.0", 150 }, 151 }, 152 }, 153 { 154 PackageUpdates: []result.PackageUpdate{ 155 { 156 Name: "django", 157 VersionFrom: ">2.1,<3.0", 158 VersionTo: ">=3.1,<4.0", 159 }, 160 }, 161 }, 162 { 163 PackageUpdates: []result.PackageUpdate{ 164 { 165 Name: "django", 166 VersionFrom: ">2.0,<3.0", 167 VersionTo: ">=3.0,<4.0", 168 }, 169 }, 170 }, 171 } 172 outDir := t.TempDir() 173 outFile := filepath.Join(outDir, "pyproject.toml") 174 175 if err := rw.Write(manif, fsys, patches, outFile); err != nil { 176 t.Fatalf("failed to write manifest: %v", err) 177 } 178 179 got, err := os.ReadFile(outFile) 180 if err != nil { 181 t.Fatalf("failed to read got pyproject.toml: %v", err) 182 } 183 want, err := os.ReadFile(filepath.Join("./testdata/poetry", "want.pyproject.toml")) 184 if err != nil { 185 t.Fatalf("failed to read want pyproject.toml: %v", err) 186 } 187 if diff := cmp.Diff(want, got); diff != "" { 188 t.Errorf("pyproject.toml (-want +got):\n%s", diff) 189 } 190 }