From b3b4f6e09dbd4c3387f5e1174ad2c5d66423cf79 Mon Sep 17 00:00:00 2001 From: Christopher Hunter Date: Wed, 5 Jul 2023 16:23:40 -0700 Subject: [PATCH 1/7] feat: add functions to read BOSH release metadata --- .../workflows/scenario/step_funcs_tile.go | 2 +- pkg/tile/bosh_release.go | 187 ++++++++++++++++++ pkg/tile/bosh_release_test.go | 147 ++++++++++++++ pkg/tile/release.go | 72 ------- pkg/tile/releases_test.go | 31 --- .../bpm-1.1.21-ubuntu-xenial-621.463.tgz | Bin 0 -> 1415 bytes pkg/tile/testdata/bpm-1.1.21.tgz | Bin 0 -> 5877 bytes 7 files changed, 335 insertions(+), 104 deletions(-) create mode 100644 pkg/tile/bosh_release.go create mode 100644 pkg/tile/bosh_release_test.go delete mode 100644 pkg/tile/release.go delete mode 100644 pkg/tile/releases_test.go create mode 100644 pkg/tile/testdata/bpm-1.1.21-ubuntu-xenial-621.463.tgz create mode 100644 pkg/tile/testdata/bpm-1.1.21.tgz diff --git a/internal/acceptance/workflows/scenario/step_funcs_tile.go b/internal/acceptance/workflows/scenario/step_funcs_tile.go index 336b36f4b..00152ffd6 100644 --- a/internal/acceptance/workflows/scenario/step_funcs_tile.go +++ b/internal/acceptance/workflows/scenario/step_funcs_tile.go @@ -78,7 +78,7 @@ func theTileOnlyContainsCompiledReleases(ctx context.Context) error { for _, release := range metadata.Releases { helloReleaseTarball := bytes.NewBuffer(nil) - _, err := tile.ReadReleaseFromFile(tilePath, release.Name, release.Version, helloReleaseTarball) + _, err := tile.ReadBOSHReleaseFromFile(tilePath, release.Name, release.Version, helloReleaseTarball) if err != nil { return err } diff --git a/pkg/tile/bosh_release.go b/pkg/tile/bosh_release.go new file mode 100644 index 000000000..9002f984b --- /dev/null +++ b/pkg/tile/bosh_release.go @@ -0,0 +1,187 @@ +package tile + +import ( + "archive/tar" + "archive/zip" + "compress/gzip" + "crypto/sha1" + "encoding/hex" + "fmt" + "hash" + "io" + "io/fs" + "os" + "path" + + "golang.org/x/exp/slices" + "gopkg.in/yaml.v2" + + "github.com/pivotal-cf/kiln/pkg/proofing" +) + +func ReadBOSHReleaseFromFile(tilePath, releaseName, releaseVersion string, releaseTarball io.Writer) (proofing.Release, error) { + f, err := os.Open(tilePath) + if err != nil { + return proofing.Release{}, err + } + defer closeAndIgnoreError(f) + fi, err := f.Stat() + if err != nil { + return proofing.Release{}, err + } + return ReadBOSHReleaseFromZip(f, fi.Size(), releaseName, releaseVersion, releaseTarball) +} + +func ReadBOSHReleaseFromZip(ra io.ReaderAt, zipFileSize int64, releaseName, releaseVersion string, releaseTarball io.Writer) (proofing.Release, error) { + zr, err := zip.NewReader(ra, zipFileSize) + if err != nil { + return proofing.Release{}, fmt.Errorf("failed to do open metadata zip reader: %w", err) + } + return ReadBOSHReleaseFromFS(zr, releaseName, releaseVersion, releaseTarball) +} + +func ReadBOSHReleaseFromFS(dir fs.FS, releaseName, releaseVersion string, releaseTarball io.Writer) (proofing.Release, error) { + metadataBuf, err := ReadMetadataFromFS(dir) + if err != nil { + return proofing.Release{}, err + } + + var metadata struct { + Releases []proofing.Release `yaml:"releases"` + } + err = yaml.Unmarshal(metadataBuf, &metadata) + if err != nil { + return proofing.Release{}, err + } + + releaseIndex := slices.IndexFunc(metadata.Releases, func(release proofing.Release) bool { + return release.Name == releaseName && release.Version == releaseVersion + }) + if releaseIndex == -1 { + return proofing.Release{}, fmt.Errorf("release not found with %s/%s", releaseName, releaseVersion) + } + release := metadata.Releases[releaseIndex] + + f, err := dir.Open(path.Join("releases", release.File)) + if err != nil { + return proofing.Release{}, err + } + defer closeAndIgnoreError(f) + + _, err = io.Copy(releaseTarball, f) + if err != nil { + return proofing.Release{}, fmt.Errorf("failed to copy release tarball: %w", err) + } + + return release, nil +} + +type BOSHReleasePackage struct { + Name string `yaml:"name"` + Version string `yaml:"version"` + Fingerprint string `yaml:"fingerprint"` + SHA1 string `yaml:"sha1"` + Dependencies []string `yaml:"dependencies"` +} + +type CompiledBOSHReleasePackage struct { + Name string `yaml:"name"` + Version string `yaml:"version"` + Fingerprint string `yaml:"fingerprint"` + SHA1 string `yaml:"sha1"` + Dependencies []string `yaml:"dependencies"` + + Stemcell string `yaml:"stemcell"` +} + +type BOSHReleaseManifest struct { + Name string `yaml:"name,omitempty"` + Version string `yaml:"version,omitempty"` + CommitHash string `yaml:"commit_hash,omitempty"` + UncommittedChanges bool `yaml:"uncommitted_changes"` + + CompiledPackages []CompiledBOSHReleasePackage `yaml:"compiled_packages"` + Packages []BOSHReleasePackage `yaml:"packages"` +} + +type BOSHReleaseTarball struct { + Manifest BOSHReleaseManifest + + SHA1 string + FilePath string +} + +func ReadBOSHReleaseManifestsFromTarballs(dir fs.FS, tarballPaths ...string) ([]BOSHReleaseTarball, error) { + results := make([]BOSHReleaseTarball, 0, len(tarballPaths)) + for _, tarballPath := range tarballPaths { + mf, err := openAndProcessFile(dir, tarballPath, ReadProductTemplatePartFromBOSHReleaseTarball) + if err != nil { + return nil, err + } + sha1Checksum, err := openAndProcessFile(dir, tarballPath, calculateChecksum(sha1.New())) + if err != nil { + return nil, err + } + + results = append(results, BOSHReleaseTarball{ + Manifest: mf, + SHA1: sha1Checksum, + FilePath: tarballPath, + }) + } + return slices.Clip(results), nil +} + +func openAndProcessFile[T any](dir fs.FS, fileName string, process func(io.Reader) (T, error)) (T, error) { + file, err := dir.Open(fileName) + if err != nil { + var zero T + return zero, err + } + defer closeAndIgnoreError(file) + return process(file) +} + +func ReadProductTemplatePartFromBOSHReleaseTarball(r io.Reader) (BOSHReleaseManifest, error) { + gzipReader, err := gzip.NewReader(r) + if err != nil { + return BOSHReleaseManifest{}, err + } + tarReader := tar.NewReader(gzipReader) + + for { + header, err := tarReader.Next() + if err != nil { + if err != io.EOF { + return BOSHReleaseManifest{}, err + } + break + } + if path.Base(header.Name) != "release.MF" { + continue + } + releaseMFBuffer, err := io.ReadAll(tarReader) + if err != nil { + return BOSHReleaseManifest{}, err + } + + var releaseMF BOSHReleaseManifest + + if err := yaml.Unmarshal(releaseMFBuffer, &releaseMF); err != nil { + return BOSHReleaseManifest{}, err + } + + return releaseMF, nil + } + return BOSHReleaseManifest{}, fmt.Errorf("failed to find release.MF in tarball") +} + +func calculateChecksum(h hash.Hash) func(r io.Reader) (string, error) { + return func(r io.Reader) (string, error) { + _, err := io.Copy(h, r) + if err != nil { + return "", err + } + return hex.EncodeToString(h.Sum(nil)), nil + } +} diff --git a/pkg/tile/bosh_release_test.go b/pkg/tile/bosh_release_test.go new file mode 100644 index 000000000..c82c0d692 --- /dev/null +++ b/pkg/tile/bosh_release_test.go @@ -0,0 +1,147 @@ +package tile_test + +import ( + "bytes" + "github.com/stretchr/testify/require" + "io" + "os" + "path/filepath" + "testing" + + "github.com/pivotal-cf/kiln/pkg/proofing" + + . "github.com/onsi/gomega" + + "github.com/pivotal-cf/kiln/pkg/tile" +) + +func TestReadReleaseFromFile(t *testing.T) { + please := NewWithT(t) + + buf := bytes.NewBuffer(nil) + releaseMetadata, err := tile.ReadBOSHReleaseFromFile(filepath.Join("testdata", "tile-0.1.2.pivotal"), "hello-release", "v0.1.4", buf) + please.Expect(err).NotTo(HaveOccurred()) + + please.Expect(releaseMetadata).To(Equal(proofing.Release{ + File: "hello-release-v0.1.4-ubuntu-xenial-621.256.tgz", + Name: "hello-release", + SHA1: "c471ac6371eb8fc24508b14d9a49a44f9a5ef98c", + Version: "v0.1.4", + })) + + _, err = io.ReadAll(buf) + please.Expect(err).NotTo(HaveOccurred()) +} + +func TestReadProductTemplatePartFromBOSHReleaseTarball(t *testing.T) { + t.Run("when the release is compiled", func(t *testing.T) { + f, err := os.Open(filepath.Join("testdata", "bpm-1.1.21-ubuntu-xenial-621.463.tgz")) + require.NoError(t, err) + t.Cleanup(func() { + closeAndIgnoreError(f) + }) + + result, err := tile.ReadProductTemplatePartFromBOSHReleaseTarball(f) + require.NoError(t, err) + + require.Equal(t, tile.BOSHReleaseManifest{ + Name: "bpm", + Version: "1.1.21", + CommitHash: "fd88358", UncommittedChanges: false, CompiledPackages: []tile.CompiledBOSHReleasePackage{ + { + Name: "bpm", + Version: "be375c78c703cea04667ea7cbbc6d024bb391182", + Fingerprint: "be375c78c703cea04667ea7cbbc6d024bb391182", + SHA1: "b67ab0ceb0cab69a170521bb1a77c91a8546ac21", + Dependencies: []string{"golang-1-linux", "bpm-runc", "tini"}, + Stemcell: "ubuntu-xenial/621.463"}, + { + Name: "test-server", + Version: "12eba471a2c3dddb8547ef03c23a3231d1f62e6c", + Fingerprint: "12eba471a2c3dddb8547ef03c23a3231d1f62e6c", + SHA1: "7ab0c2066c63eb5c5dd2c06d35b73376f4ad9a81", + Dependencies: []string{"golang-1-linux"}, + Stemcell: "ubuntu-xenial/621.463"}, + { + Name: "bpm-runc", + Version: "464c6e6611f814bd12016156bf3e682486f34672", + Fingerprint: "464c6e6611f814bd12016156bf3e682486f34672", + SHA1: "bacd602ee0830a30c17b7a502aa0021a6739a3ff", + Dependencies: []string{"golang-1-linux"}, + Stemcell: "ubuntu-xenial/621.463"}, + { + Name: "golang-1-linux", + Version: "2336380dbf01a44020813425f92be34685ce118bf4767406c461771cfef14fc9", + Fingerprint: "2336380dbf01a44020813425f92be34685ce118bf4767406c461771cfef14fc9", + SHA1: "e8dad3e51eeb5f5fb41dd56bbb8a3ec9655bd4f7", + Dependencies: []string{}, + Stemcell: "ubuntu-xenial/621.463"}, + { + Name: "tini", + Version: "3d7b02f3eeb480b9581bec4a0096dab9ebdfa4bc", + Fingerprint: "3d7b02f3eeb480b9581bec4a0096dab9ebdfa4bc", + SHA1: "347c76d509ad4b82d99bbbb4b291768ff90b0fba", + Dependencies: []string{}, + Stemcell: "ubuntu-xenial/621.463"}, + }, + }, result) + }) + + t.Run("when the release is not compiled", func(t *testing.T) { + f, err := os.Open(filepath.Join("testdata", "bpm-1.1.21.tgz")) + require.NoError(t, err) + t.Cleanup(func() { + closeAndIgnoreError(f) + }) + + result, err := tile.ReadProductTemplatePartFromBOSHReleaseTarball(f) + require.NoError(t, err) + + require.Equal(t, tile.BOSHReleaseManifest{ + Name: "bpm", + Version: "1.1.21", + CommitHash: "fd88358", + UncommittedChanges: false, + Packages: []tile.BOSHReleasePackage{ + { + Name: "bpm", + Version: "be375c78c703cea04667ea7cbbc6d024bb391182", + Fingerprint: "be375c78c703cea04667ea7cbbc6d024bb391182", + SHA1: "6ae70da9768bd7333b883463e089c65bea44c685", + Dependencies: []string{"golang-1-linux", "bpm-runc", "tini"}}, + { + Name: "bpm-runc", + Version: "464c6e6611f814bd12016156bf3e682486f34672", + Fingerprint: "464c6e6611f814bd12016156bf3e682486f34672", + SHA1: "1a141265caca8b61209349efdbd4ecbc3f802526", + Dependencies: []string{"golang-1-linux"}, + }, + { + Name: "golang-1-linux", + Version: "2336380dbf01a44020813425f92be34685ce118bf4767406c461771cfef14fc9", + Fingerprint: "2336380dbf01a44020813425f92be34685ce118bf4767406c461771cfef14fc9", + SHA1: "sha256:c440fd7aa6d179a6891f765c46f69fa2b6cbadd8da3b019a4fb27fc9001a4f1f", + Dependencies: []string{}, + }, + { + Name: "test-server", + Version: "12eba471a2c3dddb8547ef03c23a3231d1f62e6c", + Fingerprint: "12eba471a2c3dddb8547ef03c23a3231d1f62e6c", + SHA1: "28e74c692da08a1c065052d118b6c1324caa6e8b", + Dependencies: []string{"golang-1-linux"}, + }, + { + Name: "tini", + Version: "3d7b02f3eeb480b9581bec4a0096dab9ebdfa4bc", + Fingerprint: "3d7b02f3eeb480b9581bec4a0096dab9ebdfa4bc", + SHA1: "3d16adbc5ed9bc46a46503cd4f12d883a28fa991", + Dependencies: []string{}, + }, + }, + }, result) + }) +} + +func closeAndIgnoreError(c io.Closer) { + _ = c.Close() +} diff --git a/pkg/tile/release.go b/pkg/tile/release.go deleted file mode 100644 index 3cddb6f33..000000000 --- a/pkg/tile/release.go +++ /dev/null @@ -1,72 +0,0 @@ -package tile - -import ( - "archive/zip" - "fmt" - "io" - "io/fs" - "os" - "path" - - "golang.org/x/exp/slices" - "gopkg.in/yaml.v2" - - "github.com/pivotal-cf/kiln/pkg/proofing" -) - -func ReadReleaseFromFile(tilePath, releaseName, releaseVersion string, releaseTarball io.Writer) (proofing.Release, error) { - f, err := os.Open(tilePath) - if err != nil { - return proofing.Release{}, err - } - defer closeAndIgnoreError(f) - fi, err := f.Stat() - if err != nil { - return proofing.Release{}, err - } - return ReadReleaseFromZip(f, fi.Size(), releaseName, releaseVersion, releaseTarball) -} - -func ReadReleaseFromZip(ra io.ReaderAt, zipFileSize int64, releaseName, releaseVersion string, releaseTarball io.Writer) (proofing.Release, error) { - zr, err := zip.NewReader(ra, zipFileSize) - if err != nil { - return proofing.Release{}, fmt.Errorf("failed to do open metadata zip reader: %w", err) - } - return ReadReleaseFromFS(zr, releaseName, releaseVersion, releaseTarball) -} - -func ReadReleaseFromFS(dir fs.FS, releaseName, releaseVersion string, releaseTarball io.Writer) (proofing.Release, error) { - metadataBuf, err := ReadMetadataFromFS(dir) - if err != nil { - return proofing.Release{}, err - } - - var metadata struct { - Releases []proofing.Release `yaml:"releases"` - } - err = yaml.Unmarshal(metadataBuf, &metadata) - if err != nil { - return proofing.Release{}, err - } - - releaseIndex := slices.IndexFunc(metadata.Releases, func(release proofing.Release) bool { - return release.Name == releaseName && release.Version == releaseVersion - }) - if releaseIndex == -1 { - return proofing.Release{}, fmt.Errorf("release not found with %s/%s", releaseName, releaseVersion) - } - release := metadata.Releases[releaseIndex] - - f, err := dir.Open(path.Join("releases", release.File)) - if err != nil { - return proofing.Release{}, err - } - defer closeAndIgnoreError(f) - - _, err = io.Copy(releaseTarball, f) - if err != nil { - return proofing.Release{}, fmt.Errorf("failed to copy release tarball: %w", err) - } - - return release, nil -} diff --git a/pkg/tile/releases_test.go b/pkg/tile/releases_test.go deleted file mode 100644 index ee66975a6..000000000 --- a/pkg/tile/releases_test.go +++ /dev/null @@ -1,31 +0,0 @@ -package tile_test - -import ( - "bytes" - "io" - "testing" - - "github.com/pivotal-cf/kiln/pkg/proofing" - - . "github.com/onsi/gomega" - - "github.com/pivotal-cf/kiln/pkg/tile" -) - -func TestReadReleaseFromFile(t *testing.T) { - please := NewWithT(t) - - buf := bytes.NewBuffer(nil) - releaseMetadata, err := tile.ReadReleaseFromFile("testdata/tile-0.1.2.pivotal", "hello-release", "v0.1.4", buf) - please.Expect(err).NotTo(HaveOccurred()) - - please.Expect(releaseMetadata).To(Equal(proofing.Release{ - File: "hello-release-v0.1.4-ubuntu-xenial-621.256.tgz", - Name: "hello-release", - SHA1: "c471ac6371eb8fc24508b14d9a49a44f9a5ef98c", - Version: "v0.1.4", - })) - - _, err = io.ReadAll(buf) - please.Expect(err).NotTo(HaveOccurred()) -} diff --git a/pkg/tile/testdata/bpm-1.1.21-ubuntu-xenial-621.463.tgz b/pkg/tile/testdata/bpm-1.1.21-ubuntu-xenial-621.463.tgz new file mode 100644 index 0000000000000000000000000000000000000000..34266e764784290d6311702f743851646d2e3b65 GIT binary patch literal 1415 zcmV;21$g=&iwFSS@}*<|1MOJLZyQAzUn)fi3keXfiqlF(f{Qovp4n89aFVuZm86fP z&=#Ta&0}Mywv(>cCEWM}xbZh|=KzQ!XHJ}vDj`ltT;S3Z2fnpK+&WLAxCQE;G+OU? zzM1d&o6kCW@B9#aCD3Tk$T+x#$HP4971x@cp^hPPS!j zZS6+?Q%~Y+93KxYIkP*z7)39+tyTit+s%-)z%~2d|B2&l6umz9?p_yiXcvukh^C^4 zKfHPO@)z^JeRgiQ<1`O`byPu~0Ly9e#npWpuG#gpiHZ<-K8&np2kBTk&3 zujgB>aQnn>HnSx zPSXE<8}&Q3Ur)B>p#SShe2?SZp(ST_=UZrF>3$y3vqK4?4hc@xXEQF9;o~e?_RA^nXtRPrbua=}`&{F~aQa`~?5}pFh08Fkd{4p6lO)WNcMGz%ljDCDX(AKT%|I|33*-tJMlt%XXs~ z{Q5SyyRZ>DGnH!GhE|w~?RKjY$M-|tX>7IeHE=DRHck`n0+bQc0kpH$DUUI=7JoHT z!%!w`v^PS&oj2OWNOGMzP!v!aEO7w`Sd{|RL^5hE1+865!APONF#>-On^_poRTjdiTvOG*fUuu;Z#tH(#%j{J!R!zHB#A(2W6NrD&s=w zec>NLZa4hkydo?FVmJX#9Mx8XBn$wlgM!jL1)gQ6Yx2IV*fX4QuDBuIW`qJV6~n8H z3nsIaVQLFyqzjn8HWONDBrhiv)tb62WK?7>9d^hm?ALcxFdjS)k_OC-OlDS4@6oZ= z8sNdDN=oZRrbl;F{NYD~3Mk9r5qEH}EnyhEV1*$zm4@2j1jZ&+9&8${&p_CHsXu~T z-#jj~)5=Sdf)~~>pQdP<6_%w`E0bj@u_Uwb&&=E0vWHWhNonvYXVzHBKy#uj9*O=; zk(!jSDf2kT<*hAOQ=ryT9koMCQAO01&Ha)OL!4Hmhk{&7AEIkr{)F+OrG zOM}zMEktle4QNjc0qM&W(%NQ@8OiqL;s|nmg-fqv+>DTnnbZ@RVu`9?wL$jM0)nAL zIGr6wpbm>$U~ZN>5d|Pq6m}f<5lo~&0um%Q%nU0$f?Qu=1!Wxx#drXW3zg1;4yhEF zR-9qpISF8_FE7GYqgby)r;cWNW4JUGi+DucusL?NLGUQ18= VTAyHo2_`ree*s%KR(}8>003E3u0j9+ literal 0 HcmV?d00001 diff --git a/pkg/tile/testdata/bpm-1.1.21.tgz b/pkg/tile/testdata/bpm-1.1.21.tgz new file mode 100644 index 0000000000000000000000000000000000000000..40095d7ee7ee950dc0b3201fc67e8125d5f62824 GIT binary patch literal 5877 zcmV0(+m28ou~`uJoRVN2<(*dwz_EtSi5b!Ag! z7q)Avdk|_~M7+q1s>q1!SiH;u^$!3EiOc)~&LaU57bGrl;3t5P5I4keq&acm``!}q za`93_*=EQ@C}3Tqv!FXVL9T6!+{giaa_~(P1pB` zVOqB1c8GE7n8B#aiWY#%xXvn8gyYNZgWKZx3OIrk(j0$L#z(*VtDSqD&T|@)!(;L# zkpr)FehoereEthQaK852Hv_qIa&jbo;xqmZK7TfM%RPDhX{Ym>VLs{6=`>}%2@O;6 z{r|$}(@y7i+V8%pX+g6p$yn#3&d>h!_udTudiQ_6{rv}@e)Jc;pMBK%@7MqM?_d7( z(ck>lzx>mW|Ms8%^7Nz5Z@K^WhxOT`pZvprWXJ#c2Y>$?i+Fx>-!S^-L(idZYEu8nNPjSQiD$swgSm^%~dNzh}C0_V1aN-y!Gk8j)q=1Gj(M zAd@PYu+L1d-**ST?K{1J;~2ivH~e+qAkT)6caCM96JO>y0{?W-_Ahw<6tKi;!0#!+$n z!-GA~*?E099zA)z>sxSrN((!9_2OV>I^FyH?2F__=U) zQbtSGd;a8h)<75UIG4-c@=*S^<5(7GfC=(vbkBS1kHE9Mf#XO8AndC0l=;2jzqHZPG#{q=DHVm@FFDR?rVzi~6?V1t#c%>kd4h zdQLE~BDiL|Fegp`YB4R6ta__?<(QfeNZ2<$->3e-?#HojgGSk|X#}2W1-20cX3)27 z-#4QM(TbJTHY>nMMLNP}7{&t@`qc3a$F|Hq^&_KiP&e{?sE++04z0dx4dxMki+KX! zI35^g!1|7BS^Ys|xC4XQ9t-@wWt+Z3S>H6A(2r*kE?EJn>IjEMA1o;L5t89i3bnjL zLmS{YmNTFRvqIbMTm5;2-(sFX*rT!IdyZ$>jDlQDH;kyy2CicasBO_;5W1B1gJ^w9 z!#5Na;wXq576zdm_YKRnyql1z2wI@NAqyVYeXePE8` z#oizW)%C)FMo~Yac3_wT>coNN0~`aFkIi_VOXN@f^g0_fEf#>`n-pv&ilU(JIzEd* zNi7>p!!{!`_AKUw3r^$a^8|@jpZTC1;Qgr4r)Fq)uHjk{vd0Te+j2r6oAraYku=w1 zjTk%f1H%GcV}a8*f`QuyHx)Y6Fa}-(X3l~rrcSUx%v;P8#MqJP(I^OA@bm$QhdMxw z9Y!Do3&Rez`Y|00%w+;elaOU4d!Qq31Q88E@-Cw=F$f&iH<%ZJ+SuTIUDJ&00IbBE zNBk}33B>)#1m6ut!TIGLtGH%lU!O8&7c|or3c=X9-AhrI_xtg^a@8{6_Key!vuCssJnzw(~ zbL>_B=PrgdShoM?LSE_j*Fi|KtrN#79hIMrlL(^kdf&aOY4jw45M2zjIR9+8yE77> z$2vZt;ynJ zO|HBqE0i@^g{%>IeDqc%uf}S8FymLm;S-Gi`<+Yc|J7KH)%YbIYv0>D-h13>3WCKO zI_=AR*Che>M6>WyZ7z|=NAmcsIIa?b)mV+ySdF_L`25ea;qLyy@&2u?aijOYY|F7N z*D-Cr|L0h%=YQ^Itlt0npojka&u#gE8@>NEWB)Gvw|f5PF2?HpuMd0lZq4f3akc$h zw&%O^@!ztXRs6q;L9QD+QyPvLc_tpTU%%qcABYF=iPbZ@y4#4b@Jr*ZfQUP*hZ(U-uAt~CxhxyZ#Oc>2b1(bpo zOiDtth=h3-iCHAh3sRS?OA0nE@~95+a#w=Fd!wYRiX^DMcG8$JTKg(D_04121R2PKS)i^JbAMy1h zoMkhrF|7zJIub5<#BY*(&=6oFnv#7EdI5<#LjpPWjL?unQCI*Q;9dzPhZ`h<2`k0Y zz|gA5(=MR}Qzt1$x{K7{)fyl5B>0kHo=HgZMsk)^V*y7j*dtH!g5xo*i)juT({i;D zxRTL^gtEa&DamHCC8p+QtmuOH3Xl>ak!0fME~#=7QV=@cC!vV1I0p(cp&1=96dtZy z*5Ozp)+J|S#>ofi^K~hQt#jrqL2Uvkn+agT#Z!)xDME^q7`QnFXM~_PUE}*(e7PLh zBN(p$)fIRpz!ziyVk%gvAOgsMWx#|m0a4CC*YIpb{#9OYkWHA2KNTBWy42x+>RL7N<;+ko+M?-6`t#vFaj=?1ywtS)j}{qFt5qHrcDbLv!a0M{M(pw z{0%NK$)f~Fqui>LfRijtYt9NVLXzbbNs~!}tAiZNJg&}Ay-L0y2qgmUE8F9MBp7i+ zSJ{7@jOv1a4`NA~<~|OC*PsfEsMG91Tmx~`DYuUpG9CC5-(D29rE+ zqK#ir-VN9QH#hE0a0+ftI9nkj#n{3*q_CABHh}xOmD4GNjy?*8p5&IS(ZD5|ZG7LOh@)3NPcP7~vYI{h&RdcBO3)O}eF}@^ zDK`q3mW+}NR#}w!qCZxCDxNX_E}3VaRUO`)JbO+mhJGA68G z=>^z9_J%Vq0Bu1%!PgqMl+Y8*?qVA9Ako!gWW&@2q>wu-k6WqlqAQm%eyPOgZJ;q( zZM}wp(%@7qZSX)~Gcw^i9LY>XLCOVh_$>JTGUU6OQB>&lb67f6Zo8}l@h(5YQ+Ws1 zE{-`zPnrT>i2Lz{v_eUlhr27Ig`TLOSLVy3z6T7L83QXWPhM^o?a4+%(}sj4;(gKh0E--)aTlc!(3I=ZS%LF1o_y4qY0$F4aVIRvQPvZ%TAq?QJZY@LYb~kgY86+LT9UAo|D2+@fR*$OH`Z z2~tMJJvkt)uhSY~$-b#Ue^OjF%z@t`Tw}tknV)b(R*!s+X%#NJ+mNp^D{@?m;3{=> zX)&XjneLStL`kACh@cAroOu?<^8!c?flA2mrmO5o$|*MJ5({-KMAcjW6cO^1_Ns!a4UXLO`}ApcfRK?k|CKHeni@R%l>Q za#Sis0t8D@5N(mEpjDF|r0W1|Oivll@)Sb6j?Uv4^E?OwECu%~{soVc7nKl9;|FA- zEVDxHW)x+}0wE){DmERl+{`l&I_EO_E{R&0(ggS|?$w9`E^;6`cN@Q%f%TRpEfQ{> zae==vKvpy?QL#@q{LOL;%HTX>G9rTegN&rf>iM+!35p<5;mT+W=!+z87CE`Z8Hz&1 zx*i$EDF3DwD#25sPB%iSl951xjwpW3ot!M(H`{>K7{IbwQesK=L{(2Lfy z&3hs6gNe#*X8h3=SsoV&rj4*z4Ni{h5oR=S%$tZjTQ-Xjeu*dRwxtkfNUK^C#)OpP zJcXJ_#CPSp9;i6GNw);0HE7xh@kR7Ry#ZoPfJAg!dg|L$hd34pr93{&R}v3-7*%Tq z+M1$q)27l`M`8UgnmPrl5R?x|hI%5Z$5LA!U0kEm2vhv3t4I)zaAsEywUrB2fq`{Z z-mI1IygC4k=84l5ZWe46qKg*RM#rwy?k>8;h+*E;)shLWqE%~dk~YzTSc1>IOU2P< zZo+#i7#z7M=Ls!D86*?gDJ-t2+Q20!Sq#;)OpCVAX*Kefg&&G~dQy-fjd+dODji$OR&+`f`@9+$>D0Jq5QK0N zx;Npg24*>jm-3Y>8^FNd#x-ldmQT5E;GD8yf$BhjP^$ClSEhi0^@yb_0px-*|q zGTp9c8&D*PTR(##bJRw_MfiEqUF0%Vxt`YLlC{ASF2!?}!V?In0EMssU=eL2kr$0@ zGVISm!HkIoqfmsNj71fO{%euVn!I`PAWG?`$pQ`p|XU-}T$6P32kXpC|!qW)9jocC#*!K#S? zY*=bcyjuk|lgI;#dS3qoV=mjbSjwWds^DoWZ`O+hV6O3{i2{L0I&_q=C6{27`8-jXdN0Y=*^%Ht*2bX&8Dd9iqLNhzXt=NePu@Nj9Zo7W<+uv;|~g`2D!d&xYN zMm?Ho%QThBTqQ6g5SJG_awkC4s%;in_Q=Z&qG-v5#?E1(Fv0SdL)11%n*PScd={xS zv$QtWrLC(r)5jI(8#yA?3-s>u+mvQ9&EjZk3L`*>)HPDOk7E8oUg4x>_lC!pAQwd$ zn(c^}cNj)EYGn=Kpkxsf8$oCWnn>hABD)X`Qs81!5{;myqP8*U1p8)9MuS~1 zR-9r_U!DR^QisLON@*3wN>kc0wP4@WiQGNHfL?-3Fr;&lLg3FQxIK;70GA=}2!TK; zil*qmPVGW}R#}shn~VlaLV)0u-y?fT$xA2Pw2jFtiob0X_b;UpG^hp_qJZU$U=uwqLfWZX&MOG?*_@^}DfsIV0RH>}!F`-`F`O!{ZI|c;|R{teE?1 zc=Gh{^%9;7>o*a1Gr?r7Okl5oEgX>HQh zf_R^lDnE4rMJ{I*FNlgo7Yoch8J;}b?*i8kwuc8#j)n)H??2x^IO&q-`$xM^0n44o z!)L>jueb_58J-;MAB)Eab|j1!J4Ya}m(O;N$cvXpFAk6QMYI*Wg(>bV0RB^0G~v4r zd}l^fg|q4ck}L9Qkzjhx364R#@D{Frt;f~+rJ~zdmXH%6xyoH9CHL%Q9wtqhES$RB zXXV{keWP`;m=(I$@4>lZDNcHp&>%_q=J^mKFM;$Yt2iD423$&cvlDQHN?U8SsGTfO zph|BUWNefskbQ-0tJ~~$cV}9;P3PxYecu#`0`~ONB;W}hM{b1uh-TkHEm`3c2qoVg zUv3}5d(MOpY|1E+r3qhHb_BR+=>&get=_}O+3Jyi_ThkX%5ZO8+kFOug2YyAC13(0 zdb+qFCxI#tjXgKO8{5@|*fYl{-o$F$HJ&eYIXCOZ$JF9Vl1X7|epT-nY+ku1uCPL~ z(_AR*D9@v_B-ML|Zy+e=(<#L+A?5@%A|BHutqT#2Xd2g9o80gqxa3I?+yy}8)%hV7 zW+f;N>LDiR^NlzOqiLqo=rrM*q_KQ_11vx?K|S0c!3zr*^vF(#F#)-tJTI=i(*|nI zC|->*b)PlY`OU&Bx7$<}8jkZ^bU}Hib7r%h_go=wiy8MP;OaPrGz*y^Vk+98()(R- zy)dKXOy~z41Q697@FrMaTSP6+zvSAqK zrv|vCk3Z3prP^*tlXJ^$5#Gd=m(h{7Zj|H8Go5x9rS<4-r$|!+*%QW^DT#%DMuQjj z&Uq6zyop#0<%*aAnQ^qFbxw;3_e3hWZn)T*b6pheZkg;HgHML49E(-aMC~s2je`rB zY_tSjAO~8WHp%>%rj1(K*x(`*c>iDzzlnjn z-?FfXw3h1ZnVry$z+R~mrc#SQPciVg-Raq zZ8SQwm#4~VTJaqFn)guT8&cbV==%CidUls}Bji))>)H<6;sek441s>b(uUmsvlXYB zaJ}_o#%2~*kNxrfMx2BM|5iv1^)wmfP# Date: Wed, 5 Jul 2023 16:33:08 -0700 Subject: [PATCH 2/7] refactor: use BOSH release manifest reader - refator: add test coverage for TestReadBOSHReleaseManifestsFromTarballs - feat: add Stemcell method on BOSHReleaseManifest - fix linter errors - refactor: use new stemcell utility --- internal/builder/release_manifest_reader.go | 73 +++---------------- .../builder/release_manifest_reader_test.go | 6 +- pkg/tile/bosh_release.go | 8 ++ pkg/tile/bosh_release_test.go | 11 +++ 4 files changed, 31 insertions(+), 67 deletions(-) diff --git a/internal/builder/release_manifest_reader.go b/internal/builder/release_manifest_reader.go index bb62e5b80..de6a4111f 100644 --- a/internal/builder/release_manifest_reader.go +++ b/internal/builder/release_manifest_reader.go @@ -1,18 +1,14 @@ package builder import ( - "archive/tar" - "compress/gzip" "crypto/sha1" + "encoding/hex" "fmt" - "io" - "path/filepath" - "strings" - "github.com/go-git/go-billy/v5" "github.com/go-git/go-billy/v5/osfs" - - "gopkg.in/yaml.v2" + "github.com/pivotal-cf/kiln/pkg/tile" + "io" + "path/filepath" ) type ReleaseManifest struct { @@ -24,17 +20,6 @@ type ReleaseManifest struct { StemcellVersion string `yaml:"-"` } -// inputReleaseManifest is a subset of release.MF -type inputReleaseManifest struct { - Name string `yaml:"name"` - Version string `yaml:"version"` - CompiledPackages []compiledPackage `yaml:"compiled_packages"` -} - -type compiledPackage struct { - Stemcell string `yaml:"stemcell"` -} - type ReleaseManifestReader struct { fs billy.Filesystem } @@ -54,54 +39,14 @@ func (r ReleaseManifestReader) Read(releaseTarball string) (Part, error) { } defer closeAndIgnoreError(file) - // TODO: use component.ReadReleaseManifest - // we could not do it yet due to a circular package reference where we import builder in the local release source - - gr, err := gzip.NewReader(file) - if err != nil { - return Part{}, err - } - defer closeAndIgnoreError(gr) - - tr := tar.NewReader(gr) - - var header *tar.Header - for { - header, err = tr.Next() - if err != nil { - if err == io.EOF { - return Part{}, fmt.Errorf("could not find release.MF in %q", releaseTarball) - } - - return Part{}, fmt.Errorf("error while reading %q: %s", releaseTarball, err) - } - - if filepath.Base(header.Name) == "release.MF" { - break - } - } - - var inputReleaseManifest inputReleaseManifest - inputReleaseManifestContents, err := io.ReadAll(tr) - if err != nil { - return Part{}, err // NOTE: cannot replicate this error scenario in a test - } - - err = yaml.Unmarshal(inputReleaseManifestContents, &inputReleaseManifest) + inputReleaseManifest, err := tile.ReadProductTemplatePartFromBOSHReleaseTarball(file) if err != nil { return Part{}, err } - var stemcellOS, stemcellVersion string - compiledPackages := inputReleaseManifest.CompiledPackages - if len(compiledPackages) > 0 { - inputStemcell := inputReleaseManifest.CompiledPackages[0].Stemcell - stemcellParts := strings.Split(inputStemcell, "/") - if len(stemcellParts) != 2 { - return Part{}, fmt.Errorf("Invalid format for compiled package stemcell inside release.MF (expected 'os/version'): %s", inputStemcell) - } - stemcellOS = stemcellParts[0] - stemcellVersion = stemcellParts[1] + stemcellOS, stemcellVersion, stemcellOK := inputReleaseManifest.Stemcell() + if !stemcellOK && len(inputReleaseManifest.CompiledPackages) > 0 { + return Part{}, fmt.Errorf("%s/%s has invalid stemcell: %q", inputReleaseManifest.Name, inputReleaseManifest.Version, inputReleaseManifest.CompiledPackages[0].Stemcell) } outputReleaseManifest := ReleaseManifest{ @@ -123,7 +68,7 @@ func (r ReleaseManifestReader) Read(releaseTarball string) (Part, error) { return Part{}, err // NOTE: cannot replicate this error scenario in a test } - outputReleaseManifest.SHA1 = fmt.Sprintf("%x", hash.Sum(nil)) + outputReleaseManifest.SHA1 = hex.EncodeToString(hash.Sum(nil)) return Part{ File: releaseTarball, diff --git a/internal/builder/release_manifest_reader_test.go b/internal/builder/release_manifest_reader_test.go index e6fd9b5fb..5edf97793 100644 --- a/internal/builder/release_manifest_reader_test.go +++ b/internal/builder/release_manifest_reader_test.go @@ -183,7 +183,7 @@ version: 1.2.3 Expect(gw.Close()).NotTo(HaveOccurred()) _, err = reader.Read(tarball.Name()) - Expect(err).To(MatchError(fmt.Sprintf("could not find release.MF in %q", tarball.Name()))) + Expect(err).To(MatchError("failed to find release.MF in tarball")) }) }) @@ -220,7 +220,7 @@ version: 1.2.3 Expect(err).NotTo(HaveOccurred()) _, err = reader.Read(tarball.Name()) - Expect(err).To(MatchError(fmt.Sprintf("could not find release.MF in %q", tarball.Name()))) + Expect(err).To(MatchError("failed to find release.MF in tarball")) }) }) @@ -242,7 +242,7 @@ version: 1.2.3 Expect(err).NotTo(HaveOccurred()) _, err = reader.Read(tarball.Name()) - Expect(err).To(MatchError(fmt.Sprintf("error while reading %q: unexpected EOF", tarball.Name()))) + Expect(err).To(MatchError("unexpected EOF")) }) }) diff --git a/pkg/tile/bosh_release.go b/pkg/tile/bosh_release.go index 9002f984b..67dafd0c2 100644 --- a/pkg/tile/bosh_release.go +++ b/pkg/tile/bosh_release.go @@ -12,6 +12,7 @@ import ( "io/fs" "os" "path" + "strings" "golang.org/x/exp/slices" "gopkg.in/yaml.v2" @@ -104,6 +105,13 @@ type BOSHReleaseManifest struct { Packages []BOSHReleasePackage `yaml:"packages"` } +func (mf BOSHReleaseManifest) Stemcell() (string, string, bool) { + if len(mf.CompiledPackages) == 0 { + return "", "", false + } + return strings.Cut(mf.CompiledPackages[0].Stemcell, "/") +} + type BOSHReleaseTarball struct { Manifest BOSHReleaseManifest diff --git a/pkg/tile/bosh_release_test.go b/pkg/tile/bosh_release_test.go index c82c0d692..6f779399c 100644 --- a/pkg/tile/bosh_release_test.go +++ b/pkg/tile/bosh_release_test.go @@ -2,6 +2,7 @@ package tile_test import ( "bytes" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "io" "os" @@ -33,6 +34,16 @@ func TestReadReleaseFromFile(t *testing.T) { please.Expect(err).NotTo(HaveOccurred()) } +func TestReadBOSHReleaseManifestsFromTarballs(t *testing.T) { + boshReleases, err := tile.ReadBOSHReleaseManifestsFromTarballs(os.DirFS("testdata"), "bpm-1.1.21-ubuntu-xenial-621.463.tgz", "bpm-1.1.21.tgz") + require.NoError(t, err) + require.Len(t, boshReleases, 2) + assert.Equal(t, "be5b1710f33128f6c864eae1d97effddb94dd3ac", boshReleases[0].SHA1) + assert.Equal(t, "519b78f2f3333a7b9c000bbef325e12a2f36996d", boshReleases[1].SHA1) + assert.Equal(t, "bpm-1.1.21-ubuntu-xenial-621.463.tgz", boshReleases[0].FilePath) + assert.Equal(t, "bpm-1.1.21.tgz", boshReleases[1].FilePath) +} + func TestReadProductTemplatePartFromBOSHReleaseTarball(t *testing.T) { t.Run("when the release is compiled", func(t *testing.T) { f, err := os.Open(filepath.Join("testdata", "bpm-1.1.21-ubuntu-xenial-621.463.tgz")) From 42e3b775b355f82dd52c50ec47c6cda6753022c9 Mon Sep 17 00:00:00 2001 From: Christopher Hunter Date: Thu, 6 Jul 2023 15:23:47 -0700 Subject: [PATCH 3/7] gofumpt --- .../acceptance/workflows/acceptance_test.go | 3 ++- internal/builder/release_manifest_reader.go | 5 ++-- internal/commands/test_tile_test.go | 1 - pkg/tile/bosh_release_test.go | 23 ++++++++++++------- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/internal/acceptance/workflows/acceptance_test.go b/internal/acceptance/workflows/acceptance_test.go index 5021702a9..c87e1d658 100644 --- a/internal/acceptance/workflows/acceptance_test.go +++ b/internal/acceptance/workflows/acceptance_test.go @@ -13,13 +13,14 @@ package workflows import ( "context" - "golang.org/x/exp/slices" "os" "os/exec" "path/filepath" "strings" "testing" + "golang.org/x/exp/slices" + "github.com/cucumber/godog" "github.com/pivotal-cf/kiln/internal/acceptance/workflows/scenario" diff --git a/internal/builder/release_manifest_reader.go b/internal/builder/release_manifest_reader.go index de6a4111f..1cd4aca73 100644 --- a/internal/builder/release_manifest_reader.go +++ b/internal/builder/release_manifest_reader.go @@ -4,11 +4,12 @@ import ( "crypto/sha1" "encoding/hex" "fmt" + "io" + "path/filepath" + "github.com/go-git/go-billy/v5" "github.com/go-git/go-billy/v5/osfs" "github.com/pivotal-cf/kiln/pkg/tile" - "io" - "path/filepath" ) type ReleaseManifest struct { diff --git a/internal/commands/test_tile_test.go b/internal/commands/test_tile_test.go index 73aa5c3b7..f6fc0075c 100644 --- a/internal/commands/test_tile_test.go +++ b/internal/commands/test_tile_test.go @@ -345,7 +345,6 @@ var _ = Describe("kiln test docker", func() { Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("Docker daemon is not running")) }) - }) }) diff --git a/pkg/tile/bosh_release_test.go b/pkg/tile/bosh_release_test.go index 6f779399c..1dfdf4637 100644 --- a/pkg/tile/bosh_release_test.go +++ b/pkg/tile/bosh_release_test.go @@ -2,13 +2,14 @@ package tile_test import ( "bytes" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "io" "os" "path/filepath" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/pivotal-cf/kiln/pkg/proofing" . "github.com/onsi/gomega" @@ -65,35 +66,40 @@ func TestReadProductTemplatePartFromBOSHReleaseTarball(t *testing.T) { Fingerprint: "be375c78c703cea04667ea7cbbc6d024bb391182", SHA1: "b67ab0ceb0cab69a170521bb1a77c91a8546ac21", Dependencies: []string{"golang-1-linux", "bpm-runc", "tini"}, - Stemcell: "ubuntu-xenial/621.463"}, + Stemcell: "ubuntu-xenial/621.463", + }, { Name: "test-server", Version: "12eba471a2c3dddb8547ef03c23a3231d1f62e6c", Fingerprint: "12eba471a2c3dddb8547ef03c23a3231d1f62e6c", SHA1: "7ab0c2066c63eb5c5dd2c06d35b73376f4ad9a81", Dependencies: []string{"golang-1-linux"}, - Stemcell: "ubuntu-xenial/621.463"}, + Stemcell: "ubuntu-xenial/621.463", + }, { Name: "bpm-runc", Version: "464c6e6611f814bd12016156bf3e682486f34672", Fingerprint: "464c6e6611f814bd12016156bf3e682486f34672", SHA1: "bacd602ee0830a30c17b7a502aa0021a6739a3ff", Dependencies: []string{"golang-1-linux"}, - Stemcell: "ubuntu-xenial/621.463"}, + Stemcell: "ubuntu-xenial/621.463", + }, { Name: "golang-1-linux", Version: "2336380dbf01a44020813425f92be34685ce118bf4767406c461771cfef14fc9", Fingerprint: "2336380dbf01a44020813425f92be34685ce118bf4767406c461771cfef14fc9", SHA1: "e8dad3e51eeb5f5fb41dd56bbb8a3ec9655bd4f7", Dependencies: []string{}, - Stemcell: "ubuntu-xenial/621.463"}, + Stemcell: "ubuntu-xenial/621.463", + }, { Name: "tini", Version: "3d7b02f3eeb480b9581bec4a0096dab9ebdfa4bc", Fingerprint: "3d7b02f3eeb480b9581bec4a0096dab9ebdfa4bc", SHA1: "347c76d509ad4b82d99bbbb4b291768ff90b0fba", Dependencies: []string{}, - Stemcell: "ubuntu-xenial/621.463"}, + Stemcell: "ubuntu-xenial/621.463", + }, }, }, result) }) @@ -119,7 +125,8 @@ func TestReadProductTemplatePartFromBOSHReleaseTarball(t *testing.T) { Version: "be375c78c703cea04667ea7cbbc6d024bb391182", Fingerprint: "be375c78c703cea04667ea7cbbc6d024bb391182", SHA1: "6ae70da9768bd7333b883463e089c65bea44c685", - Dependencies: []string{"golang-1-linux", "bpm-runc", "tini"}}, + Dependencies: []string{"golang-1-linux", "bpm-runc", "tini"}, + }, { Name: "bpm-runc", Version: "464c6e6611f814bd12016156bf3e682486f34672", From 3adfb373b19bcc37fcaa362d4ec625ecbb92ef5d Mon Sep 17 00:00:00 2001 From: Christopher Hunter Date: Fri, 14 Jul 2023 17:24:57 -0400 Subject: [PATCH 4/7] refactor: reduce template spec in Kilnfiles this reduces number of templating functions in the kilnfile. interpolation in the Kilnfile is a mistake and should be factored out this is to remove circular dependency when we move bosh release tarball functions to cargo --- pkg/cargo/files.go | 47 ++++++++++++++++++++++++++++++++++------- pkg/cargo/files_test.go | 2 +- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/pkg/cargo/files.go b/pkg/cargo/files.go index 014edd1fe..97473f2ab 100644 --- a/pkg/cargo/files.go +++ b/pkg/cargo/files.go @@ -1,15 +1,17 @@ package cargo import ( + "bytes" + "errors" "fmt" "io" "os" "path/filepath" + "strconv" "strings" + "text/template" - "gopkg.in/yaml.v2" - - "github.com/pivotal-cf/kiln/internal/builder" + "gopkg.in/yaml.v3" ) func InterpolateAndParseKilnfile(in io.Reader, templateVariables map[string]interface{}) (Kilnfile, error) { @@ -18,16 +20,44 @@ func InterpolateAndParseKilnfile(in io.Reader, templateVariables map[string]inte return Kilnfile{}, fmt.Errorf("unable to read Kilnfile: %w", err) } - interpolator := builder.NewInterpolator() - interpolatedMetadata, err := interpolator.Interpolate(builder.InterpolateInput{ - Variables: templateVariables, - }, "Kilnfile", kilnfileYAML) + kilnfileTemplate, err := template.New("Kilnfile"). + Funcs(template.FuncMap{ + "variable": variableTemplateFunction(templateVariables), + }). + Delims("$(", ")"). + Option("missingkey=error"). + Parse(string(kilnfileYAML)) if err != nil { return Kilnfile{}, err } + var buf bytes.Buffer + if err := kilnfileTemplate.Execute(&buf, struct{}{}); err != nil { + return Kilnfile{}, err + } + var kilnfile Kilnfile - return kilnfile, yaml.Unmarshal(interpolatedMetadata, &kilnfile) + return kilnfile, yaml.Unmarshal(buf.Bytes(), &kilnfile) +} + +func variableTemplateFunction(templateVariables map[string]any) func(name string) (string, error) { + return func(name string) (string, error) { + if templateVariables == nil { + return "", errors.New("--variable or --variables-file must be specified") + } + val, ok := templateVariables[name] + if !ok { + return "", fmt.Errorf("could not find variable with key %q", name) + } + switch value := val.(type) { + case string: + return value, nil + case int: + return strconv.Itoa(value), nil + default: + return "", fmt.Errorf("the variables function used to interpolate variables in the Kilnfile only supports int and string values (%q has type %s)", name, value) + } + } } func ResolveKilnfilePath(path string) (string, error) { @@ -99,6 +129,7 @@ func WriteKilnfile(path string, kf Kilnfile) error { } defer closeAndIgnoreError(f) e := yaml.NewEncoder(f) + e.SetIndent(2) defer closeAndIgnoreError(e) return e.Encode(kf) } diff --git a/pkg/cargo/files_test.go b/pkg/cargo/files_test.go index 3e87281c6..1d323d6b7 100644 --- a/pkg/cargo/files_test.go +++ b/pkg/cargo/files_test.go @@ -140,7 +140,7 @@ func TestInterpolateAndParseKilnfile_interpolation_variable_not_found(t *testing strings.NewReader(validKilnfile), variables, ) - please.Expect(err).To(MatchError(ContainSubstring(`could not find variable with key 'region'`))) + please.Expect(err).To(MatchError(ContainSubstring(`could not find variable with key "region"`))) } const validKilnfile = `--- From b78f5e029e0a84f61ab6b181ba34f73d5de82279 Mon Sep 17 00:00:00 2001 From: Christopher Hunter Date: Fri, 7 Jul 2023 11:26:49 -0700 Subject: [PATCH 5/7] refactor: use hex instead of fmt %x this is easier to read --- internal/builder/release_manifest_reader_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/builder/release_manifest_reader_test.go b/internal/builder/release_manifest_reader_test.go index 5edf97793..48c8193d9 100644 --- a/internal/builder/release_manifest_reader_test.go +++ b/internal/builder/release_manifest_reader_test.go @@ -6,7 +6,7 @@ import ( "bytes" "compress/gzip" "crypto/sha1" - "fmt" + "encoding/hex" "io" "os" "path/filepath" @@ -59,7 +59,7 @@ func createReleaseTarball(releaseMetadata string) (*os.File, string) { _, err = io.Copy(hash, file) Expect(err).NotTo(HaveOccurred()) - releaseSHA1 := fmt.Sprintf("%x", hash.Sum(nil)) + releaseSHA1 := hex.EncodeToString(hash.Sum(nil)) err = file.Close() Expect(err).NotTo(HaveOccurred()) From 3b90683614069335ff3816551d7131558bd386a9 Mon Sep 17 00:00:00 2001 From: Christopher Hunter Date: Fri, 7 Jul 2023 11:30:20 -0700 Subject: [PATCH 6/7] refactor: move utilities to cargo --- .../workflows/scenario/step_funcs_tile.go | 4 +++- internal/builder/release_manifest_reader.go | 5 ++-- pkg/{tile => cargo}/bosh_release.go | 6 +++-- pkg/{tile => cargo}/bosh_release_test.go | 22 +++++++++--------- .../bpm-1.1.21-ubuntu-xenial-621.463.tgz | Bin pkg/{tile => cargo}/testdata/bpm-1.1.21.tgz | Bin pkg/cargo/testdata/tile-0.1.2.pivotal | Bin 0 -> 86227 bytes 7 files changed, 21 insertions(+), 16 deletions(-) rename pkg/{tile => cargo}/bosh_release.go (98%) rename pkg/{tile => cargo}/bosh_release_test.go (88%) rename pkg/{tile => cargo}/testdata/bpm-1.1.21-ubuntu-xenial-621.463.tgz (100%) rename pkg/{tile => cargo}/testdata/bpm-1.1.21.tgz (100%) create mode 100644 pkg/cargo/testdata/tile-0.1.2.pivotal diff --git a/internal/acceptance/workflows/scenario/step_funcs_tile.go b/internal/acceptance/workflows/scenario/step_funcs_tile.go index 00152ffd6..2e758d67a 100644 --- a/internal/acceptance/workflows/scenario/step_funcs_tile.go +++ b/internal/acceptance/workflows/scenario/step_funcs_tile.go @@ -11,6 +11,8 @@ import ( "os" "strings" + "github.com/pivotal-cf/kiln/pkg/cargo" + "github.com/cucumber/godog" "gopkg.in/yaml.v2" @@ -78,7 +80,7 @@ func theTileOnlyContainsCompiledReleases(ctx context.Context) error { for _, release := range metadata.Releases { helloReleaseTarball := bytes.NewBuffer(nil) - _, err := tile.ReadBOSHReleaseFromFile(tilePath, release.Name, release.Version, helloReleaseTarball) + _, err := cargo.ReadBOSHReleaseFromFile(tilePath, release.Name, release.Version, helloReleaseTarball) if err != nil { return err } diff --git a/internal/builder/release_manifest_reader.go b/internal/builder/release_manifest_reader.go index 1cd4aca73..3c212d74b 100644 --- a/internal/builder/release_manifest_reader.go +++ b/internal/builder/release_manifest_reader.go @@ -7,9 +7,10 @@ import ( "io" "path/filepath" + "github.com/pivotal-cf/kiln/pkg/cargo" + "github.com/go-git/go-billy/v5" "github.com/go-git/go-billy/v5/osfs" - "github.com/pivotal-cf/kiln/pkg/tile" ) type ReleaseManifest struct { @@ -40,7 +41,7 @@ func (r ReleaseManifestReader) Read(releaseTarball string) (Part, error) { } defer closeAndIgnoreError(file) - inputReleaseManifest, err := tile.ReadProductTemplatePartFromBOSHReleaseTarball(file) + inputReleaseManifest, err := cargo.ReadProductTemplatePartFromBOSHReleaseTarball(file) if err != nil { return Part{}, err } diff --git a/pkg/tile/bosh_release.go b/pkg/cargo/bosh_release.go similarity index 98% rename from pkg/tile/bosh_release.go rename to pkg/cargo/bosh_release.go index 67dafd0c2..f42eedfb1 100644 --- a/pkg/tile/bosh_release.go +++ b/pkg/cargo/bosh_release.go @@ -1,4 +1,4 @@ -package tile +package cargo import ( "archive/tar" @@ -14,6 +14,8 @@ import ( "path" "strings" + "github.com/pivotal-cf/kiln/pkg/tile" + "golang.org/x/exp/slices" "gopkg.in/yaml.v2" @@ -42,7 +44,7 @@ func ReadBOSHReleaseFromZip(ra io.ReaderAt, zipFileSize int64, releaseName, rele } func ReadBOSHReleaseFromFS(dir fs.FS, releaseName, releaseVersion string, releaseTarball io.Writer) (proofing.Release, error) { - metadataBuf, err := ReadMetadataFromFS(dir) + metadataBuf, err := tile.ReadMetadataFromFS(dir) if err != nil { return proofing.Release{}, err } diff --git a/pkg/tile/bosh_release_test.go b/pkg/cargo/bosh_release_test.go similarity index 88% rename from pkg/tile/bosh_release_test.go rename to pkg/cargo/bosh_release_test.go index 1dfdf4637..a88b44051 100644 --- a/pkg/tile/bosh_release_test.go +++ b/pkg/cargo/bosh_release_test.go @@ -1,4 +1,4 @@ -package tile_test +package cargo_test import ( "bytes" @@ -7,21 +7,21 @@ import ( "path/filepath" "testing" + "github.com/pivotal-cf/kiln/pkg/cargo" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/pivotal-cf/kiln/pkg/proofing" . "github.com/onsi/gomega" - - "github.com/pivotal-cf/kiln/pkg/tile" ) func TestReadReleaseFromFile(t *testing.T) { please := NewWithT(t) buf := bytes.NewBuffer(nil) - releaseMetadata, err := tile.ReadBOSHReleaseFromFile(filepath.Join("testdata", "tile-0.1.2.pivotal"), "hello-release", "v0.1.4", buf) + releaseMetadata, err := cargo.ReadBOSHReleaseFromFile(filepath.Join("testdata", "tile-0.1.2.pivotal"), "hello-release", "v0.1.4", buf) please.Expect(err).NotTo(HaveOccurred()) please.Expect(releaseMetadata).To(Equal(proofing.Release{ @@ -36,7 +36,7 @@ func TestReadReleaseFromFile(t *testing.T) { } func TestReadBOSHReleaseManifestsFromTarballs(t *testing.T) { - boshReleases, err := tile.ReadBOSHReleaseManifestsFromTarballs(os.DirFS("testdata"), "bpm-1.1.21-ubuntu-xenial-621.463.tgz", "bpm-1.1.21.tgz") + boshReleases, err := cargo.ReadBOSHReleaseManifestsFromTarballs(os.DirFS("testdata"), "bpm-1.1.21-ubuntu-xenial-621.463.tgz", "bpm-1.1.21.tgz") require.NoError(t, err) require.Len(t, boshReleases, 2) assert.Equal(t, "be5b1710f33128f6c864eae1d97effddb94dd3ac", boshReleases[0].SHA1) @@ -53,13 +53,13 @@ func TestReadProductTemplatePartFromBOSHReleaseTarball(t *testing.T) { closeAndIgnoreError(f) }) - result, err := tile.ReadProductTemplatePartFromBOSHReleaseTarball(f) + result, err := cargo.ReadProductTemplatePartFromBOSHReleaseTarball(f) require.NoError(t, err) - require.Equal(t, tile.BOSHReleaseManifest{ + require.Equal(t, cargo.BOSHReleaseManifest{ Name: "bpm", Version: "1.1.21", - CommitHash: "fd88358", UncommittedChanges: false, CompiledPackages: []tile.CompiledBOSHReleasePackage{ + CommitHash: "fd88358", UncommittedChanges: false, CompiledPackages: []cargo.CompiledBOSHReleasePackage{ { Name: "bpm", Version: "be375c78c703cea04667ea7cbbc6d024bb391182", @@ -111,15 +111,15 @@ func TestReadProductTemplatePartFromBOSHReleaseTarball(t *testing.T) { closeAndIgnoreError(f) }) - result, err := tile.ReadProductTemplatePartFromBOSHReleaseTarball(f) + result, err := cargo.ReadProductTemplatePartFromBOSHReleaseTarball(f) require.NoError(t, err) - require.Equal(t, tile.BOSHReleaseManifest{ + require.Equal(t, cargo.BOSHReleaseManifest{ Name: "bpm", Version: "1.1.21", CommitHash: "fd88358", UncommittedChanges: false, - Packages: []tile.BOSHReleasePackage{ + Packages: []cargo.BOSHReleasePackage{ { Name: "bpm", Version: "be375c78c703cea04667ea7cbbc6d024bb391182", diff --git a/pkg/tile/testdata/bpm-1.1.21-ubuntu-xenial-621.463.tgz b/pkg/cargo/testdata/bpm-1.1.21-ubuntu-xenial-621.463.tgz similarity index 100% rename from pkg/tile/testdata/bpm-1.1.21-ubuntu-xenial-621.463.tgz rename to pkg/cargo/testdata/bpm-1.1.21-ubuntu-xenial-621.463.tgz diff --git a/pkg/tile/testdata/bpm-1.1.21.tgz b/pkg/cargo/testdata/bpm-1.1.21.tgz similarity index 100% rename from pkg/tile/testdata/bpm-1.1.21.tgz rename to pkg/cargo/testdata/bpm-1.1.21.tgz diff --git a/pkg/cargo/testdata/tile-0.1.2.pivotal b/pkg/cargo/testdata/tile-0.1.2.pivotal new file mode 100644 index 0000000000000000000000000000000000000000..4c3f973ab3e157b02e11fe8a66dac5f88d29ea93 GIT binary patch literal 86227 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%0D_#Y=k9w@4B;RuVTsD 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 Qh5y3eynE+w@YlQl52@CCIRF3v literal 0 HcmV?d00001 From 1d1254b380e8abb8f87ed3bfd3376813959a4ac2 Mon Sep 17 00:00:00 2001 From: Christopher Hunter Date: Fri, 14 Jul 2023 16:54:32 -0400 Subject: [PATCH 7/7] refactor: replace 'interface{}' with 'any' type any = interface{} --- .../workflows/scenario/initialize.go | 2 +- .../workflows/scenario/initialize_test.go | 2 +- .../workflows/scenario/shared_state.go | 2 +- internal/baking/fakes/logger.go | 12 +- internal/baking/icon_service_test.go | 2 +- internal/baking/interfaces.go | 2 +- internal/baking/releases_service.go | 4 +- internal/baking/releases_service_test.go | 4 +- internal/baking/stemcell_service.go | 10 +- internal/baking/stemcell_service_test.go | 4 +- internal/baking/template_variables_service.go | 6 +- .../baking/template_variables_service_test.go | 8 +- internal/builder/fakes/logger.go | 4 +- internal/builder/interfaces.go | 6 +- internal/builder/interpolator.go | 34 +- internal/builder/interpolator_test.go | 56 ++-- .../metadata_parts_directory_reader.go | 26 +- .../metadata_parts_directory_reader_test.go | 18 +- internal/builder/stemcell_manifest_reader.go | 2 +- internal/commands/bake.go | 14 +- internal/commands/bake_test.go | 32 +- internal/commands/fakes/from_directories.go | 20 +- .../fakes/parse_metadata_templates.go | 26 +- internal/commands/fakes/session_dialer.go | 16 +- internal/commands/fakes/stemcell_service.go | 60 ++-- .../fakes/template_variables_service.go | 20 +- internal/commands/flags/parse.go | 2 +- .../commands/generate_osm_manifest_test.go | 2 +- internal/commands/glaze_test.go | 4 +- internal/commands/init_test.go | 4 +- internal/commands/test_tile_test.go | 2 +- internal/commands/update_stemcell_test.go | 2 +- .../fakes/release_asset_downloader.go | 14 +- .../release_by_tag_getter_asset_downloader.go | 16 +- .../repository_release_lister.go | 14 +- internal/component/release_source_test.go | 2 +- internal/component/s3_release_source_test.go | 2 +- pkg/cargo/files.go | 2 +- pkg/cargo/files_test.go | 8 +- pkg/history/decode.go | 6 +- pkg/notes/fakes/historic_kilnfile.go | 124 +++++++ pkg/notes/fakes/historic_version.go | 118 +++++++ pkg/notes/fakes/issue_getter.go | 126 ++++++++ pkg/notes/fakes/issues_by_repo_lister.go | 126 ++++++++ pkg/notes/fakes/issues_service.go | 306 ++++++++++++++++++ pkg/notes/fakes/milestone_lister.go | 126 ++++++++ pkg/notes/fakes/releases_service.go | 129 ++++++++ pkg/notes/fakes/revision_resolver.go | 114 +++++++ pkg/notes/internal/fakes/historic_kilnfile.go | 14 +- pkg/notes/internal/fakes/historic_version.go | 14 +- pkg/notes/internal/fakes/issue_getter.go | 14 +- .../internal/fakes/issues_by_repo_lister.go | 14 +- pkg/notes/internal/fakes/issues_service.go | 18 +- pkg/notes/internal/fakes/milestone_lister.go | 14 +- pkg/notes/internal/fakes/releases_service.go | 14 +- pkg/notes/internal/fakes/revision_resolver.go | 14 +- pkg/notes/internal/fakes/trainstat_client.go | 14 +- pkg/planitest/example_product_service_test.go | 2 +- pkg/planitest/internal/config.go | 14 +- .../internal/fakes/command_runner.go | 14 +- pkg/planitest/internal/fakes/file_io.go | 16 +- pkg/planitest/internal/fakes/om_runner.go | 38 +-- .../internal/fakes/ops_manifest_runner.go | 34 +- .../internal/fakes/render_service.go | 14 +- pkg/planitest/internal/internal.go | 4 +- pkg/planitest/internal/om_runner.go | 4 +- pkg/planitest/internal/om_runner_test.go | 6 +- pkg/planitest/internal/om_service_test.go | 2 +- pkg/planitest/internal/ops_manifest_runner.go | 4 +- .../internal/ops_manifest_runner_test.go | 12 +- .../internal/ops_manifest_service_test.go | 2 +- pkg/planitest/manifest.go | 8 +- pkg/planitest/product_service.go | 2 +- pkg/proofing/install_time_verifier.go | 6 +- pkg/proofing/job_type.go | 4 +- pkg/proofing/resource_definition.go | 8 +- pkg/proofing/simple_property_blueprint.go | 4 +- pkg/proofing/upgrade/breaking_changes_test.go | 2 +- pkg/proofing/validation_error.go | 6 +- pkg/proofing/variable.go | 6 +- pkg/proofing/verifier_blueprint.go | 4 +- 81 files changed, 1578 insertions(+), 409 deletions(-) create mode 100644 pkg/notes/fakes/historic_kilnfile.go create mode 100644 pkg/notes/fakes/historic_version.go create mode 100644 pkg/notes/fakes/issue_getter.go create mode 100644 pkg/notes/fakes/issues_by_repo_lister.go create mode 100644 pkg/notes/fakes/issues_service.go create mode 100644 pkg/notes/fakes/milestone_lister.go create mode 100644 pkg/notes/fakes/releases_service.go create mode 100644 pkg/notes/fakes/revision_resolver.go diff --git a/internal/acceptance/workflows/scenario/initialize.go b/internal/acceptance/workflows/scenario/initialize.go index 674c102e4..1f5007f6c 100644 --- a/internal/acceptance/workflows/scenario/initialize.go +++ b/internal/acceptance/workflows/scenario/initialize.go @@ -10,7 +10,7 @@ import ( // scenarioContext is based on *godog.ScenarioContext type scenarioContext interface { - Step(expr, stepFunc interface{}) + Step(expr, stepFunc any) Before(h godog.BeforeScenarioHook) After(h godog.AfterScenarioHook) } diff --git a/internal/acceptance/workflows/scenario/initialize_test.go b/internal/acceptance/workflows/scenario/initialize_test.go index c25322eac..99d55d237 100644 --- a/internal/acceptance/workflows/scenario/initialize_test.go +++ b/internal/acceptance/workflows/scenario/initialize_test.go @@ -172,7 +172,7 @@ var ( tableType = reflect.TypeOf((*godog.Table)(nil)) ) -func (fake fakeScenarioContext) Step(expr, stepFunc interface{}) { +func (fake fakeScenarioContext) Step(expr, stepFunc any) { fn := reflect.ValueOf(stepFunc) if fn.Kind() != reflect.Func { fake.t.Errorf("expected stepFunc to be %s got %s", reflect.Func, fn.Kind()) diff --git a/internal/acceptance/workflows/scenario/shared_state.go b/internal/acceptance/workflows/scenario/shared_state.go index 52ea6debf..85ecfea47 100644 --- a/internal/acceptance/workflows/scenario/shared_state.go +++ b/internal/acceptance/workflows/scenario/shared_state.go @@ -205,7 +205,7 @@ func runAndLogOnError(ctx context.Context, cmd *exec.Cmd, requireSuccess bool) ( return ctx, nil } -func runAndParseStdoutAsYAML(ctx context.Context, cmd *exec.Cmd, d interface{}) (context.Context, error) { +func runAndParseStdoutAsYAML(ctx context.Context, cmd *exec.Cmd, d any) (context.Context, error) { var stdout, stderr bytes.Buffer fds := ctx.Value(standardFileDescriptorsKey).(standardFileDescriptors) cmd.Stdout = io.MultiWriter(&stdout, fds[1]) diff --git a/internal/baking/fakes/logger.go b/internal/baking/fakes/logger.go index 41e21b063..02f2c0841 100644 --- a/internal/baking/fakes/logger.go +++ b/internal/baking/fakes/logger.go @@ -6,19 +6,19 @@ import ( ) type Logger struct { - PrintlnStub func(...interface{}) + PrintlnStub func(...any) printlnMutex sync.RWMutex printlnArgsForCall []struct { - arg1 []interface{} + arg1 []any } invocations map[string][][]interface{} invocationsMutex sync.RWMutex } -func (fake *Logger) Println(arg1 ...interface{}) { +func (fake *Logger) Println(arg1 ...any) { fake.printlnMutex.Lock() fake.printlnArgsForCall = append(fake.printlnArgsForCall, struct { - arg1 []interface{} + arg1 []any }{arg1}) stub := fake.PrintlnStub fake.recordInvocation("Println", []interface{}{arg1}) @@ -34,13 +34,13 @@ func (fake *Logger) PrintlnCallCount() int { return len(fake.printlnArgsForCall) } -func (fake *Logger) PrintlnCalls(stub func(...interface{})) { +func (fake *Logger) PrintlnCalls(stub func(...any)) { fake.printlnMutex.Lock() defer fake.printlnMutex.Unlock() fake.PrintlnStub = stub } -func (fake *Logger) PrintlnArgsForCall(i int) []interface{} { +func (fake *Logger) PrintlnArgsForCall(i int) []any { fake.printlnMutex.RLock() defer fake.printlnMutex.RUnlock() argsForCall := fake.printlnArgsForCall[i] diff --git a/internal/baking/icon_service_test.go b/internal/baking/icon_service_test.go index 25fbbc4a9..4bf331961 100644 --- a/internal/baking/icon_service_test.go +++ b/internal/baking/icon_service_test.go @@ -43,7 +43,7 @@ var _ = Describe("IconService", func() { Expect(encoding).To(Equal("dGhpcyBpcyBzb21lIGRhdGE=")) Expect(logger.PrintlnCallCount()).To(Equal(1)) - Expect(logger.PrintlnArgsForCall(0)).To(Equal([]interface{}{"Encoding icon..."})) + Expect(logger.PrintlnArgsForCall(0)).To(Equal([]any{"Encoding icon..."})) }) Context("when the icon path is empty", func() { diff --git a/internal/baking/interfaces.go b/internal/baking/interfaces.go index 00ae3e694..dbc8d3591 100644 --- a/internal/baking/interfaces.go +++ b/internal/baking/interfaces.go @@ -8,7 +8,7 @@ import ( //counterfeiter:generate -o ./fakes/logger.go --fake-name Logger . logger type logger interface { - Println(v ...interface{}) + Println(v ...any) } //counterfeiter:generate -o ./fakes/part_reader.go --fake-name PartReader . partReader diff --git a/internal/baking/releases_service.go b/internal/baking/releases_service.go index 0153217d1..090aa5f55 100644 --- a/internal/baking/releases_service.go +++ b/internal/baking/releases_service.go @@ -20,7 +20,7 @@ func NewReleasesService(logger logger, reader partReader) ReleasesService { } } -func (s ReleasesService) FromDirectories(directories []string) (map[string]interface{}, error) { +func (s ReleasesService) FromDirectories(directories []string) (map[string]any, error) { s.logger.Println("Reading release manifests...") var releases []builder.Part @@ -33,7 +33,7 @@ func (s ReleasesService) FromDirectories(directories []string) (map[string]inter releases = append(releases, newReleases...) } - manifests := map[string]interface{}{} + manifests := map[string]any{} for _, rel := range releases { manifests[rel.Name] = rel.Metadata } diff --git a/internal/baking/releases_service_test.go b/internal/baking/releases_service_test.go index 1f7fa16e2..b9145a22c 100644 --- a/internal/baking/releases_service_test.go +++ b/internal/baking/releases_service_test.go @@ -69,13 +69,13 @@ var _ = Describe("ReleasesService", func() { releases, err := service.FromDirectories([]string{tempDir}) Expect(err).NotTo(HaveOccurred()) - Expect(releases).To(Equal(map[string]interface{}{ + Expect(releases).To(Equal(map[string]any{ "some-name": "some-metadata", "other-name": "other-metadata", })) Expect(logger.PrintlnCallCount()).To(Equal(1)) - Expect(logger.PrintlnArgsForCall(0)).To(Equal([]interface{}{"Reading release manifests..."})) + Expect(logger.PrintlnArgsForCall(0)).To(Equal([]any{"Reading release manifests..."})) Expect(reader.ReadCallCount()).To(Equal(2)) Expect(reader.ReadArgsForCall(0)).To(Equal(filepath.Join(tempDir, "other-release.tgz"))) diff --git a/internal/baking/stemcell_service.go b/internal/baking/stemcell_service.go index 0a138efe1..431d7e29f 100644 --- a/internal/baking/stemcell_service.go +++ b/internal/baking/stemcell_service.go @@ -26,7 +26,7 @@ func NewStemcellService(logger logger, tarballReader partReader) StemcellService } } -func (ss StemcellService) FromDirectories(directories []string) (stemcell map[string]interface{}, err error) { +func (ss StemcellService) FromDirectories(directories []string) (stemcell map[string]any, err error) { ss.logger.Println("Reading stemcells from directories...") var tarballs []string @@ -47,7 +47,7 @@ func (ss StemcellService) FromDirectories(directories []string) (stemcell map[st } } - manifests := map[string]interface{}{} + manifests := map[string]any{} for _, tarball := range tarballs { manifest, err := ss.tarballReader.Read(tarball) if err != nil { @@ -66,7 +66,7 @@ func (ss StemcellService) FromDirectories(directories []string) (stemcell map[st return manifests, nil } -func (ss StemcellService) FromTarball(path string) (interface{}, error) { +func (ss StemcellService) FromTarball(path string) (any, error) { if path == "" { return nil, nil } @@ -81,7 +81,7 @@ func (ss StemcellService) FromTarball(path string) (interface{}, error) { return stemcell.Metadata, nil } -func (ss StemcellService) FromKilnfile(kilnfilePath string) (map[string]interface{}, error) { +func (ss StemcellService) FromKilnfile(kilnfilePath string) (map[string]any, error) { kilnfileLockPath := fmt.Sprintf("%s.lock", kilnfilePath) kilnfileLockBasename := path.Base(kilnfileLockPath) ss.logger.Println(fmt.Sprintf("Reading stemcell criteria from %s", kilnfileLockBasename)) @@ -111,7 +111,7 @@ func (ss StemcellService) FromKilnfile(kilnfilePath string) (map[string]interfac stemcell := stemcellCriteria.Metadata - stemcellManifest := map[string]interface{}{ + stemcellManifest := map[string]any{ stemcell.OperatingSystem: stemcellCriteria.Metadata, } diff --git a/internal/baking/stemcell_service_test.go b/internal/baking/stemcell_service_test.go index 6682d003d..b9cdfd7fb 100644 --- a/internal/baking/stemcell_service_test.go +++ b/internal/baking/stemcell_service_test.go @@ -67,7 +67,7 @@ var _ = Describe("StemcellService", func() { stemcell, err := service.FromDirectories([]string{tempDir}) Expect(err).NotTo(HaveOccurred()) - Expect(stemcell).To(Equal(map[string]interface{}{ + Expect(stemcell).To(Equal(map[string]any{ "some-os": builder.StemcellManifest{ Version: "some-version", OperatingSystem: "some-os", @@ -128,7 +128,7 @@ var _ = Describe("StemcellService", func() { })) Expect(logger.PrintlnCallCount()).To(Equal(1)) - Expect(logger.PrintlnArgsForCall(0)).To(Equal([]interface{}{"Reading stemcell manifest..."})) + Expect(logger.PrintlnArgsForCall(0)).To(Equal([]any{"Reading stemcell manifest..."})) Expect(reader.ReadCallCount()).To(Equal(1)) Expect(reader.ReadArgsForCall(0)).To(Equal("some-stemcell-tarball")) diff --git a/internal/baking/template_variables_service.go b/internal/baking/template_variables_service.go index baa2f8d8c..34023480e 100644 --- a/internal/baking/template_variables_service.go +++ b/internal/baking/template_variables_service.go @@ -17,8 +17,8 @@ func NewTemplateVariablesService(fs billy.Basic) TemplateVariablesService { return TemplateVariablesService{filesystem: fs} } -func (s TemplateVariablesService) FromPathsAndPairs(paths []string, pairs []string) (map[string]interface{}, error) { - variables := map[string]interface{}{} +func (s TemplateVariablesService) FromPathsAndPairs(paths []string, pairs []string) (map[string]any, error) { + variables := map[string]any{} for _, path := range paths { err := parseVariablesFromFile(s.filesystem, path, variables) @@ -40,7 +40,7 @@ func (s TemplateVariablesService) FromPathsAndPairs(paths []string, pairs []stri return variables, nil } -func parseVariablesFromFile(fs billy.Basic, path string, variables map[string]interface{}) error { +func parseVariablesFromFile(fs billy.Basic, path string, variables map[string]any) error { file, err := fs.Open(path) if err != nil { return fmt.Errorf("unable to open file %q: %w", path, err) diff --git a/internal/baking/template_variables_service_test.go b/internal/baking/template_variables_service_test.go index fdd582aa9..cf4718ad1 100644 --- a/internal/baking/template_variables_service_test.go +++ b/internal/baking/template_variables_service_test.go @@ -49,9 +49,9 @@ key-3: value-3 It("parses template variables from a collection of files", func() { variables, err := service.FromPathsAndPairs([]string{path}, nil) Expect(err).NotTo(HaveOccurred()) - Expect(variables).To(Equal(map[string]interface{}{ - "key-1": map[interface{}]interface{}{ - "key-2": []interface{}{ + Expect(variables).To(Equal(map[string]any{ + "key-1": map[any]any{ + "key-2": []any{ "value-1", "value-2", }, @@ -66,7 +66,7 @@ key-3: value-3 "key-2=value-2", }) Expect(err).NotTo(HaveOccurred()) - Expect(variables).To(Equal(map[string]interface{}{ + Expect(variables).To(Equal(map[string]any{ "key-1": "value-1", "key-2": "value-2", })) diff --git a/internal/builder/fakes/logger.go b/internal/builder/fakes/logger.go index 831cc7272..ec7d83348 100644 --- a/internal/builder/fakes/logger.go +++ b/internal/builder/fakes/logger.go @@ -16,10 +16,10 @@ type Logger struct { } } -func (l *Logger) Printf(format string, v ...interface{}) { +func (l *Logger) Printf(format string, v ...any) { l.PrintfCall.Receives.LogLines = append(l.PrintfCall.Receives.LogLines, fmt.Sprintf(format, v...)) } -func (l *Logger) Println(v ...interface{}) { +func (l *Logger) Println(v ...any) { l.PrintlnCall.Receives.LogLines = append(l.PrintlnCall.Receives.LogLines, fmt.Sprintf("%s", v...)) } diff --git a/internal/builder/interfaces.go b/internal/builder/interfaces.go index 5031b4aa3..a556befd1 100644 --- a/internal/builder/interfaces.go +++ b/internal/builder/interfaces.go @@ -3,10 +3,10 @@ package builder import "io" type logger interface { - Printf(format string, v ...interface{}) - Println(v ...interface{}) + Printf(format string, v ...any) + Println(v ...any) } -type Metadata map[string]interface{} +type Metadata map[string]any func closeAndIgnoreError(c io.Closer) { _ = c.Close() } diff --git a/internal/builder/interpolator.go b/internal/builder/interpolator.go index 1ee226c90..bff5ebe65 100644 --- a/internal/builder/interpolator.go +++ b/internal/builder/interpolator.go @@ -35,17 +35,17 @@ type Interpolator struct{} type InterpolateInput struct { Version string - BOSHVariables map[string]interface{} - Variables map[string]interface{} - ReleaseManifests map[string]interface{} - StemcellManifests map[string]interface{} - StemcellManifest interface{} - FormTypes map[string]interface{} + BOSHVariables map[string]any + Variables map[string]any + ReleaseManifests map[string]any + StemcellManifests map[string]any + StemcellManifest any + FormTypes map[string]any IconImage string - InstanceGroups map[string]interface{} - Jobs map[string]interface{} - PropertyBlueprints map[string]interface{} - RuntimeConfigs map[string]interface{} + InstanceGroups map[string]any + Jobs map[string]any + PropertyBlueprints map[string]any + RuntimeConfigs map[string]any StubReleases bool MetadataGitSHA func() (string, error) } @@ -124,7 +124,7 @@ func (i Interpolator) functions(input InterpolateInput) template.FuncMap { if !ok { if input.StubReleases { - val = map[string]interface{}{ + val = map[string]any{ "name": name, "version": "UNKNOWN", "file": fmt.Sprintf("%s-UNKNOWN.tgz", name), @@ -221,7 +221,7 @@ func (i Interpolator) functions(input InterpolateInput) template.FuncMap { return i.interpolateValueIntoYAML(input, name, val) }, "select": func(field, input string) (string, error) { - object := map[string]interface{}{} + object := map[string]any{} err := json.Unmarshal([]byte(input), &object) if err != nil { @@ -263,7 +263,7 @@ func (i Interpolator) interpolate(input InterpolateInput, name string, templateY return buffer.Bytes(), nil } -func (i Interpolator) interpolateValueIntoYAML(input InterpolateInput, name string, val interface{}) (string, error) { +func (i Interpolator) interpolateValueIntoYAML(input InterpolateInput, name string, val any) (string, error) { initialYAML, err := yaml.Marshal(val) if err != nil { return "", err // should never happen @@ -288,7 +288,7 @@ func (i Interpolator) yamlMarshalOneLine(yamlContents []byte) ([]byte, error) { } func (i Interpolator) prettyPrint(inputYAML []byte) ([]byte, error) { - var data interface{} + var data any err := yaml.Unmarshal(inputYAML, &data) if err != nil { return []byte{}, err // should never happen @@ -297,7 +297,7 @@ func (i Interpolator) prettyPrint(inputYAML []byte) ([]byte, error) { return yaml.Marshal(data) } -func PreProcessMetadataWithTileFunction(variables map[string]interface{}, name string, dst io.Writer, in []byte) error { +func PreProcessMetadataWithTileFunction(variables map[string]any, name string, dst io.Writer, in []byte) error { tileFN := tileFunc(variables) t, err := template.New(name). @@ -313,9 +313,9 @@ func PreProcessMetadataWithTileFunction(variables map[string]interface{}, name s // tileFunc is used both in pre-processing and is also available // to Interpolator -func tileFunc(variables map[string]interface{}) func() (string, error) { +func tileFunc(variables map[string]any) func() (string, error) { if variables == nil { - variables = make(map[string]interface{}) + variables = make(map[string]any) } return func() (string, error) { diff --git a/internal/builder/interpolator_test.go b/internal/builder/interpolator_test.go index 31ff58e06..bca7b7b25 100644 --- a/internal/builder/interpolator_test.go +++ b/internal/builder/interpolator_test.go @@ -49,16 +49,16 @@ selected_value: $( release "some-release" | select "version" ) input = builder.InterpolateInput{ Version: "3.4.5", - BOSHVariables: map[string]interface{}{ + BOSHVariables: map[string]any{ "some-bosh-variable": builder.Metadata{ "name": "some-bosh-variable", "type": "some-bosh-type", }, }, - Variables: map[string]interface{}{ + Variables: map[string]any{ "some-variable": "some-value", }, - ReleaseManifests: map[string]interface{}{ + ReleaseManifests: map[string]any{ "some-release": builder.ReleaseManifest{ Name: "some-release", Version: "1.2.3", @@ -70,14 +70,14 @@ selected_value: $( release "some-release" | select "version" ) Version: "2.3.4", OperatingSystem: "an-operating-system", }, - FormTypes: map[string]interface{}{ + FormTypes: map[string]any{ "some-form": builder.Metadata{ "name": "some-form", "label": "some-form-label", }, }, IconImage: "some-icon-image", - InstanceGroups: map[string]interface{}{ + InstanceGroups: map[string]any{ "some-instance-group": builder.Metadata{ "name": "some-instance-group", "templates": []string{ @@ -85,13 +85,13 @@ selected_value: $( release "some-release" | select "version" ) }, }, }, - Jobs: map[string]interface{}{ + Jobs: map[string]any{ "some-job": builder.Metadata{ "name": "some-job", "release": "some-release", }, }, - PropertyBlueprints: map[string]interface{}{ + PropertyBlueprints: map[string]any{ "some-templated-property": builder.Metadata{ "name": "some-templated-property", "type": "boolean", @@ -105,7 +105,7 @@ selected_value: $( release "some-release" | select "version" ) "default": "some-value", }, }, - RuntimeConfigs: map[string]interface{}{ + RuntimeConfigs: map[string]any{ "some-runtime-config": builder.Metadata{ "name": "some-runtime-config", "runtime_config": "some-addon-runtime-config\n", @@ -198,10 +198,10 @@ some_form_types: - $( form "some-form" )` input = builder.InterpolateInput{ - Variables: map[string]interface{}{ + Variables: map[string]any{ "some-form-variable": "variable-form-label", }, - FormTypes: map[string]interface{}{ + FormTypes: map[string]any{ "some-form": builder.Metadata{ "name": "some-form", "label": `$( variable "some-form-variable" )`, @@ -223,7 +223,7 @@ some_form_types: BeforeEach(func() { input = builder.InterpolateInput{ - ReleaseManifests: map[string]interface{}{ + ReleaseManifests: map[string]any{ "some-release": builder.ReleaseManifest{ Name: "some-release", Version: "1.2.3", @@ -231,7 +231,7 @@ some_form_types: SHA1: "123abc", }, }, - StemcellManifests: map[string]interface{}{ + StemcellManifests: map[string]any{ "windows": builder.StemcellManifest{ OperatingSystem: "windows", Version: "2019.4", @@ -288,7 +288,7 @@ additional_stemcells_criteria: stemcell_criteria: $( stemcell )` input = builder.InterpolateInput{ - ReleaseManifests: map[string]interface{}{ + ReleaseManifests: map[string]any{ "some-release": builder.ReleaseManifest{ Name: "some-release", Version: "1.2.3", @@ -296,7 +296,7 @@ stemcell_criteria: $( stemcell )` SHA1: "123abc", }, }, - StemcellManifests: map[string]interface{}{ + StemcellManifests: map[string]any{ "centOS": builder.StemcellManifest{ OperatingSystem: "centOS", Version: "5.4", @@ -328,7 +328,7 @@ some_runtime_configs: - $( runtime_config "some-runtime-config" )` input = builder.InterpolateInput{ - ReleaseManifests: map[string]interface{}{ + ReleaseManifests: map[string]any{ "some-release": builder.ReleaseManifest{ Name: "some-release", Version: "1.2.3", @@ -336,7 +336,7 @@ some_runtime_configs: SHA1: "123abc", }, }, - RuntimeConfigs: map[string]interface{}{ + RuntimeConfigs: map[string]any{ "some-runtime-config": builder.Metadata{ "name": "some-runtime-config", "runtime_config": `releases: @@ -350,14 +350,14 @@ some_runtime_configs: interpolatedYAML, err := interpolator.Interpolate(input, "", []byte(templateYAML)) Expect(err).NotTo(HaveOccurred()) - var output map[string]interface{} + var output map[string]any err = yaml.Unmarshal(interpolatedYAML, &output) Expect(err).NotTo(HaveOccurred()) Expect(output).To(HaveKey("some_runtime_configs")) - configs, ok := output["some_runtime_configs"].([]interface{}) + configs, ok := output["some_runtime_configs"].([]any) Expect(ok).To(BeTrue()) - config, ok := configs[0].(map[interface{}]interface{}) + config, ok := configs[0].(map[any]any) Expect(ok).To(BeTrue()) Expect(config).To(HaveKeyWithValue("name", "some-runtime-config")) @@ -371,7 +371,7 @@ releases: Context("when the interpolated runtime config does not have a runtime_config key", func() { JustBeforeEach(func() { - input.RuntimeConfigs = map[string]interface{}{ + input.RuntimeConfigs = map[string]any{ "some-runtime-config": builder.Metadata{ "name": "some-runtime-config", }, @@ -406,7 +406,7 @@ some_runtime_configs: Context("failure cases", func() { Context("when the requested form name is not found", func() { It("returns an error", func() { - input.FormTypes = map[string]interface{}{} + input.FormTypes = map[string]any{} interpolator := builder.NewInterpolator() _, err := interpolator.Interpolate(input, "", []byte(templateYAML)) @@ -417,7 +417,7 @@ some_runtime_configs: Context("when the requested property blueprint is not found", func() { It("returns an error", func() { - input.PropertyBlueprints = map[string]interface{}{} + input.PropertyBlueprints = map[string]any{} interpolator := builder.NewInterpolator() _, err := interpolator.Interpolate(input, "", []byte(templateYAML)) @@ -428,7 +428,7 @@ some_runtime_configs: Context("when the requested runtime config is not found", func() { It("returns an error", func() { - input.RuntimeConfigs = map[string]interface{}{} + input.RuntimeConfigs = map[string]any{} interpolator := builder.NewInterpolator() _, err := interpolator.Interpolate(input, "", []byte(templateYAML)) @@ -439,7 +439,7 @@ some_runtime_configs: Context("when the nested form contains invalid templating", func() { It("returns an error", func() { - input.FormTypes = map[string]interface{}{ + input.FormTypes = map[string]any{ "some-form": builder.Metadata{ "name": "some-form", "label": "$( invalid_helper )", @@ -711,13 +711,13 @@ tile: {{if eq tile "ert" -}} {{- end -}} ` var buf bytes.Buffer - err := builder.PreProcessMetadataWithTileFunction(map[string]interface{}{"tile_name": "ERT"}, "m.yml", &buf, []byte(partYML)) + err := builder.PreProcessMetadataWithTileFunction(map[string]any{"tile_name": "ERT"}, "m.yml", &buf, []byte(partYML)) please.Expect(err).NotTo(HaveOccurred()) please.Expect(buf.Bytes()).To(MatchYAML(`tile: big-foot`)) buf.Reset() - err = builder.PreProcessMetadataWithTileFunction(map[string]interface{}{"tile_name": "SRT"}, "m.yml", &buf, []byte(partYML)) + err = builder.PreProcessMetadataWithTileFunction(map[string]any{"tile_name": "SRT"}, "m.yml", &buf, []byte(partYML)) please.Expect(err).NotTo(HaveOccurred()) please.Expect(buf.Bytes()).To(MatchYAML(`tile: small-foot`)) }) @@ -726,7 +726,7 @@ tile: {{if eq tile "ert" -}} please := NewWithT(t) partYML := `tile: {{tile}}` - err := builder.PreProcessMetadataWithTileFunction(map[string]interface{}{"tile_name": 27}, "m.yml", io.Discard, []byte(partYML)) + err := builder.PreProcessMetadataWithTileFunction(map[string]any{"tile_name": 27}, "m.yml", io.Discard, []byte(partYML)) please.Expect(err).To(And( HaveOccurred(), MatchError(ContainSubstring("expected string")), @@ -737,7 +737,7 @@ tile: {{if eq tile "ert" -}} please := NewWithT(t) partYML := `tile: {{tile}}` - err := builder.PreProcessMetadataWithTileFunction(make(map[string]interface{}), "m.yml", io.Discard, []byte(partYML)) + err := builder.PreProcessMetadataWithTileFunction(make(map[string]any), "m.yml", io.Discard, []byte(partYML)) please.Expect(err).To(And( HaveOccurred(), MatchError(ContainSubstring("could not find variable")), diff --git a/internal/builder/metadata_parts_directory_reader.go b/internal/builder/metadata_parts_directory_reader.go index 3efb96064..7a6e36c3b 100644 --- a/internal/builder/metadata_parts_directory_reader.go +++ b/internal/builder/metadata_parts_directory_reader.go @@ -20,7 +20,7 @@ type MetadataPartsDirectoryReader struct { type Part struct { File string Name string - Metadata interface{} + Metadata any } func NewMetadataPartsDirectoryReader() MetadataPartsDirectoryReader { @@ -48,7 +48,7 @@ func (r MetadataPartsDirectoryReader) Read(path string) ([]Part, error) { return r.orderAlphabeticallyByName(path, parts) } -func (r MetadataPartsDirectoryReader) ParseMetadataTemplates(directories []string, variables map[string]interface{}) (map[string]interface{}, error) { +func (r MetadataPartsDirectoryReader) ParseMetadataTemplates(directories []string, variables map[string]any) (map[string]any, error) { var releases []Part for _, directory := range directories { newReleases, err := r.ReadPreProcess(directory, variables) @@ -59,7 +59,7 @@ func (r MetadataPartsDirectoryReader) ParseMetadataTemplates(directories []strin releases = append(releases, newReleases...) } - manifests := map[string]interface{}{} + manifests := map[string]any{} for _, rel := range releases { manifests[rel.Name] = rel.Metadata } @@ -67,7 +67,7 @@ func (r MetadataPartsDirectoryReader) ParseMetadataTemplates(directories []strin return manifests, nil } -func (r MetadataPartsDirectoryReader) ReadPreProcess(path string, variables map[string]interface{}) ([]Part, error) { +func (r MetadataPartsDirectoryReader) ReadPreProcess(path string, variables map[string]any) ([]Part, error) { parts, err := r.readMetadataRecursivelyFromDir(path, variables) if err != nil { return []Part{}, err @@ -80,7 +80,7 @@ func (r MetadataPartsDirectoryReader) ReadPreProcess(path string, variables map[ return r.orderAlphabeticallyByName(path, parts) } -func (r MetadataPartsDirectoryReader) readMetadataRecursivelyFromDir(p string, variables map[string]interface{}) ([]Part, error) { +func (r MetadataPartsDirectoryReader) readMetadataRecursivelyFromDir(p string, variables map[string]any) ([]Part, error) { var parts []Part var buf bytes.Buffer @@ -108,9 +108,9 @@ func (r MetadataPartsDirectoryReader) readMetadataRecursivelyFromDir(p string, v data = buf.Bytes() } - var vars interface{} + var vars any if r.topLevelKey != "" { - var fileVars map[string]interface{} + var fileVars map[string]any err = yaml.Unmarshal(data, &fileVars) if err != nil { return fmt.Errorf("cannot unmarshal '%s': %s", filePath, err) @@ -139,11 +139,11 @@ func (r MetadataPartsDirectoryReader) readMetadataRecursivelyFromDir(p string, v return parts, err } -func (r MetadataPartsDirectoryReader) readMetadataIntoParts(fileName string, vars interface{}, parts []Part) ([]Part, error) { +func (r MetadataPartsDirectoryReader) readMetadataIntoParts(fileName string, vars any, parts []Part) ([]Part, error) { switch v := vars.(type) { - case []interface{}: + case []any: for _, item := range v { - i, ok := item.(map[interface{}]interface{}) + i, ok := item.(map[any]any) if !ok { return []Part{}, fmt.Errorf("metadata item '%v' must be a map", item) } @@ -155,7 +155,7 @@ func (r MetadataPartsDirectoryReader) readMetadataIntoParts(fileName string, var parts = append(parts, part) } - case map[interface{}]interface{}: + case map[any]any: part, err := r.buildPartFromMetadata(v, fileName) if err != nil { return []Part{}, err @@ -168,7 +168,7 @@ func (r MetadataPartsDirectoryReader) readMetadataIntoParts(fileName string, var return parts, nil } -func (r MetadataPartsDirectoryReader) buildPartFromMetadata(metadata map[interface{}]interface{}, legacyFilename string) (Part, error) { +func (r MetadataPartsDirectoryReader) buildPartFromMetadata(metadata map[any]any, legacyFilename string) (Part, error) { name, ok := metadata["alias"].(string) if !ok { name, ok = metadata["name"].(string) @@ -194,7 +194,7 @@ func (r MetadataPartsDirectoryReader) orderWithOrderFromFile(path string, parts return []Part{}, err } - var files map[string][]interface{} + var files map[string][]any err = yaml.Unmarshal(data, &files) if err != nil { return []Part{}, fmt.Errorf("invalid format for %q: %w", orderPath, err) diff --git a/internal/builder/metadata_parts_directory_reader_test.go b/internal/builder/metadata_parts_directory_reader_test.go index db3f83dd2..e98286924 100644 --- a/internal/builder/metadata_parts_directory_reader_test.go +++ b/internal/builder/metadata_parts_directory_reader_test.go @@ -55,7 +55,7 @@ type: password { File: "vars-file-1.yml", Name: "variable-1", - Metadata: map[interface{}]interface{}{ + Metadata: map[any]any{ "name": "variable-1", "type": "certificate", }, @@ -63,7 +63,7 @@ type: password { File: "vars-file-1.yml", Name: "variable-2-alias", - Metadata: map[interface{}]interface{}{ + Metadata: map[any]any{ "name": "variable-2", "type": "user", }, @@ -71,7 +71,7 @@ type: password { File: "vars-file-2.yml", Name: "variable-3", - Metadata: map[interface{}]interface{}{ + Metadata: map[any]any{ "name": "variable-3", "type": "password", }, @@ -171,7 +171,7 @@ variables: { File: "vars-file-1.yml", Name: "variable-1", - Metadata: map[interface{}]interface{}{ + Metadata: map[any]any{ "name": "variable-1", "type": "certificate", }, @@ -179,7 +179,7 @@ variables: { File: "vars-file-1.yml", Name: "variable-2", - Metadata: map[interface{}]interface{}{ + Metadata: map[any]any{ "name": "variable-2", "type": "user", }, @@ -187,7 +187,7 @@ variables: { File: "vars-file-2.yml", Name: "variable-3", - Metadata: map[interface{}]interface{}{ + Metadata: map[any]any{ "name": "variable-3", "type": "password", }, @@ -273,7 +273,7 @@ variables: { File: "vars-file-2.yml", Name: "variable-3", - Metadata: map[interface{}]interface{}{ + Metadata: map[any]any{ "name": "variable-3", "type": "password", }, @@ -281,7 +281,7 @@ variables: { File: "vars-file-1.yml", Name: "variable-2", - Metadata: map[interface{}]interface{}{ + Metadata: map[any]any{ "name": "variable-2", "type": "user", }, @@ -289,7 +289,7 @@ variables: { File: "vars-file-1.yml", Name: "variable-1", - Metadata: map[interface{}]interface{}{ + Metadata: map[any]any{ "name": "variable-1", "type": "certificate", }, diff --git a/internal/builder/stemcell_manifest_reader.go b/internal/builder/stemcell_manifest_reader.go index ae3330d8b..6f6a6af92 100644 --- a/internal/builder/stemcell_manifest_reader.go +++ b/internal/builder/stemcell_manifest_reader.go @@ -17,7 +17,7 @@ type StemcellManifest struct { // the input field in stemcell.MF is called `operating_system` while the output field is `os` -func (s StemcellManifest) MarshalYAML() (interface{}, error) { +func (s StemcellManifest) MarshalYAML() (any, error) { return struct { Version string `yaml:"version"` OperatingSystem string `yaml:"os"` diff --git a/internal/commands/bake.go b/internal/commands/bake.go index 07c389317..fd69ac2a0 100644 --- a/internal/commands/bake.go +++ b/internal/commands/bake.go @@ -30,24 +30,24 @@ type tileWriter interface { //counterfeiter:generate -o ./fakes/from_directories.go --fake-name FromDirectories . fromDirectories type fromDirectories interface { - FromDirectories(directories []string) (map[string]interface{}, error) + FromDirectories(directories []string) (map[string]any, error) } //counterfeiter:generate -o ./fakes/parse_metadata_templates.go --fake-name MetadataTemplatesParser . metadataTemplatesParser type metadataTemplatesParser interface { - ParseMetadataTemplates(directories []string, variables map[string]interface{}) (map[string]interface{}, error) + ParseMetadataTemplates(directories []string, variables map[string]any) (map[string]any, error) } //counterfeiter:generate -o ./fakes/stemcell_service.go --fake-name StemcellService . stemcellService type stemcellService interface { fromDirectories - FromKilnfile(path string) (stemcell map[string]interface{}, err error) - FromTarball(path string) (stemcell interface{}, err error) + FromKilnfile(path string) (stemcell map[string]any, err error) + FromTarball(path string) (stemcell any, err error) } //counterfeiter:generate -o ./fakes/template_variables_service.go --fake-name TemplateVariablesService . templateVariablesService type templateVariablesService interface { - FromPathsAndPairs(paths []string, pairs []string) (templateVariables map[string]interface{}, err error) + FromPathsAndPairs(paths []string, pairs []string) (templateVariables map[string]any, err error) } //counterfeiter:generate -o ./fakes/icon_service.go --fake-name IconService . iconService @@ -408,8 +408,8 @@ func (b Bake) Execute(args []string) error { return fmt.Errorf("failed to parse releases: %s", err) } - var stemcellManifests map[string]interface{} - var stemcellManifest interface{} + var stemcellManifests map[string]any + var stemcellManifest any if b.Options.StemcellTarball != "" { // TODO remove when stemcell tarball is deprecated stemcellManifest, err = b.stemcell.FromTarball(b.Options.StemcellTarball) diff --git a/internal/commands/bake_test.go b/internal/commands/bake_test.go index 711b7c485..48928cdf3 100644 --- a/internal/commands/bake_test.go +++ b/internal/commands/bake_test.go @@ -96,12 +96,12 @@ var _ = Describe("Bake", func() { return "/home/", nil } - fakeTemplateVariablesService.FromPathsAndPairsReturns(map[string]interface{}{ + fakeTemplateVariablesService.FromPathsAndPairsReturns(map[string]any{ "some-variable-from-file": "some-variable-value-from-file", "some-variable": "some-variable-value", }, nil) - fakeReleasesService.FromDirectoriesReturns(map[string]interface{}{ + fakeReleasesService.FromDirectoriesReturns(map[string]any{ "some-release-1": builder.ReleaseManifest{ Name: "some-release-1", Version: "1.2.3", @@ -119,21 +119,21 @@ var _ = Describe("Bake", func() { OperatingSystem: "an-operating-system", }, nil) - fakeFormsService.ParseMetadataTemplatesReturns(map[string]interface{}{ + fakeFormsService.ParseMetadataTemplatesReturns(map[string]any{ "some-form": builder.Metadata{ "name": "some-form", "label": "some-form-label", }, }, nil) - fakeBOSHVariablesService.ParseMetadataTemplatesReturns(map[string]interface{}{ + fakeBOSHVariablesService.ParseMetadataTemplatesReturns(map[string]any{ "some-secret": builder.Metadata{ "name": "some-secret", "type": "password", }, }, nil) - fakeInstanceGroupsService.ParseMetadataTemplatesReturns(map[string]interface{}{ + fakeInstanceGroupsService.ParseMetadataTemplatesReturns(map[string]any{ "some-instance-group": builder.Metadata{ "name": "some-instance-group", "manifest": "some-manifest", @@ -142,7 +142,7 @@ var _ = Describe("Bake", func() { }, }, nil) - fakeJobsService.ParseMetadataTemplatesReturns(map[string]interface{}{ + fakeJobsService.ParseMetadataTemplatesReturns(map[string]any{ "some-job": builder.Metadata{ "name": "some-job", "release": "some-release", @@ -150,7 +150,7 @@ var _ = Describe("Bake", func() { }, }, nil) - fakePropertiesService.ParseMetadataTemplatesReturns(map[string]interface{}{ + fakePropertiesService.ParseMetadataTemplatesReturns(map[string]any{ "some-property": builder.Metadata{ "name": "some-property", "type": "boolean", @@ -159,7 +159,7 @@ var _ = Describe("Bake", func() { }, }, nil) - fakeRuntimeConfigsService.ParseMetadataTemplatesReturns(map[string]interface{}{ + fakeRuntimeConfigsService.ParseMetadataTemplatesReturns(map[string]any{ "some-runtime-config": builder.Metadata{ "name": "some-runtime-config", "runtime_config": "some-addon-runtime-config", @@ -265,17 +265,17 @@ var _ = Describe("Bake", func() { input.MetadataGitSHA = nil // func pointers are not comparable unless they are both nil Expect(input).To(Equal(builder.InterpolateInput{ Version: "1.2.3", - BOSHVariables: map[string]interface{}{ + BOSHVariables: map[string]any{ "some-secret": builder.Metadata{ "name": "some-secret", "type": "password", }, }, - Variables: map[string]interface{}{ + Variables: map[string]any{ "some-variable-from-file": "some-variable-value-from-file", "some-variable": "some-variable-value", }, - ReleaseManifests: map[string]interface{}{ + ReleaseManifests: map[string]any{ "some-release-1": builder.ReleaseManifest{ Name: "some-release-1", Version: "1.2.3", @@ -291,14 +291,14 @@ var _ = Describe("Bake", func() { Version: "2.3.4", OperatingSystem: "an-operating-system", }, - FormTypes: map[string]interface{}{ + FormTypes: map[string]any{ "some-form": builder.Metadata{ "name": "some-form", "label": "some-form-label", }, }, IconImage: "some-encoded-icon", - InstanceGroups: map[string]interface{}{ + InstanceGroups: map[string]any{ "some-instance-group": builder.Metadata{ "name": "some-instance-group", "manifest": "some-manifest", @@ -306,14 +306,14 @@ var _ = Describe("Bake", func() { "release": "some-release", }, }, - Jobs: map[string]interface{}{ + Jobs: map[string]any{ "some-job": builder.Metadata{ "name": "some-job", "release": "some-release", "consumes": "some-link", }, }, - PropertyBlueprints: map[string]interface{}{ + PropertyBlueprints: map[string]any{ "some-property": builder.Metadata{ "name": "some-property", "type": "boolean", @@ -321,7 +321,7 @@ var _ = Describe("Bake", func() { "default": false, }, }, - RuntimeConfigs: map[string]interface{}{ + RuntimeConfigs: map[string]any{ "some-runtime-config": builder.Metadata{ "name": "some-runtime-config", "runtime_config": "some-addon-runtime-config", diff --git a/internal/commands/fakes/from_directories.go b/internal/commands/fakes/from_directories.go index 2d63a2bca..40b0a9fca 100644 --- a/internal/commands/fakes/from_directories.go +++ b/internal/commands/fakes/from_directories.go @@ -6,24 +6,24 @@ import ( ) type FromDirectories struct { - FromDirectoriesStub func([]string) (map[string]interface{}, error) + FromDirectoriesStub func([]string) (map[string]any, error) fromDirectoriesMutex sync.RWMutex fromDirectoriesArgsForCall []struct { arg1 []string } fromDirectoriesReturns struct { - result1 map[string]interface{} + result1 map[string]any result2 error } fromDirectoriesReturnsOnCall map[int]struct { - result1 map[string]interface{} + result1 map[string]any result2 error } invocations map[string][][]interface{} invocationsMutex sync.RWMutex } -func (fake *FromDirectories) FromDirectories(arg1 []string) (map[string]interface{}, error) { +func (fake *FromDirectories) FromDirectories(arg1 []string) (map[string]any, error) { var arg1Copy []string if arg1 != nil { arg1Copy = make([]string, len(arg1)) @@ -53,7 +53,7 @@ func (fake *FromDirectories) FromDirectoriesCallCount() int { return len(fake.fromDirectoriesArgsForCall) } -func (fake *FromDirectories) FromDirectoriesCalls(stub func([]string) (map[string]interface{}, error)) { +func (fake *FromDirectories) FromDirectoriesCalls(stub func([]string) (map[string]any, error)) { fake.fromDirectoriesMutex.Lock() defer fake.fromDirectoriesMutex.Unlock() fake.FromDirectoriesStub = stub @@ -66,28 +66,28 @@ func (fake *FromDirectories) FromDirectoriesArgsForCall(i int) []string { return argsForCall.arg1 } -func (fake *FromDirectories) FromDirectoriesReturns(result1 map[string]interface{}, result2 error) { +func (fake *FromDirectories) FromDirectoriesReturns(result1 map[string]any, result2 error) { fake.fromDirectoriesMutex.Lock() defer fake.fromDirectoriesMutex.Unlock() fake.FromDirectoriesStub = nil fake.fromDirectoriesReturns = struct { - result1 map[string]interface{} + result1 map[string]any result2 error }{result1, result2} } -func (fake *FromDirectories) FromDirectoriesReturnsOnCall(i int, result1 map[string]interface{}, result2 error) { +func (fake *FromDirectories) FromDirectoriesReturnsOnCall(i int, result1 map[string]any, result2 error) { fake.fromDirectoriesMutex.Lock() defer fake.fromDirectoriesMutex.Unlock() fake.FromDirectoriesStub = nil if fake.fromDirectoriesReturnsOnCall == nil { fake.fromDirectoriesReturnsOnCall = make(map[int]struct { - result1 map[string]interface{} + result1 map[string]any result2 error }) } fake.fromDirectoriesReturnsOnCall[i] = struct { - result1 map[string]interface{} + result1 map[string]any result2 error }{result1, result2} } diff --git a/internal/commands/fakes/parse_metadata_templates.go b/internal/commands/fakes/parse_metadata_templates.go index 07374f53e..d32147dd9 100644 --- a/internal/commands/fakes/parse_metadata_templates.go +++ b/internal/commands/fakes/parse_metadata_templates.go @@ -6,25 +6,25 @@ import ( ) type MetadataTemplatesParser struct { - ParseMetadataTemplatesStub func([]string, map[string]interface{}) (map[string]interface{}, error) + ParseMetadataTemplatesStub func([]string, map[string]any) (map[string]any, error) parseMetadataTemplatesMutex sync.RWMutex parseMetadataTemplatesArgsForCall []struct { arg1 []string - arg2 map[string]interface{} + arg2 map[string]any } parseMetadataTemplatesReturns struct { - result1 map[string]interface{} + result1 map[string]any result2 error } parseMetadataTemplatesReturnsOnCall map[int]struct { - result1 map[string]interface{} + result1 map[string]any result2 error } invocations map[string][][]interface{} invocationsMutex sync.RWMutex } -func (fake *MetadataTemplatesParser) ParseMetadataTemplates(arg1 []string, arg2 map[string]interface{}) (map[string]interface{}, error) { +func (fake *MetadataTemplatesParser) ParseMetadataTemplates(arg1 []string, arg2 map[string]any) (map[string]any, error) { var arg1Copy []string if arg1 != nil { arg1Copy = make([]string, len(arg1)) @@ -34,7 +34,7 @@ func (fake *MetadataTemplatesParser) ParseMetadataTemplates(arg1 []string, arg2 ret, specificReturn := fake.parseMetadataTemplatesReturnsOnCall[len(fake.parseMetadataTemplatesArgsForCall)] fake.parseMetadataTemplatesArgsForCall = append(fake.parseMetadataTemplatesArgsForCall, struct { arg1 []string - arg2 map[string]interface{} + arg2 map[string]any }{arg1Copy, arg2}) stub := fake.ParseMetadataTemplatesStub fakeReturns := fake.parseMetadataTemplatesReturns @@ -55,41 +55,41 @@ func (fake *MetadataTemplatesParser) ParseMetadataTemplatesCallCount() int { return len(fake.parseMetadataTemplatesArgsForCall) } -func (fake *MetadataTemplatesParser) ParseMetadataTemplatesCalls(stub func([]string, map[string]interface{}) (map[string]interface{}, error)) { +func (fake *MetadataTemplatesParser) ParseMetadataTemplatesCalls(stub func([]string, map[string]any) (map[string]any, error)) { fake.parseMetadataTemplatesMutex.Lock() defer fake.parseMetadataTemplatesMutex.Unlock() fake.ParseMetadataTemplatesStub = stub } -func (fake *MetadataTemplatesParser) ParseMetadataTemplatesArgsForCall(i int) ([]string, map[string]interface{}) { +func (fake *MetadataTemplatesParser) ParseMetadataTemplatesArgsForCall(i int) ([]string, map[string]any) { fake.parseMetadataTemplatesMutex.RLock() defer fake.parseMetadataTemplatesMutex.RUnlock() argsForCall := fake.parseMetadataTemplatesArgsForCall[i] return argsForCall.arg1, argsForCall.arg2 } -func (fake *MetadataTemplatesParser) ParseMetadataTemplatesReturns(result1 map[string]interface{}, result2 error) { +func (fake *MetadataTemplatesParser) ParseMetadataTemplatesReturns(result1 map[string]any, result2 error) { fake.parseMetadataTemplatesMutex.Lock() defer fake.parseMetadataTemplatesMutex.Unlock() fake.ParseMetadataTemplatesStub = nil fake.parseMetadataTemplatesReturns = struct { - result1 map[string]interface{} + result1 map[string]any result2 error }{result1, result2} } -func (fake *MetadataTemplatesParser) ParseMetadataTemplatesReturnsOnCall(i int, result1 map[string]interface{}, result2 error) { +func (fake *MetadataTemplatesParser) ParseMetadataTemplatesReturnsOnCall(i int, result1 map[string]any, result2 error) { fake.parseMetadataTemplatesMutex.Lock() defer fake.parseMetadataTemplatesMutex.Unlock() fake.ParseMetadataTemplatesStub = nil if fake.parseMetadataTemplatesReturnsOnCall == nil { fake.parseMetadataTemplatesReturnsOnCall = make(map[int]struct { - result1 map[string]interface{} + result1 map[string]any result2 error }) } fake.parseMetadataTemplatesReturnsOnCall[i] = struct { - result1 map[string]interface{} + result1 map[string]any result2 error }{result1, result2} } diff --git a/internal/commands/fakes/session_dialer.go b/internal/commands/fakes/session_dialer.go index 41d2c41a3..d085a405e 100644 --- a/internal/commands/fakes/session_dialer.go +++ b/internal/commands/fakes/session_dialer.go @@ -26,7 +26,7 @@ type SessionDialer struct { runReturnsOnCall map[int]struct { result1 error } - invocations map[string][][]interface{} + invocations map[string][][]any invocationsMutex sync.RWMutex } @@ -36,7 +36,7 @@ func (fake *SessionDialer) Allow(arg1 session.Attachable) { arg1 session.Attachable }{arg1}) stub := fake.AllowStub - fake.recordInvocation("Allow", []interface{}{arg1}) + fake.recordInvocation("Allow", []any{arg1}) fake.allowMutex.Unlock() if stub != nil { fake.AllowStub(arg1) @@ -71,7 +71,7 @@ func (fake *SessionDialer) Run(arg1 context.Context, arg2 session.Dialer) error }{arg1, arg2}) stub := fake.RunStub fakeReturns := fake.runReturns - fake.recordInvocation("Run", []interface{}{arg1, arg2}) + fake.recordInvocation("Run", []any{arg1, arg2}) fake.runMutex.Unlock() if stub != nil { return stub(arg1, arg2) @@ -124,28 +124,28 @@ func (fake *SessionDialer) RunReturnsOnCall(i int, result1 error) { }{result1} } -func (fake *SessionDialer) Invocations() map[string][][]interface{} { +func (fake *SessionDialer) Invocations() map[string][][]any { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() fake.allowMutex.RLock() defer fake.allowMutex.RUnlock() fake.runMutex.RLock() defer fake.runMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} + copiedInvocations := map[string][][]any{} for key, value := range fake.invocations { copiedInvocations[key] = value } return copiedInvocations } -func (fake *SessionDialer) recordInvocation(key string, args []interface{}) { +func (fake *SessionDialer) recordInvocation(key string, args []any) { fake.invocationsMutex.Lock() defer fake.invocationsMutex.Unlock() if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} + fake.invocations = map[string][][]any{} } if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} + fake.invocations[key] = [][]any{} } fake.invocations[key] = append(fake.invocations[key], args) } diff --git a/internal/commands/fakes/stemcell_service.go b/internal/commands/fakes/stemcell_service.go index 9634254d8..7aa4e4669 100644 --- a/internal/commands/fakes/stemcell_service.go +++ b/internal/commands/fakes/stemcell_service.go @@ -6,50 +6,50 @@ import ( ) type StemcellService struct { - FromDirectoriesStub func([]string) (map[string]interface{}, error) + FromDirectoriesStub func([]string) (map[string]any, error) fromDirectoriesMutex sync.RWMutex fromDirectoriesArgsForCall []struct { arg1 []string } fromDirectoriesReturns struct { - result1 map[string]interface{} + result1 map[string]any result2 error } fromDirectoriesReturnsOnCall map[int]struct { - result1 map[string]interface{} + result1 map[string]any result2 error } - FromKilnfileStub func(string) (map[string]interface{}, error) + FromKilnfileStub func(string) (map[string]any, error) fromKilnfileMutex sync.RWMutex fromKilnfileArgsForCall []struct { arg1 string } fromKilnfileReturns struct { - result1 map[string]interface{} + result1 map[string]any result2 error } fromKilnfileReturnsOnCall map[int]struct { - result1 map[string]interface{} + result1 map[string]any result2 error } - FromTarballStub func(string) (interface{}, error) + FromTarballStub func(string) (any, error) fromTarballMutex sync.RWMutex fromTarballArgsForCall []struct { arg1 string } fromTarballReturns struct { - result1 interface{} + result1 any result2 error } fromTarballReturnsOnCall map[int]struct { - result1 interface{} + result1 any result2 error } invocations map[string][][]interface{} invocationsMutex sync.RWMutex } -func (fake *StemcellService) FromDirectories(arg1 []string) (map[string]interface{}, error) { +func (fake *StemcellService) FromDirectories(arg1 []string) (map[string]any, error) { var arg1Copy []string if arg1 != nil { arg1Copy = make([]string, len(arg1)) @@ -79,7 +79,7 @@ func (fake *StemcellService) FromDirectoriesCallCount() int { return len(fake.fromDirectoriesArgsForCall) } -func (fake *StemcellService) FromDirectoriesCalls(stub func([]string) (map[string]interface{}, error)) { +func (fake *StemcellService) FromDirectoriesCalls(stub func([]string) (map[string]any, error)) { fake.fromDirectoriesMutex.Lock() defer fake.fromDirectoriesMutex.Unlock() fake.FromDirectoriesStub = stub @@ -92,33 +92,33 @@ func (fake *StemcellService) FromDirectoriesArgsForCall(i int) []string { return argsForCall.arg1 } -func (fake *StemcellService) FromDirectoriesReturns(result1 map[string]interface{}, result2 error) { +func (fake *StemcellService) FromDirectoriesReturns(result1 map[string]any, result2 error) { fake.fromDirectoriesMutex.Lock() defer fake.fromDirectoriesMutex.Unlock() fake.FromDirectoriesStub = nil fake.fromDirectoriesReturns = struct { - result1 map[string]interface{} + result1 map[string]any result2 error }{result1, result2} } -func (fake *StemcellService) FromDirectoriesReturnsOnCall(i int, result1 map[string]interface{}, result2 error) { +func (fake *StemcellService) FromDirectoriesReturnsOnCall(i int, result1 map[string]any, result2 error) { fake.fromDirectoriesMutex.Lock() defer fake.fromDirectoriesMutex.Unlock() fake.FromDirectoriesStub = nil if fake.fromDirectoriesReturnsOnCall == nil { fake.fromDirectoriesReturnsOnCall = make(map[int]struct { - result1 map[string]interface{} + result1 map[string]any result2 error }) } fake.fromDirectoriesReturnsOnCall[i] = struct { - result1 map[string]interface{} + result1 map[string]any result2 error }{result1, result2} } -func (fake *StemcellService) FromKilnfile(arg1 string) (map[string]interface{}, error) { +func (fake *StemcellService) FromKilnfile(arg1 string) (map[string]any, error) { fake.fromKilnfileMutex.Lock() ret, specificReturn := fake.fromKilnfileReturnsOnCall[len(fake.fromKilnfileArgsForCall)] fake.fromKilnfileArgsForCall = append(fake.fromKilnfileArgsForCall, struct { @@ -143,7 +143,7 @@ func (fake *StemcellService) FromKilnfileCallCount() int { return len(fake.fromKilnfileArgsForCall) } -func (fake *StemcellService) FromKilnfileCalls(stub func(string) (map[string]interface{}, error)) { +func (fake *StemcellService) FromKilnfileCalls(stub func(string) (map[string]any, error)) { fake.fromKilnfileMutex.Lock() defer fake.fromKilnfileMutex.Unlock() fake.FromKilnfileStub = stub @@ -156,33 +156,33 @@ func (fake *StemcellService) FromKilnfileArgsForCall(i int) string { return argsForCall.arg1 } -func (fake *StemcellService) FromKilnfileReturns(result1 map[string]interface{}, result2 error) { +func (fake *StemcellService) FromKilnfileReturns(result1 map[string]any, result2 error) { fake.fromKilnfileMutex.Lock() defer fake.fromKilnfileMutex.Unlock() fake.FromKilnfileStub = nil fake.fromKilnfileReturns = struct { - result1 map[string]interface{} + result1 map[string]any result2 error }{result1, result2} } -func (fake *StemcellService) FromKilnfileReturnsOnCall(i int, result1 map[string]interface{}, result2 error) { +func (fake *StemcellService) FromKilnfileReturnsOnCall(i int, result1 map[string]any, result2 error) { fake.fromKilnfileMutex.Lock() defer fake.fromKilnfileMutex.Unlock() fake.FromKilnfileStub = nil if fake.fromKilnfileReturnsOnCall == nil { fake.fromKilnfileReturnsOnCall = make(map[int]struct { - result1 map[string]interface{} + result1 map[string]any result2 error }) } fake.fromKilnfileReturnsOnCall[i] = struct { - result1 map[string]interface{} + result1 map[string]any result2 error }{result1, result2} } -func (fake *StemcellService) FromTarball(arg1 string) (interface{}, error) { +func (fake *StemcellService) FromTarball(arg1 string) (any, error) { fake.fromTarballMutex.Lock() ret, specificReturn := fake.fromTarballReturnsOnCall[len(fake.fromTarballArgsForCall)] fake.fromTarballArgsForCall = append(fake.fromTarballArgsForCall, struct { @@ -207,7 +207,7 @@ func (fake *StemcellService) FromTarballCallCount() int { return len(fake.fromTarballArgsForCall) } -func (fake *StemcellService) FromTarballCalls(stub func(string) (interface{}, error)) { +func (fake *StemcellService) FromTarballCalls(stub func(string) (any, error)) { fake.fromTarballMutex.Lock() defer fake.fromTarballMutex.Unlock() fake.FromTarballStub = stub @@ -220,28 +220,28 @@ func (fake *StemcellService) FromTarballArgsForCall(i int) string { return argsForCall.arg1 } -func (fake *StemcellService) FromTarballReturns(result1 interface{}, result2 error) { +func (fake *StemcellService) FromTarballReturns(result1 any, result2 error) { fake.fromTarballMutex.Lock() defer fake.fromTarballMutex.Unlock() fake.FromTarballStub = nil fake.fromTarballReturns = struct { - result1 interface{} + result1 any result2 error }{result1, result2} } -func (fake *StemcellService) FromTarballReturnsOnCall(i int, result1 interface{}, result2 error) { +func (fake *StemcellService) FromTarballReturnsOnCall(i int, result1 any, result2 error) { fake.fromTarballMutex.Lock() defer fake.fromTarballMutex.Unlock() fake.FromTarballStub = nil if fake.fromTarballReturnsOnCall == nil { fake.fromTarballReturnsOnCall = make(map[int]struct { - result1 interface{} + result1 any result2 error }) } fake.fromTarballReturnsOnCall[i] = struct { - result1 interface{} + result1 any result2 error }{result1, result2} } diff --git a/internal/commands/fakes/template_variables_service.go b/internal/commands/fakes/template_variables_service.go index 49bf03827..087ce59ac 100644 --- a/internal/commands/fakes/template_variables_service.go +++ b/internal/commands/fakes/template_variables_service.go @@ -6,25 +6,25 @@ import ( ) type TemplateVariablesService struct { - FromPathsAndPairsStub func([]string, []string) (map[string]interface{}, error) + FromPathsAndPairsStub func([]string, []string) (map[string]any, error) fromPathsAndPairsMutex sync.RWMutex fromPathsAndPairsArgsForCall []struct { arg1 []string arg2 []string } fromPathsAndPairsReturns struct { - result1 map[string]interface{} + result1 map[string]any result2 error } fromPathsAndPairsReturnsOnCall map[int]struct { - result1 map[string]interface{} + result1 map[string]any result2 error } invocations map[string][][]interface{} invocationsMutex sync.RWMutex } -func (fake *TemplateVariablesService) FromPathsAndPairs(arg1 []string, arg2 []string) (map[string]interface{}, error) { +func (fake *TemplateVariablesService) FromPathsAndPairs(arg1 []string, arg2 []string) (map[string]any, error) { var arg1Copy []string if arg1 != nil { arg1Copy = make([]string, len(arg1)) @@ -60,7 +60,7 @@ func (fake *TemplateVariablesService) FromPathsAndPairsCallCount() int { return len(fake.fromPathsAndPairsArgsForCall) } -func (fake *TemplateVariablesService) FromPathsAndPairsCalls(stub func([]string, []string) (map[string]interface{}, error)) { +func (fake *TemplateVariablesService) FromPathsAndPairsCalls(stub func([]string, []string) (map[string]any, error)) { fake.fromPathsAndPairsMutex.Lock() defer fake.fromPathsAndPairsMutex.Unlock() fake.FromPathsAndPairsStub = stub @@ -73,28 +73,28 @@ func (fake *TemplateVariablesService) FromPathsAndPairsArgsForCall(i int) ([]str return argsForCall.arg1, argsForCall.arg2 } -func (fake *TemplateVariablesService) FromPathsAndPairsReturns(result1 map[string]interface{}, result2 error) { +func (fake *TemplateVariablesService) FromPathsAndPairsReturns(result1 map[string]any, result2 error) { fake.fromPathsAndPairsMutex.Lock() defer fake.fromPathsAndPairsMutex.Unlock() fake.FromPathsAndPairsStub = nil fake.fromPathsAndPairsReturns = struct { - result1 map[string]interface{} + result1 map[string]any result2 error }{result1, result2} } -func (fake *TemplateVariablesService) FromPathsAndPairsReturnsOnCall(i int, result1 map[string]interface{}, result2 error) { +func (fake *TemplateVariablesService) FromPathsAndPairsReturnsOnCall(i int, result1 map[string]any, result2 error) { fake.fromPathsAndPairsMutex.Lock() defer fake.fromPathsAndPairsMutex.Unlock() fake.FromPathsAndPairsStub = nil if fake.fromPathsAndPairsReturnsOnCall == nil { fake.fromPathsAndPairsReturnsOnCall = make(map[int]struct { - result1 map[string]interface{} + result1 map[string]any result2 error }) } fake.fromPathsAndPairsReturnsOnCall[i] = struct { - result1 map[string]interface{} + result1 map[string]any result2 error }{result1, result2} } diff --git a/internal/commands/flags/parse.go b/internal/commands/flags/parse.go index b4ce7054b..5e088ebd2 100644 --- a/internal/commands/flags/parse.go +++ b/internal/commands/flags/parse.go @@ -32,7 +32,7 @@ type ( } VariablesService interface { - FromPathsAndPairs(paths []string, pairs []string) (templateVariables map[string]interface{}, err error) + FromPathsAndPairs(paths []string, pairs []string) (templateVariables map[string]any, err error) } ) diff --git a/internal/commands/generate_osm_manifest_test.go b/internal/commands/generate_osm_manifest_test.go index e978da639..7852f73d2 100644 --- a/internal/commands/generate_osm_manifest_test.go +++ b/internal/commands/generate_osm_manifest_test.go @@ -334,7 +334,7 @@ func TestOSM_Execute(t *testing.T) { }) } -func writeYAML(t *testing.T, path string, data interface{}) { +func writeYAML(t *testing.T, path string, data any) { t.Helper() buf, err := yaml.Marshal(data) if err != nil { diff --git a/internal/commands/glaze_test.go b/internal/commands/glaze_test.go index 1f9997dc6..615e98296 100644 --- a/internal/commands/glaze_test.go +++ b/internal/commands/glaze_test.go @@ -187,7 +187,7 @@ func TestGlaze_Execute(t *testing.T) { }) } -func writeYAML(t *testing.T, path string, data interface{}) { +func writeYAML(t *testing.T, path string, data any) { t.Helper() buf, err := yaml.Marshal(data) if err != nil { @@ -206,7 +206,7 @@ func writeYAML(t *testing.T, path string, data interface{}) { } } -func readYAML(t *testing.T, path string, data interface{}) { +func readYAML(t *testing.T, path string, data any) { t.Helper() buf, err := os.ReadFile(path) diff --git a/internal/commands/init_test.go b/internal/commands/init_test.go index 8bdb5fcf0..0d0808000 100644 --- a/internal/commands/init_test.go +++ b/internal/commands/init_test.go @@ -26,7 +26,7 @@ type command interface { var _ command -func fsWriteYAML(fs billy.Basic, path string, data interface{}) error { +func fsWriteYAML(fs billy.Basic, path string, data any) error { buf, err := yaml.Marshal(data) if err != nil { return err @@ -42,7 +42,7 @@ func fsWriteYAML(fs billy.Basic, path string, data interface{}) error { return err } -func fsReadYAML(fs billy.Basic, path string, data interface{}) error { +func fsReadYAML(fs billy.Basic, path string, data any) error { f, err := fs.Open(path) if err != nil { return nil diff --git a/internal/commands/test_tile_test.go b/internal/commands/test_tile_test.go index f6fc0075c..d5630f746 100644 --- a/internal/commands/test_tile_test.go +++ b/internal/commands/test_tile_test.go @@ -383,7 +383,7 @@ type testingT interface { Helper() Cleanup(func()) TempDir() string - Fatal(args ...interface{}) + Fatal(args ...any) Name() string } diff --git a/internal/commands/update_stemcell_test.go b/internal/commands/update_stemcell_test.go index 612b6859e..c2ab0df43 100644 --- a/internal/commands/update_stemcell_test.go +++ b/internal/commands/update_stemcell_test.go @@ -430,7 +430,7 @@ var _ = Describe("UpdateStemcell", func() { }) }) -func createYAMLFile(fs billy.Filesystem, fp string, data interface{}) error { +func createYAMLFile(fs billy.Filesystem, fp string, data any) error { f, err := fs.Create(fp) if err != nil { return err diff --git a/internal/component/fakes/release_asset_downloader.go b/internal/component/fakes/release_asset_downloader.go index 1767f53b3..34f9f9bc6 100644 --- a/internal/component/fakes/release_asset_downloader.go +++ b/internal/component/fakes/release_asset_downloader.go @@ -30,7 +30,7 @@ type ReleaseAssetDownloader struct { result2 string result3 error } - invocations map[string][][]interface{} + invocations map[string][][]any invocationsMutex sync.RWMutex } @@ -46,7 +46,7 @@ func (fake *ReleaseAssetDownloader) DownloadReleaseAsset(arg1 context.Context, a }{arg1, arg2, arg3, arg4, arg5}) stub := fake.DownloadReleaseAssetStub fakeReturns := fake.downloadReleaseAssetReturns - fake.recordInvocation("DownloadReleaseAsset", []interface{}{arg1, arg2, arg3, arg4, arg5}) + fake.recordInvocation("DownloadReleaseAsset", []any{arg1, arg2, arg3, arg4, arg5}) fake.downloadReleaseAssetMutex.Unlock() if stub != nil { return stub(arg1, arg2, arg3, arg4, arg5) @@ -105,26 +105,26 @@ func (fake *ReleaseAssetDownloader) DownloadReleaseAssetReturnsOnCall(i int, res }{result1, result2, result3} } -func (fake *ReleaseAssetDownloader) Invocations() map[string][][]interface{} { +func (fake *ReleaseAssetDownloader) Invocations() map[string][][]any { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() fake.downloadReleaseAssetMutex.RLock() defer fake.downloadReleaseAssetMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} + copiedInvocations := map[string][][]any{} for key, value := range fake.invocations { copiedInvocations[key] = value } return copiedInvocations } -func (fake *ReleaseAssetDownloader) recordInvocation(key string, args []interface{}) { +func (fake *ReleaseAssetDownloader) recordInvocation(key string, args []any) { fake.invocationsMutex.Lock() defer fake.invocationsMutex.Unlock() if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} + fake.invocations = map[string][][]any{} } if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} + fake.invocations[key] = [][]any{} } fake.invocations[key] = append(fake.invocations[key], args) } diff --git a/internal/component/fakes_internal/release_by_tag_getter_asset_downloader.go b/internal/component/fakes_internal/release_by_tag_getter_asset_downloader.go index fade2ea64..b23c72c42 100644 --- a/internal/component/fakes_internal/release_by_tag_getter_asset_downloader.go +++ b/internal/component/fakes_internal/release_by_tag_getter_asset_downloader.go @@ -48,7 +48,7 @@ type ReleaseByTagGetterAssetDownloader struct { result2 *github.Response result3 error } - invocations map[string][][]interface{} + invocations map[string][][]any invocationsMutex sync.RWMutex } @@ -64,7 +64,7 @@ func (fake *ReleaseByTagGetterAssetDownloader) DownloadReleaseAsset(arg1 context }{arg1, arg2, arg3, arg4, arg5}) stub := fake.DownloadReleaseAssetStub fakeReturns := fake.downloadReleaseAssetReturns - fake.recordInvocation("DownloadReleaseAsset", []interface{}{arg1, arg2, arg3, arg4, arg5}) + fake.recordInvocation("DownloadReleaseAsset", []any{arg1, arg2, arg3, arg4, arg5}) fake.downloadReleaseAssetMutex.Unlock() if stub != nil { return stub(arg1, arg2, arg3, arg4, arg5) @@ -134,7 +134,7 @@ func (fake *ReleaseByTagGetterAssetDownloader) GetReleaseByTag(arg1 context.Cont }{arg1, arg2, arg3, arg4}) stub := fake.GetReleaseByTagStub fakeReturns := fake.getReleaseByTagReturns - fake.recordInvocation("GetReleaseByTag", []interface{}{arg1, arg2, arg3, arg4}) + fake.recordInvocation("GetReleaseByTag", []any{arg1, arg2, arg3, arg4}) fake.getReleaseByTagMutex.Unlock() if stub != nil { return stub(arg1, arg2, arg3, arg4) @@ -193,28 +193,28 @@ func (fake *ReleaseByTagGetterAssetDownloader) GetReleaseByTagReturnsOnCall(i in }{result1, result2, result3} } -func (fake *ReleaseByTagGetterAssetDownloader) Invocations() map[string][][]interface{} { +func (fake *ReleaseByTagGetterAssetDownloader) Invocations() map[string][][]any { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() fake.downloadReleaseAssetMutex.RLock() defer fake.downloadReleaseAssetMutex.RUnlock() fake.getReleaseByTagMutex.RLock() defer fake.getReleaseByTagMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} + copiedInvocations := map[string][][]any{} for key, value := range fake.invocations { copiedInvocations[key] = value } return copiedInvocations } -func (fake *ReleaseByTagGetterAssetDownloader) recordInvocation(key string, args []interface{}) { +func (fake *ReleaseByTagGetterAssetDownloader) recordInvocation(key string, args []any) { fake.invocationsMutex.Lock() defer fake.invocationsMutex.Unlock() if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} + fake.invocations = map[string][][]any{} } if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} + fake.invocations[key] = [][]any{} } fake.invocations[key] = append(fake.invocations[key], args) } diff --git a/internal/component/fakes_internal/repository_release_lister.go b/internal/component/fakes_internal/repository_release_lister.go index 978856fd3..042e3b89c 100644 --- a/internal/component/fakes_internal/repository_release_lister.go +++ b/internal/component/fakes_internal/repository_release_lister.go @@ -27,7 +27,7 @@ type RepositoryReleaseLister struct { result2 *github.Response result3 error } - invocations map[string][][]interface{} + invocations map[string][][]any invocationsMutex sync.RWMutex } @@ -42,7 +42,7 @@ func (fake *RepositoryReleaseLister) ListReleases(arg1 context.Context, arg2 str }{arg1, arg2, arg3, arg4}) stub := fake.ListReleasesStub fakeReturns := fake.listReleasesReturns - fake.recordInvocation("ListReleases", []interface{}{arg1, arg2, arg3, arg4}) + fake.recordInvocation("ListReleases", []any{arg1, arg2, arg3, arg4}) fake.listReleasesMutex.Unlock() if stub != nil { return stub(arg1, arg2, arg3, arg4) @@ -101,26 +101,26 @@ func (fake *RepositoryReleaseLister) ListReleasesReturnsOnCall(i int, result1 [] }{result1, result2, result3} } -func (fake *RepositoryReleaseLister) Invocations() map[string][][]interface{} { +func (fake *RepositoryReleaseLister) Invocations() map[string][][]any { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() fake.listReleasesMutex.RLock() defer fake.listReleasesMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} + copiedInvocations := map[string][][]any{} for key, value := range fake.invocations { copiedInvocations[key] = value } return copiedInvocations } -func (fake *RepositoryReleaseLister) recordInvocation(key string, args []interface{}) { +func (fake *RepositoryReleaseLister) recordInvocation(key string, args []any) { fake.invocationsMutex.Lock() defer fake.invocationsMutex.Unlock() if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} + fake.invocations = map[string][][]any{} } if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} + fake.invocations[key] = [][]any{} } fake.invocations[key] = append(fake.invocations[key], args) } diff --git a/internal/component/release_source_test.go b/internal/component/release_source_test.go index bfa8828b7..caba16a6a 100644 --- a/internal/component/release_source_test.go +++ b/internal/component/release_source_test.go @@ -116,7 +116,7 @@ var _ = Describe("ReleaseSourceList", func() { }) It("panics with a helpful message", func() { - var r interface{} + var r any func() { defer func() { r = recover() diff --git a/internal/component/s3_release_source_test.go b/internal/component/s3_release_source_test.go index e2c259939..c5e03c4ee 100644 --- a/internal/component/s3_release_source_test.go +++ b/internal/component/s3_release_source_test.go @@ -60,7 +60,7 @@ var _ = Describe("S3ReleaseSource", func() { DescribeTable("bad config", func(before func(sourceConfig *cargo.ReleaseSourceConfig), expectedSubstring string) { before(config) - var r interface{} + var r any func() { defer func() { r = recover() diff --git a/pkg/cargo/files.go b/pkg/cargo/files.go index 97473f2ab..80f753930 100644 --- a/pkg/cargo/files.go +++ b/pkg/cargo/files.go @@ -14,7 +14,7 @@ import ( "gopkg.in/yaml.v3" ) -func InterpolateAndParseKilnfile(in io.Reader, templateVariables map[string]interface{}) (Kilnfile, error) { +func InterpolateAndParseKilnfile(in io.Reader, templateVariables map[string]any) (Kilnfile, error) { kilnfileYAML, err := io.ReadAll(in) if err != nil { return Kilnfile{}, fmt.Errorf("unable to read Kilnfile: %w", err) diff --git a/pkg/cargo/files_test.go b/pkg/cargo/files_test.go index 1d323d6b7..f0f1c63ad 100644 --- a/pkg/cargo/files_test.go +++ b/pkg/cargo/files_test.go @@ -18,7 +18,7 @@ import ( func TestInterpolateAndParseKilnfile(t *testing.T) { please := NewWithT(t) - variables := map[string]interface{}{ + variables := map[string]any{ "bucket": "my-bucket", "region": "middle-earth", "path_template": "not-used", @@ -68,7 +68,7 @@ release_sources: path_template: $( variable "path_template" ) ` - variables := map[string]interface{}{ + variables := map[string]any{ "bucket": "my-bucket", "region": "middle-earth", "path_template": "not-used", @@ -108,7 +108,7 @@ release_sources: func TestInterpolateAndParseKilnfile_input_is_not_valid_yaml(t *testing.T) { please := NewWithT(t) - variables := map[string]interface{}{ + variables := map[string]any{ "bucket": "my-bucket", "region": "middle-earth", "path_template": "not-used", @@ -127,7 +127,7 @@ func TestInterpolateAndParseKilnfile_input_is_not_valid_yaml(t *testing.T) { func TestInterpolateAndParseKilnfile_interpolation_variable_not_found(t *testing.T) { please := NewWithT(t) - variables := map[string]interface{}{ + variables := map[string]any{ "bucket": "my-bucket", // "region": "middle-earth", // <- the missing variable "path_template": "not-used", diff --git a/pkg/history/decode.go b/pkg/history/decode.go index 544eeb8b3..9897b15f5 100644 --- a/pkg/history/decode.go +++ b/pkg/history/decode.go @@ -11,7 +11,7 @@ import ( "gopkg.in/yaml.v2" ) -func unmarshalFile(storage storer.EncodedObjectStorer, commitHash plumbing.Hash, data interface{}, filePath string) error { +func unmarshalFile(storage storer.EncodedObjectStorer, commitHash plumbing.Hash, data any, filePath string) error { buf, err := fileAtCommit(storage, commitHash, filePath) if err != nil { return err @@ -19,7 +19,7 @@ func unmarshalFile(storage storer.EncodedObjectStorer, commitHash plumbing.Hash, return decodeFile(buf, filePath, data) } -//func readDataFromTree(tree *object.Tree, data interface{}, names []string) error { +//func readDataFromTree(tree *object.Tree, data any, names []string) error { // buf, fileName, err := readBytesFromTree(tree, names) // if err != nil { // return err @@ -27,7 +27,7 @@ func unmarshalFile(storage storer.EncodedObjectStorer, commitHash plumbing.Hash, // return decodeFile(buf, fileName, data) //} -func decodeFile(buf []byte, fileName string, data interface{}) error { +func decodeFile(buf []byte, fileName string, data any) error { if filepath.Base(fileName) == "Kilnfile" { return yaml.Unmarshal(buf, data) } diff --git a/pkg/notes/fakes/historic_kilnfile.go b/pkg/notes/fakes/historic_kilnfile.go new file mode 100644 index 000000000..8a05a0452 --- /dev/null +++ b/pkg/notes/fakes/historic_kilnfile.go @@ -0,0 +1,124 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package fakes + +import ( + "sync" + + "github.com/go-git/go-git/v5/plumbing" + "github.com/go-git/go-git/v5/plumbing/storer" + "github.com/pivotal-cf/kiln/pkg/cargo" +) + +type HistoricKilnfile struct { + Stub func(storer.EncodedObjectStorer, plumbing.Hash, string) (cargo.Kilnfile, cargo.KilnfileLock, error) + mutex sync.RWMutex + argsForCall []struct { + arg1 storer.EncodedObjectStorer + arg2 plumbing.Hash + arg3 string + } + returns struct { + result1 cargo.Kilnfile + result2 cargo.KilnfileLock + result3 error + } + returnsOnCall map[int]struct { + result1 cargo.Kilnfile + result2 cargo.KilnfileLock + result3 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *HistoricKilnfile) Spy(arg1 storer.EncodedObjectStorer, arg2 plumbing.Hash, arg3 string) (cargo.Kilnfile, cargo.KilnfileLock, error) { + fake.mutex.Lock() + ret, specificReturn := fake.returnsOnCall[len(fake.argsForCall)] + fake.argsForCall = append(fake.argsForCall, struct { + arg1 storer.EncodedObjectStorer + arg2 plumbing.Hash + arg3 string + }{arg1, arg2, arg3}) + stub := fake.Stub + returns := fake.returns + fake.recordInvocation("historicKilnfile", []interface{}{arg1, arg2, arg3}) + fake.mutex.Unlock() + if stub != nil { + return stub(arg1, arg2, arg3) + } + if specificReturn { + return ret.result1, ret.result2, ret.result3 + } + return returns.result1, returns.result2, returns.result3 +} + +func (fake *HistoricKilnfile) CallCount() int { + fake.mutex.RLock() + defer fake.mutex.RUnlock() + return len(fake.argsForCall) +} + +func (fake *HistoricKilnfile) Calls(stub func(storer.EncodedObjectStorer, plumbing.Hash, string) (cargo.Kilnfile, cargo.KilnfileLock, error)) { + fake.mutex.Lock() + defer fake.mutex.Unlock() + fake.Stub = stub +} + +func (fake *HistoricKilnfile) ArgsForCall(i int) (storer.EncodedObjectStorer, plumbing.Hash, string) { + fake.mutex.RLock() + defer fake.mutex.RUnlock() + return fake.argsForCall[i].arg1, fake.argsForCall[i].arg2, fake.argsForCall[i].arg3 +} + +func (fake *HistoricKilnfile) Returns(result1 cargo.Kilnfile, result2 cargo.KilnfileLock, result3 error) { + fake.mutex.Lock() + defer fake.mutex.Unlock() + fake.Stub = nil + fake.returns = struct { + result1 cargo.Kilnfile + result2 cargo.KilnfileLock + result3 error + }{result1, result2, result3} +} + +func (fake *HistoricKilnfile) ReturnsOnCall(i int, result1 cargo.Kilnfile, result2 cargo.KilnfileLock, result3 error) { + fake.mutex.Lock() + defer fake.mutex.Unlock() + fake.Stub = nil + if fake.returnsOnCall == nil { + fake.returnsOnCall = make(map[int]struct { + result1 cargo.Kilnfile + result2 cargo.KilnfileLock + result3 error + }) + } + fake.returnsOnCall[i] = struct { + result1 cargo.Kilnfile + result2 cargo.KilnfileLock + result3 error + }{result1, result2, result3} +} + +func (fake *HistoricKilnfile) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.mutex.RLock() + defer fake.mutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *HistoricKilnfile) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} diff --git a/pkg/notes/fakes/historic_version.go b/pkg/notes/fakes/historic_version.go new file mode 100644 index 000000000..b3d47fb2e --- /dev/null +++ b/pkg/notes/fakes/historic_version.go @@ -0,0 +1,118 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package fakes + +import ( + "sync" + + "github.com/go-git/go-git/v5/plumbing" + "github.com/go-git/go-git/v5/plumbing/storer" +) + +type HistoricVersion struct { + Stub func(storer.EncodedObjectStorer, plumbing.Hash, string) (string, error) + mutex sync.RWMutex + argsForCall []struct { + arg1 storer.EncodedObjectStorer + arg2 plumbing.Hash + arg3 string + } + returns struct { + result1 string + result2 error + } + returnsOnCall map[int]struct { + result1 string + result2 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *HistoricVersion) Spy(arg1 storer.EncodedObjectStorer, arg2 plumbing.Hash, arg3 string) (string, error) { + fake.mutex.Lock() + ret, specificReturn := fake.returnsOnCall[len(fake.argsForCall)] + fake.argsForCall = append(fake.argsForCall, struct { + arg1 storer.EncodedObjectStorer + arg2 plumbing.Hash + arg3 string + }{arg1, arg2, arg3}) + stub := fake.Stub + returns := fake.returns + fake.recordInvocation("historicVersion", []interface{}{arg1, arg2, arg3}) + fake.mutex.Unlock() + if stub != nil { + return stub(arg1, arg2, arg3) + } + if specificReturn { + return ret.result1, ret.result2 + } + return returns.result1, returns.result2 +} + +func (fake *HistoricVersion) CallCount() int { + fake.mutex.RLock() + defer fake.mutex.RUnlock() + return len(fake.argsForCall) +} + +func (fake *HistoricVersion) Calls(stub func(storer.EncodedObjectStorer, plumbing.Hash, string) (string, error)) { + fake.mutex.Lock() + defer fake.mutex.Unlock() + fake.Stub = stub +} + +func (fake *HistoricVersion) ArgsForCall(i int) (storer.EncodedObjectStorer, plumbing.Hash, string) { + fake.mutex.RLock() + defer fake.mutex.RUnlock() + return fake.argsForCall[i].arg1, fake.argsForCall[i].arg2, fake.argsForCall[i].arg3 +} + +func (fake *HistoricVersion) Returns(result1 string, result2 error) { + fake.mutex.Lock() + defer fake.mutex.Unlock() + fake.Stub = nil + fake.returns = struct { + result1 string + result2 error + }{result1, result2} +} + +func (fake *HistoricVersion) ReturnsOnCall(i int, result1 string, result2 error) { + fake.mutex.Lock() + defer fake.mutex.Unlock() + fake.Stub = nil + if fake.returnsOnCall == nil { + fake.returnsOnCall = make(map[int]struct { + result1 string + result2 error + }) + } + fake.returnsOnCall[i] = struct { + result1 string + result2 error + }{result1, result2} +} + +func (fake *HistoricVersion) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.mutex.RLock() + defer fake.mutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *HistoricVersion) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} diff --git a/pkg/notes/fakes/issue_getter.go b/pkg/notes/fakes/issue_getter.go new file mode 100644 index 000000000..3dbaa90cc --- /dev/null +++ b/pkg/notes/fakes/issue_getter.go @@ -0,0 +1,126 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package fakes + +import ( + "context" + "sync" + + "github.com/google/go-github/v40/github" +) + +type IssueGetter struct { + GetStub func(context.Context, string, string, int) (*github.Issue, *github.Response, error) + getMutex sync.RWMutex + getArgsForCall []struct { + arg1 context.Context + arg2 string + arg3 string + arg4 int + } + getReturns struct { + result1 *github.Issue + result2 *github.Response + result3 error + } + getReturnsOnCall map[int]struct { + result1 *github.Issue + result2 *github.Response + result3 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *IssueGetter) Get(arg1 context.Context, arg2 string, arg3 string, arg4 int) (*github.Issue, *github.Response, error) { + fake.getMutex.Lock() + ret, specificReturn := fake.getReturnsOnCall[len(fake.getArgsForCall)] + fake.getArgsForCall = append(fake.getArgsForCall, struct { + arg1 context.Context + arg2 string + arg3 string + arg4 int + }{arg1, arg2, arg3, arg4}) + stub := fake.GetStub + fakeReturns := fake.getReturns + fake.recordInvocation("Get", []interface{}{arg1, arg2, arg3, arg4}) + fake.getMutex.Unlock() + if stub != nil { + return stub(arg1, arg2, arg3, arg4) + } + if specificReturn { + return ret.result1, ret.result2, ret.result3 + } + return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 +} + +func (fake *IssueGetter) GetCallCount() int { + fake.getMutex.RLock() + defer fake.getMutex.RUnlock() + return len(fake.getArgsForCall) +} + +func (fake *IssueGetter) GetCalls(stub func(context.Context, string, string, int) (*github.Issue, *github.Response, error)) { + fake.getMutex.Lock() + defer fake.getMutex.Unlock() + fake.GetStub = stub +} + +func (fake *IssueGetter) GetArgsForCall(i int) (context.Context, string, string, int) { + fake.getMutex.RLock() + defer fake.getMutex.RUnlock() + argsForCall := fake.getArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 +} + +func (fake *IssueGetter) GetReturns(result1 *github.Issue, result2 *github.Response, result3 error) { + fake.getMutex.Lock() + defer fake.getMutex.Unlock() + fake.GetStub = nil + fake.getReturns = struct { + result1 *github.Issue + result2 *github.Response + result3 error + }{result1, result2, result3} +} + +func (fake *IssueGetter) GetReturnsOnCall(i int, result1 *github.Issue, result2 *github.Response, result3 error) { + fake.getMutex.Lock() + defer fake.getMutex.Unlock() + fake.GetStub = nil + if fake.getReturnsOnCall == nil { + fake.getReturnsOnCall = make(map[int]struct { + result1 *github.Issue + result2 *github.Response + result3 error + }) + } + fake.getReturnsOnCall[i] = struct { + result1 *github.Issue + result2 *github.Response + result3 error + }{result1, result2, result3} +} + +func (fake *IssueGetter) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.getMutex.RLock() + defer fake.getMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *IssueGetter) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} diff --git a/pkg/notes/fakes/issues_by_repo_lister.go b/pkg/notes/fakes/issues_by_repo_lister.go new file mode 100644 index 000000000..f63c2368d --- /dev/null +++ b/pkg/notes/fakes/issues_by_repo_lister.go @@ -0,0 +1,126 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package fakes + +import ( + "context" + "sync" + + "github.com/google/go-github/v40/github" +) + +type IssuesByRepoLister struct { + ListByRepoStub func(context.Context, string, string, *github.IssueListByRepoOptions) ([]*github.Issue, *github.Response, error) + listByRepoMutex sync.RWMutex + listByRepoArgsForCall []struct { + arg1 context.Context + arg2 string + arg3 string + arg4 *github.IssueListByRepoOptions + } + listByRepoReturns struct { + result1 []*github.Issue + result2 *github.Response + result3 error + } + listByRepoReturnsOnCall map[int]struct { + result1 []*github.Issue + result2 *github.Response + result3 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *IssuesByRepoLister) ListByRepo(arg1 context.Context, arg2 string, arg3 string, arg4 *github.IssueListByRepoOptions) ([]*github.Issue, *github.Response, error) { + fake.listByRepoMutex.Lock() + ret, specificReturn := fake.listByRepoReturnsOnCall[len(fake.listByRepoArgsForCall)] + fake.listByRepoArgsForCall = append(fake.listByRepoArgsForCall, struct { + arg1 context.Context + arg2 string + arg3 string + arg4 *github.IssueListByRepoOptions + }{arg1, arg2, arg3, arg4}) + stub := fake.ListByRepoStub + fakeReturns := fake.listByRepoReturns + fake.recordInvocation("ListByRepo", []interface{}{arg1, arg2, arg3, arg4}) + fake.listByRepoMutex.Unlock() + if stub != nil { + return stub(arg1, arg2, arg3, arg4) + } + if specificReturn { + return ret.result1, ret.result2, ret.result3 + } + return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 +} + +func (fake *IssuesByRepoLister) ListByRepoCallCount() int { + fake.listByRepoMutex.RLock() + defer fake.listByRepoMutex.RUnlock() + return len(fake.listByRepoArgsForCall) +} + +func (fake *IssuesByRepoLister) ListByRepoCalls(stub func(context.Context, string, string, *github.IssueListByRepoOptions) ([]*github.Issue, *github.Response, error)) { + fake.listByRepoMutex.Lock() + defer fake.listByRepoMutex.Unlock() + fake.ListByRepoStub = stub +} + +func (fake *IssuesByRepoLister) ListByRepoArgsForCall(i int) (context.Context, string, string, *github.IssueListByRepoOptions) { + fake.listByRepoMutex.RLock() + defer fake.listByRepoMutex.RUnlock() + argsForCall := fake.listByRepoArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 +} + +func (fake *IssuesByRepoLister) ListByRepoReturns(result1 []*github.Issue, result2 *github.Response, result3 error) { + fake.listByRepoMutex.Lock() + defer fake.listByRepoMutex.Unlock() + fake.ListByRepoStub = nil + fake.listByRepoReturns = struct { + result1 []*github.Issue + result2 *github.Response + result3 error + }{result1, result2, result3} +} + +func (fake *IssuesByRepoLister) ListByRepoReturnsOnCall(i int, result1 []*github.Issue, result2 *github.Response, result3 error) { + fake.listByRepoMutex.Lock() + defer fake.listByRepoMutex.Unlock() + fake.ListByRepoStub = nil + if fake.listByRepoReturnsOnCall == nil { + fake.listByRepoReturnsOnCall = make(map[int]struct { + result1 []*github.Issue + result2 *github.Response + result3 error + }) + } + fake.listByRepoReturnsOnCall[i] = struct { + result1 []*github.Issue + result2 *github.Response + result3 error + }{result1, result2, result3} +} + +func (fake *IssuesByRepoLister) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.listByRepoMutex.RLock() + defer fake.listByRepoMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *IssuesByRepoLister) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} diff --git a/pkg/notes/fakes/issues_service.go b/pkg/notes/fakes/issues_service.go new file mode 100644 index 000000000..fb4af88f0 --- /dev/null +++ b/pkg/notes/fakes/issues_service.go @@ -0,0 +1,306 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package fakes + +import ( + "context" + "sync" + + "github.com/google/go-github/v40/github" +) + +type IssuesService struct { + GetStub func(context.Context, string, string, int) (*github.Issue, *github.Response, error) + getMutex sync.RWMutex + getArgsForCall []struct { + arg1 context.Context + arg2 string + arg3 string + arg4 int + } + getReturns struct { + result1 *github.Issue + result2 *github.Response + result3 error + } + getReturnsOnCall map[int]struct { + result1 *github.Issue + result2 *github.Response + result3 error + } + ListByRepoStub func(context.Context, string, string, *github.IssueListByRepoOptions) ([]*github.Issue, *github.Response, error) + listByRepoMutex sync.RWMutex + listByRepoArgsForCall []struct { + arg1 context.Context + arg2 string + arg3 string + arg4 *github.IssueListByRepoOptions + } + listByRepoReturns struct { + result1 []*github.Issue + result2 *github.Response + result3 error + } + listByRepoReturnsOnCall map[int]struct { + result1 []*github.Issue + result2 *github.Response + result3 error + } + ListMilestonesStub func(context.Context, string, string, *github.MilestoneListOptions) ([]*github.Milestone, *github.Response, error) + listMilestonesMutex sync.RWMutex + listMilestonesArgsForCall []struct { + arg1 context.Context + arg2 string + arg3 string + arg4 *github.MilestoneListOptions + } + listMilestonesReturns struct { + result1 []*github.Milestone + result2 *github.Response + result3 error + } + listMilestonesReturnsOnCall map[int]struct { + result1 []*github.Milestone + result2 *github.Response + result3 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *IssuesService) Get(arg1 context.Context, arg2 string, arg3 string, arg4 int) (*github.Issue, *github.Response, error) { + fake.getMutex.Lock() + ret, specificReturn := fake.getReturnsOnCall[len(fake.getArgsForCall)] + fake.getArgsForCall = append(fake.getArgsForCall, struct { + arg1 context.Context + arg2 string + arg3 string + arg4 int + }{arg1, arg2, arg3, arg4}) + stub := fake.GetStub + fakeReturns := fake.getReturns + fake.recordInvocation("Get", []interface{}{arg1, arg2, arg3, arg4}) + fake.getMutex.Unlock() + if stub != nil { + return stub(arg1, arg2, arg3, arg4) + } + if specificReturn { + return ret.result1, ret.result2, ret.result3 + } + return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 +} + +func (fake *IssuesService) GetCallCount() int { + fake.getMutex.RLock() + defer fake.getMutex.RUnlock() + return len(fake.getArgsForCall) +} + +func (fake *IssuesService) GetCalls(stub func(context.Context, string, string, int) (*github.Issue, *github.Response, error)) { + fake.getMutex.Lock() + defer fake.getMutex.Unlock() + fake.GetStub = stub +} + +func (fake *IssuesService) GetArgsForCall(i int) (context.Context, string, string, int) { + fake.getMutex.RLock() + defer fake.getMutex.RUnlock() + argsForCall := fake.getArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 +} + +func (fake *IssuesService) GetReturns(result1 *github.Issue, result2 *github.Response, result3 error) { + fake.getMutex.Lock() + defer fake.getMutex.Unlock() + fake.GetStub = nil + fake.getReturns = struct { + result1 *github.Issue + result2 *github.Response + result3 error + }{result1, result2, result3} +} + +func (fake *IssuesService) GetReturnsOnCall(i int, result1 *github.Issue, result2 *github.Response, result3 error) { + fake.getMutex.Lock() + defer fake.getMutex.Unlock() + fake.GetStub = nil + if fake.getReturnsOnCall == nil { + fake.getReturnsOnCall = make(map[int]struct { + result1 *github.Issue + result2 *github.Response + result3 error + }) + } + fake.getReturnsOnCall[i] = struct { + result1 *github.Issue + result2 *github.Response + result3 error + }{result1, result2, result3} +} + +func (fake *IssuesService) ListByRepo(arg1 context.Context, arg2 string, arg3 string, arg4 *github.IssueListByRepoOptions) ([]*github.Issue, *github.Response, error) { + fake.listByRepoMutex.Lock() + ret, specificReturn := fake.listByRepoReturnsOnCall[len(fake.listByRepoArgsForCall)] + fake.listByRepoArgsForCall = append(fake.listByRepoArgsForCall, struct { + arg1 context.Context + arg2 string + arg3 string + arg4 *github.IssueListByRepoOptions + }{arg1, arg2, arg3, arg4}) + stub := fake.ListByRepoStub + fakeReturns := fake.listByRepoReturns + fake.recordInvocation("ListByRepo", []interface{}{arg1, arg2, arg3, arg4}) + fake.listByRepoMutex.Unlock() + if stub != nil { + return stub(arg1, arg2, arg3, arg4) + } + if specificReturn { + return ret.result1, ret.result2, ret.result3 + } + return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 +} + +func (fake *IssuesService) ListByRepoCallCount() int { + fake.listByRepoMutex.RLock() + defer fake.listByRepoMutex.RUnlock() + return len(fake.listByRepoArgsForCall) +} + +func (fake *IssuesService) ListByRepoCalls(stub func(context.Context, string, string, *github.IssueListByRepoOptions) ([]*github.Issue, *github.Response, error)) { + fake.listByRepoMutex.Lock() + defer fake.listByRepoMutex.Unlock() + fake.ListByRepoStub = stub +} + +func (fake *IssuesService) ListByRepoArgsForCall(i int) (context.Context, string, string, *github.IssueListByRepoOptions) { + fake.listByRepoMutex.RLock() + defer fake.listByRepoMutex.RUnlock() + argsForCall := fake.listByRepoArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 +} + +func (fake *IssuesService) ListByRepoReturns(result1 []*github.Issue, result2 *github.Response, result3 error) { + fake.listByRepoMutex.Lock() + defer fake.listByRepoMutex.Unlock() + fake.ListByRepoStub = nil + fake.listByRepoReturns = struct { + result1 []*github.Issue + result2 *github.Response + result3 error + }{result1, result2, result3} +} + +func (fake *IssuesService) ListByRepoReturnsOnCall(i int, result1 []*github.Issue, result2 *github.Response, result3 error) { + fake.listByRepoMutex.Lock() + defer fake.listByRepoMutex.Unlock() + fake.ListByRepoStub = nil + if fake.listByRepoReturnsOnCall == nil { + fake.listByRepoReturnsOnCall = make(map[int]struct { + result1 []*github.Issue + result2 *github.Response + result3 error + }) + } + fake.listByRepoReturnsOnCall[i] = struct { + result1 []*github.Issue + result2 *github.Response + result3 error + }{result1, result2, result3} +} + +func (fake *IssuesService) ListMilestones(arg1 context.Context, arg2 string, arg3 string, arg4 *github.MilestoneListOptions) ([]*github.Milestone, *github.Response, error) { + fake.listMilestonesMutex.Lock() + ret, specificReturn := fake.listMilestonesReturnsOnCall[len(fake.listMilestonesArgsForCall)] + fake.listMilestonesArgsForCall = append(fake.listMilestonesArgsForCall, struct { + arg1 context.Context + arg2 string + arg3 string + arg4 *github.MilestoneListOptions + }{arg1, arg2, arg3, arg4}) + stub := fake.ListMilestonesStub + fakeReturns := fake.listMilestonesReturns + fake.recordInvocation("ListMilestones", []interface{}{arg1, arg2, arg3, arg4}) + fake.listMilestonesMutex.Unlock() + if stub != nil { + return stub(arg1, arg2, arg3, arg4) + } + if specificReturn { + return ret.result1, ret.result2, ret.result3 + } + return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 +} + +func (fake *IssuesService) ListMilestonesCallCount() int { + fake.listMilestonesMutex.RLock() + defer fake.listMilestonesMutex.RUnlock() + return len(fake.listMilestonesArgsForCall) +} + +func (fake *IssuesService) ListMilestonesCalls(stub func(context.Context, string, string, *github.MilestoneListOptions) ([]*github.Milestone, *github.Response, error)) { + fake.listMilestonesMutex.Lock() + defer fake.listMilestonesMutex.Unlock() + fake.ListMilestonesStub = stub +} + +func (fake *IssuesService) ListMilestonesArgsForCall(i int) (context.Context, string, string, *github.MilestoneListOptions) { + fake.listMilestonesMutex.RLock() + defer fake.listMilestonesMutex.RUnlock() + argsForCall := fake.listMilestonesArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 +} + +func (fake *IssuesService) ListMilestonesReturns(result1 []*github.Milestone, result2 *github.Response, result3 error) { + fake.listMilestonesMutex.Lock() + defer fake.listMilestonesMutex.Unlock() + fake.ListMilestonesStub = nil + fake.listMilestonesReturns = struct { + result1 []*github.Milestone + result2 *github.Response + result3 error + }{result1, result2, result3} +} + +func (fake *IssuesService) ListMilestonesReturnsOnCall(i int, result1 []*github.Milestone, result2 *github.Response, result3 error) { + fake.listMilestonesMutex.Lock() + defer fake.listMilestonesMutex.Unlock() + fake.ListMilestonesStub = nil + if fake.listMilestonesReturnsOnCall == nil { + fake.listMilestonesReturnsOnCall = make(map[int]struct { + result1 []*github.Milestone + result2 *github.Response + result3 error + }) + } + fake.listMilestonesReturnsOnCall[i] = struct { + result1 []*github.Milestone + result2 *github.Response + result3 error + }{result1, result2, result3} +} + +func (fake *IssuesService) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.getMutex.RLock() + defer fake.getMutex.RUnlock() + fake.listByRepoMutex.RLock() + defer fake.listByRepoMutex.RUnlock() + fake.listMilestonesMutex.RLock() + defer fake.listMilestonesMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *IssuesService) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} diff --git a/pkg/notes/fakes/milestone_lister.go b/pkg/notes/fakes/milestone_lister.go new file mode 100644 index 000000000..02d2c029d --- /dev/null +++ b/pkg/notes/fakes/milestone_lister.go @@ -0,0 +1,126 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package fakes + +import ( + "context" + "sync" + + "github.com/google/go-github/v40/github" +) + +type MilestoneLister struct { + ListMilestonesStub func(context.Context, string, string, *github.MilestoneListOptions) ([]*github.Milestone, *github.Response, error) + listMilestonesMutex sync.RWMutex + listMilestonesArgsForCall []struct { + arg1 context.Context + arg2 string + arg3 string + arg4 *github.MilestoneListOptions + } + listMilestonesReturns struct { + result1 []*github.Milestone + result2 *github.Response + result3 error + } + listMilestonesReturnsOnCall map[int]struct { + result1 []*github.Milestone + result2 *github.Response + result3 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *MilestoneLister) ListMilestones(arg1 context.Context, arg2 string, arg3 string, arg4 *github.MilestoneListOptions) ([]*github.Milestone, *github.Response, error) { + fake.listMilestonesMutex.Lock() + ret, specificReturn := fake.listMilestonesReturnsOnCall[len(fake.listMilestonesArgsForCall)] + fake.listMilestonesArgsForCall = append(fake.listMilestonesArgsForCall, struct { + arg1 context.Context + arg2 string + arg3 string + arg4 *github.MilestoneListOptions + }{arg1, arg2, arg3, arg4}) + stub := fake.ListMilestonesStub + fakeReturns := fake.listMilestonesReturns + fake.recordInvocation("ListMilestones", []interface{}{arg1, arg2, arg3, arg4}) + fake.listMilestonesMutex.Unlock() + if stub != nil { + return stub(arg1, arg2, arg3, arg4) + } + if specificReturn { + return ret.result1, ret.result2, ret.result3 + } + return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 +} + +func (fake *MilestoneLister) ListMilestonesCallCount() int { + fake.listMilestonesMutex.RLock() + defer fake.listMilestonesMutex.RUnlock() + return len(fake.listMilestonesArgsForCall) +} + +func (fake *MilestoneLister) ListMilestonesCalls(stub func(context.Context, string, string, *github.MilestoneListOptions) ([]*github.Milestone, *github.Response, error)) { + fake.listMilestonesMutex.Lock() + defer fake.listMilestonesMutex.Unlock() + fake.ListMilestonesStub = stub +} + +func (fake *MilestoneLister) ListMilestonesArgsForCall(i int) (context.Context, string, string, *github.MilestoneListOptions) { + fake.listMilestonesMutex.RLock() + defer fake.listMilestonesMutex.RUnlock() + argsForCall := fake.listMilestonesArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 +} + +func (fake *MilestoneLister) ListMilestonesReturns(result1 []*github.Milestone, result2 *github.Response, result3 error) { + fake.listMilestonesMutex.Lock() + defer fake.listMilestonesMutex.Unlock() + fake.ListMilestonesStub = nil + fake.listMilestonesReturns = struct { + result1 []*github.Milestone + result2 *github.Response + result3 error + }{result1, result2, result3} +} + +func (fake *MilestoneLister) ListMilestonesReturnsOnCall(i int, result1 []*github.Milestone, result2 *github.Response, result3 error) { + fake.listMilestonesMutex.Lock() + defer fake.listMilestonesMutex.Unlock() + fake.ListMilestonesStub = nil + if fake.listMilestonesReturnsOnCall == nil { + fake.listMilestonesReturnsOnCall = make(map[int]struct { + result1 []*github.Milestone + result2 *github.Response + result3 error + }) + } + fake.listMilestonesReturnsOnCall[i] = struct { + result1 []*github.Milestone + result2 *github.Response + result3 error + }{result1, result2, result3} +} + +func (fake *MilestoneLister) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.listMilestonesMutex.RLock() + defer fake.listMilestonesMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *MilestoneLister) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} diff --git a/pkg/notes/fakes/releases_service.go b/pkg/notes/fakes/releases_service.go new file mode 100644 index 000000000..0d89fd752 --- /dev/null +++ b/pkg/notes/fakes/releases_service.go @@ -0,0 +1,129 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package fakes + +import ( + "context" + "sync" + + "github.com/google/go-github/v40/github" + "github.com/pivotal-cf/kiln/pkg/cargo" +) + +type ReleaseService struct { + ListReleasesStub func(context.Context, string, string, *github.ListOptions) ([]*github.RepositoryRelease, *github.Response, error) + listReleasesMutex sync.RWMutex + listReleasesArgsForCall []struct { + arg1 context.Context + arg2 string + arg3 string + arg4 *github.ListOptions + } + listReleasesReturns struct { + result1 []*github.RepositoryRelease + result2 *github.Response + result3 error + } + listReleasesReturnsOnCall map[int]struct { + result1 []*github.RepositoryRelease + result2 *github.Response + result3 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *ReleaseService) ListReleases(arg1 context.Context, arg2 string, arg3 string, arg4 *github.ListOptions) ([]*github.RepositoryRelease, *github.Response, error) { + fake.listReleasesMutex.Lock() + ret, specificReturn := fake.listReleasesReturnsOnCall[len(fake.listReleasesArgsForCall)] + fake.listReleasesArgsForCall = append(fake.listReleasesArgsForCall, struct { + arg1 context.Context + arg2 string + arg3 string + arg4 *github.ListOptions + }{arg1, arg2, arg3, arg4}) + stub := fake.ListReleasesStub + fakeReturns := fake.listReleasesReturns + fake.recordInvocation("ListReleases", []interface{}{arg1, arg2, arg3, arg4}) + fake.listReleasesMutex.Unlock() + if stub != nil { + return stub(arg1, arg2, arg3, arg4) + } + if specificReturn { + return ret.result1, ret.result2, ret.result3 + } + return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 +} + +func (fake *ReleaseService) ListReleasesCallCount() int { + fake.listReleasesMutex.RLock() + defer fake.listReleasesMutex.RUnlock() + return len(fake.listReleasesArgsForCall) +} + +func (fake *ReleaseService) ListReleasesCalls(stub func(context.Context, string, string, *github.ListOptions) ([]*github.RepositoryRelease, *github.Response, error)) { + fake.listReleasesMutex.Lock() + defer fake.listReleasesMutex.Unlock() + fake.ListReleasesStub = stub +} + +func (fake *ReleaseService) ListReleasesArgsForCall(i int) (context.Context, string, string, *github.ListOptions) { + fake.listReleasesMutex.RLock() + defer fake.listReleasesMutex.RUnlock() + argsForCall := fake.listReleasesArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 +} + +func (fake *ReleaseService) ListReleasesReturns(result1 []*github.RepositoryRelease, result2 *github.Response, result3 error) { + fake.listReleasesMutex.Lock() + defer fake.listReleasesMutex.Unlock() + fake.ListReleasesStub = nil + fake.listReleasesReturns = struct { + result1 []*github.RepositoryRelease + result2 *github.Response + result3 error + }{result1, result2, result3} +} + +func (fake *ReleaseService) ListReleasesReturnsOnCall(i int, result1 []*github.RepositoryRelease, result2 *github.Response, result3 error) { + fake.listReleasesMutex.Lock() + defer fake.listReleasesMutex.Unlock() + fake.ListReleasesStub = nil + if fake.listReleasesReturnsOnCall == nil { + fake.listReleasesReturnsOnCall = make(map[int]struct { + result1 []*github.RepositoryRelease + result2 *github.Response + result3 error + }) + } + fake.listReleasesReturnsOnCall[i] = struct { + result1 []*github.RepositoryRelease + result2 *github.Response + result3 error + }{result1, result2, result3} +} + +func (fake *ReleaseService) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.listReleasesMutex.RLock() + defer fake.listReleasesMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *ReleaseService) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ cargo.RepositoryReleaseLister = new(ReleaseService) diff --git a/pkg/notes/fakes/revision_resolver.go b/pkg/notes/fakes/revision_resolver.go new file mode 100644 index 000000000..68269f21a --- /dev/null +++ b/pkg/notes/fakes/revision_resolver.go @@ -0,0 +1,114 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package fakes + +import ( + "sync" + + "github.com/go-git/go-git/v5/plumbing" +) + +type RevisionResolver struct { + ResolveRevisionStub func(plumbing.Revision) (*plumbing.Hash, error) + resolveRevisionMutex sync.RWMutex + resolveRevisionArgsForCall []struct { + arg1 plumbing.Revision + } + resolveRevisionReturns struct { + result1 *plumbing.Hash + result2 error + } + resolveRevisionReturnsOnCall map[int]struct { + result1 *plumbing.Hash + result2 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *RevisionResolver) ResolveRevision(arg1 plumbing.Revision) (*plumbing.Hash, error) { + fake.resolveRevisionMutex.Lock() + ret, specificReturn := fake.resolveRevisionReturnsOnCall[len(fake.resolveRevisionArgsForCall)] + fake.resolveRevisionArgsForCall = append(fake.resolveRevisionArgsForCall, struct { + arg1 plumbing.Revision + }{arg1}) + stub := fake.ResolveRevisionStub + fakeReturns := fake.resolveRevisionReturns + fake.recordInvocation("ResolveRevision", []interface{}{arg1}) + fake.resolveRevisionMutex.Unlock() + if stub != nil { + return stub(arg1) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *RevisionResolver) ResolveRevisionCallCount() int { + fake.resolveRevisionMutex.RLock() + defer fake.resolveRevisionMutex.RUnlock() + return len(fake.resolveRevisionArgsForCall) +} + +func (fake *RevisionResolver) ResolveRevisionCalls(stub func(plumbing.Revision) (*plumbing.Hash, error)) { + fake.resolveRevisionMutex.Lock() + defer fake.resolveRevisionMutex.Unlock() + fake.ResolveRevisionStub = stub +} + +func (fake *RevisionResolver) ResolveRevisionArgsForCall(i int) plumbing.Revision { + fake.resolveRevisionMutex.RLock() + defer fake.resolveRevisionMutex.RUnlock() + argsForCall := fake.resolveRevisionArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *RevisionResolver) ResolveRevisionReturns(result1 *plumbing.Hash, result2 error) { + fake.resolveRevisionMutex.Lock() + defer fake.resolveRevisionMutex.Unlock() + fake.ResolveRevisionStub = nil + fake.resolveRevisionReturns = struct { + result1 *plumbing.Hash + result2 error + }{result1, result2} +} + +func (fake *RevisionResolver) ResolveRevisionReturnsOnCall(i int, result1 *plumbing.Hash, result2 error) { + fake.resolveRevisionMutex.Lock() + defer fake.resolveRevisionMutex.Unlock() + fake.ResolveRevisionStub = nil + if fake.resolveRevisionReturnsOnCall == nil { + fake.resolveRevisionReturnsOnCall = make(map[int]struct { + result1 *plumbing.Hash + result2 error + }) + } + fake.resolveRevisionReturnsOnCall[i] = struct { + result1 *plumbing.Hash + result2 error + }{result1, result2} +} + +func (fake *RevisionResolver) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.resolveRevisionMutex.RLock() + defer fake.resolveRevisionMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *RevisionResolver) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} diff --git a/pkg/notes/internal/fakes/historic_kilnfile.go b/pkg/notes/internal/fakes/historic_kilnfile.go index 8a05a0452..d687dc660 100644 --- a/pkg/notes/internal/fakes/historic_kilnfile.go +++ b/pkg/notes/internal/fakes/historic_kilnfile.go @@ -27,7 +27,7 @@ type HistoricKilnfile struct { result2 cargo.KilnfileLock result3 error } - invocations map[string][][]interface{} + invocations map[string][][]any invocationsMutex sync.RWMutex } @@ -41,7 +41,7 @@ func (fake *HistoricKilnfile) Spy(arg1 storer.EncodedObjectStorer, arg2 plumbing }{arg1, arg2, arg3}) stub := fake.Stub returns := fake.returns - fake.recordInvocation("historicKilnfile", []interface{}{arg1, arg2, arg3}) + fake.recordInvocation("historicKilnfile", []any{arg1, arg2, arg3}) fake.mutex.Unlock() if stub != nil { return stub(arg1, arg2, arg3) @@ -99,26 +99,26 @@ func (fake *HistoricKilnfile) ReturnsOnCall(i int, result1 cargo.Kilnfile, resul }{result1, result2, result3} } -func (fake *HistoricKilnfile) Invocations() map[string][][]interface{} { +func (fake *HistoricKilnfile) Invocations() map[string][][]any { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() fake.mutex.RLock() defer fake.mutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} + copiedInvocations := map[string][][]any{} for key, value := range fake.invocations { copiedInvocations[key] = value } return copiedInvocations } -func (fake *HistoricKilnfile) recordInvocation(key string, args []interface{}) { +func (fake *HistoricKilnfile) recordInvocation(key string, args []any) { fake.invocationsMutex.Lock() defer fake.invocationsMutex.Unlock() if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} + fake.invocations = map[string][][]any{} } if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} + fake.invocations[key] = [][]any{} } fake.invocations[key] = append(fake.invocations[key], args) } diff --git a/pkg/notes/internal/fakes/historic_version.go b/pkg/notes/internal/fakes/historic_version.go index b3d47fb2e..deb321033 100644 --- a/pkg/notes/internal/fakes/historic_version.go +++ b/pkg/notes/internal/fakes/historic_version.go @@ -24,7 +24,7 @@ type HistoricVersion struct { result1 string result2 error } - invocations map[string][][]interface{} + invocations map[string][][]any invocationsMutex sync.RWMutex } @@ -38,7 +38,7 @@ func (fake *HistoricVersion) Spy(arg1 storer.EncodedObjectStorer, arg2 plumbing. }{arg1, arg2, arg3}) stub := fake.Stub returns := fake.returns - fake.recordInvocation("historicVersion", []interface{}{arg1, arg2, arg3}) + fake.recordInvocation("historicVersion", []any{arg1, arg2, arg3}) fake.mutex.Unlock() if stub != nil { return stub(arg1, arg2, arg3) @@ -93,26 +93,26 @@ func (fake *HistoricVersion) ReturnsOnCall(i int, result1 string, result2 error) }{result1, result2} } -func (fake *HistoricVersion) Invocations() map[string][][]interface{} { +func (fake *HistoricVersion) Invocations() map[string][][]any { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() fake.mutex.RLock() defer fake.mutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} + copiedInvocations := map[string][][]any{} for key, value := range fake.invocations { copiedInvocations[key] = value } return copiedInvocations } -func (fake *HistoricVersion) recordInvocation(key string, args []interface{}) { +func (fake *HistoricVersion) recordInvocation(key string, args []any) { fake.invocationsMutex.Lock() defer fake.invocationsMutex.Unlock() if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} + fake.invocations = map[string][][]any{} } if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} + fake.invocations[key] = [][]any{} } fake.invocations[key] = append(fake.invocations[key], args) } diff --git a/pkg/notes/internal/fakes/issue_getter.go b/pkg/notes/internal/fakes/issue_getter.go index 3dbaa90cc..fcd0c6451 100644 --- a/pkg/notes/internal/fakes/issue_getter.go +++ b/pkg/notes/internal/fakes/issue_getter.go @@ -27,7 +27,7 @@ type IssueGetter struct { result2 *github.Response result3 error } - invocations map[string][][]interface{} + invocations map[string][][]any invocationsMutex sync.RWMutex } @@ -42,7 +42,7 @@ func (fake *IssueGetter) Get(arg1 context.Context, arg2 string, arg3 string, arg }{arg1, arg2, arg3, arg4}) stub := fake.GetStub fakeReturns := fake.getReturns - fake.recordInvocation("Get", []interface{}{arg1, arg2, arg3, arg4}) + fake.recordInvocation("Get", []any{arg1, arg2, arg3, arg4}) fake.getMutex.Unlock() if stub != nil { return stub(arg1, arg2, arg3, arg4) @@ -101,26 +101,26 @@ func (fake *IssueGetter) GetReturnsOnCall(i int, result1 *github.Issue, result2 }{result1, result2, result3} } -func (fake *IssueGetter) Invocations() map[string][][]interface{} { +func (fake *IssueGetter) Invocations() map[string][][]any { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() fake.getMutex.RLock() defer fake.getMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} + copiedInvocations := map[string][][]any{} for key, value := range fake.invocations { copiedInvocations[key] = value } return copiedInvocations } -func (fake *IssueGetter) recordInvocation(key string, args []interface{}) { +func (fake *IssueGetter) recordInvocation(key string, args []any) { fake.invocationsMutex.Lock() defer fake.invocationsMutex.Unlock() if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} + fake.invocations = map[string][][]any{} } if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} + fake.invocations[key] = [][]any{} } fake.invocations[key] = append(fake.invocations[key], args) } diff --git a/pkg/notes/internal/fakes/issues_by_repo_lister.go b/pkg/notes/internal/fakes/issues_by_repo_lister.go index f63c2368d..af96733bd 100644 --- a/pkg/notes/internal/fakes/issues_by_repo_lister.go +++ b/pkg/notes/internal/fakes/issues_by_repo_lister.go @@ -27,7 +27,7 @@ type IssuesByRepoLister struct { result2 *github.Response result3 error } - invocations map[string][][]interface{} + invocations map[string][][]any invocationsMutex sync.RWMutex } @@ -42,7 +42,7 @@ func (fake *IssuesByRepoLister) ListByRepo(arg1 context.Context, arg2 string, ar }{arg1, arg2, arg3, arg4}) stub := fake.ListByRepoStub fakeReturns := fake.listByRepoReturns - fake.recordInvocation("ListByRepo", []interface{}{arg1, arg2, arg3, arg4}) + fake.recordInvocation("ListByRepo", []any{arg1, arg2, arg3, arg4}) fake.listByRepoMutex.Unlock() if stub != nil { return stub(arg1, arg2, arg3, arg4) @@ -101,26 +101,26 @@ func (fake *IssuesByRepoLister) ListByRepoReturnsOnCall(i int, result1 []*github }{result1, result2, result3} } -func (fake *IssuesByRepoLister) Invocations() map[string][][]interface{} { +func (fake *IssuesByRepoLister) Invocations() map[string][][]any { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() fake.listByRepoMutex.RLock() defer fake.listByRepoMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} + copiedInvocations := map[string][][]any{} for key, value := range fake.invocations { copiedInvocations[key] = value } return copiedInvocations } -func (fake *IssuesByRepoLister) recordInvocation(key string, args []interface{}) { +func (fake *IssuesByRepoLister) recordInvocation(key string, args []any) { fake.invocationsMutex.Lock() defer fake.invocationsMutex.Unlock() if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} + fake.invocations = map[string][][]any{} } if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} + fake.invocations[key] = [][]any{} } fake.invocations[key] = append(fake.invocations[key], args) } diff --git a/pkg/notes/internal/fakes/issues_service.go b/pkg/notes/internal/fakes/issues_service.go index fb4af88f0..0b902787b 100644 --- a/pkg/notes/internal/fakes/issues_service.go +++ b/pkg/notes/internal/fakes/issues_service.go @@ -63,7 +63,7 @@ type IssuesService struct { result2 *github.Response result3 error } - invocations map[string][][]interface{} + invocations map[string][][]any invocationsMutex sync.RWMutex } @@ -78,7 +78,7 @@ func (fake *IssuesService) Get(arg1 context.Context, arg2 string, arg3 string, a }{arg1, arg2, arg3, arg4}) stub := fake.GetStub fakeReturns := fake.getReturns - fake.recordInvocation("Get", []interface{}{arg1, arg2, arg3, arg4}) + fake.recordInvocation("Get", []any{arg1, arg2, arg3, arg4}) fake.getMutex.Unlock() if stub != nil { return stub(arg1, arg2, arg3, arg4) @@ -148,7 +148,7 @@ func (fake *IssuesService) ListByRepo(arg1 context.Context, arg2 string, arg3 st }{arg1, arg2, arg3, arg4}) stub := fake.ListByRepoStub fakeReturns := fake.listByRepoReturns - fake.recordInvocation("ListByRepo", []interface{}{arg1, arg2, arg3, arg4}) + fake.recordInvocation("ListByRepo", []any{arg1, arg2, arg3, arg4}) fake.listByRepoMutex.Unlock() if stub != nil { return stub(arg1, arg2, arg3, arg4) @@ -218,7 +218,7 @@ func (fake *IssuesService) ListMilestones(arg1 context.Context, arg2 string, arg }{arg1, arg2, arg3, arg4}) stub := fake.ListMilestonesStub fakeReturns := fake.listMilestonesReturns - fake.recordInvocation("ListMilestones", []interface{}{arg1, arg2, arg3, arg4}) + fake.recordInvocation("ListMilestones", []any{arg1, arg2, arg3, arg4}) fake.listMilestonesMutex.Unlock() if stub != nil { return stub(arg1, arg2, arg3, arg4) @@ -277,7 +277,7 @@ func (fake *IssuesService) ListMilestonesReturnsOnCall(i int, result1 []*github. }{result1, result2, result3} } -func (fake *IssuesService) Invocations() map[string][][]interface{} { +func (fake *IssuesService) Invocations() map[string][][]any { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() fake.getMutex.RLock() @@ -286,21 +286,21 @@ func (fake *IssuesService) Invocations() map[string][][]interface{} { defer fake.listByRepoMutex.RUnlock() fake.listMilestonesMutex.RLock() defer fake.listMilestonesMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} + copiedInvocations := map[string][][]any{} for key, value := range fake.invocations { copiedInvocations[key] = value } return copiedInvocations } -func (fake *IssuesService) recordInvocation(key string, args []interface{}) { +func (fake *IssuesService) recordInvocation(key string, args []any) { fake.invocationsMutex.Lock() defer fake.invocationsMutex.Unlock() if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} + fake.invocations = map[string][][]any{} } if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} + fake.invocations[key] = [][]any{} } fake.invocations[key] = append(fake.invocations[key], args) } diff --git a/pkg/notes/internal/fakes/milestone_lister.go b/pkg/notes/internal/fakes/milestone_lister.go index 02d2c029d..ec4389a97 100644 --- a/pkg/notes/internal/fakes/milestone_lister.go +++ b/pkg/notes/internal/fakes/milestone_lister.go @@ -27,7 +27,7 @@ type MilestoneLister struct { result2 *github.Response result3 error } - invocations map[string][][]interface{} + invocations map[string][][]any invocationsMutex sync.RWMutex } @@ -42,7 +42,7 @@ func (fake *MilestoneLister) ListMilestones(arg1 context.Context, arg2 string, a }{arg1, arg2, arg3, arg4}) stub := fake.ListMilestonesStub fakeReturns := fake.listMilestonesReturns - fake.recordInvocation("ListMilestones", []interface{}{arg1, arg2, arg3, arg4}) + fake.recordInvocation("ListMilestones", []any{arg1, arg2, arg3, arg4}) fake.listMilestonesMutex.Unlock() if stub != nil { return stub(arg1, arg2, arg3, arg4) @@ -101,26 +101,26 @@ func (fake *MilestoneLister) ListMilestonesReturnsOnCall(i int, result1 []*githu }{result1, result2, result3} } -func (fake *MilestoneLister) Invocations() map[string][][]interface{} { +func (fake *MilestoneLister) Invocations() map[string][][]any { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() fake.listMilestonesMutex.RLock() defer fake.listMilestonesMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} + copiedInvocations := map[string][][]any{} for key, value := range fake.invocations { copiedInvocations[key] = value } return copiedInvocations } -func (fake *MilestoneLister) recordInvocation(key string, args []interface{}) { +func (fake *MilestoneLister) recordInvocation(key string, args []any) { fake.invocationsMutex.Lock() defer fake.invocationsMutex.Unlock() if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} + fake.invocations = map[string][][]any{} } if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} + fake.invocations[key] = [][]any{} } fake.invocations[key] = append(fake.invocations[key], args) } diff --git a/pkg/notes/internal/fakes/releases_service.go b/pkg/notes/internal/fakes/releases_service.go index 0d89fd752..f97492ca4 100644 --- a/pkg/notes/internal/fakes/releases_service.go +++ b/pkg/notes/internal/fakes/releases_service.go @@ -28,7 +28,7 @@ type ReleaseService struct { result2 *github.Response result3 error } - invocations map[string][][]interface{} + invocations map[string][][]any invocationsMutex sync.RWMutex } @@ -43,7 +43,7 @@ func (fake *ReleaseService) ListReleases(arg1 context.Context, arg2 string, arg3 }{arg1, arg2, arg3, arg4}) stub := fake.ListReleasesStub fakeReturns := fake.listReleasesReturns - fake.recordInvocation("ListReleases", []interface{}{arg1, arg2, arg3, arg4}) + fake.recordInvocation("ListReleases", []any{arg1, arg2, arg3, arg4}) fake.listReleasesMutex.Unlock() if stub != nil { return stub(arg1, arg2, arg3, arg4) @@ -102,26 +102,26 @@ func (fake *ReleaseService) ListReleasesReturnsOnCall(i int, result1 []*github.R }{result1, result2, result3} } -func (fake *ReleaseService) Invocations() map[string][][]interface{} { +func (fake *ReleaseService) Invocations() map[string][][]any { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() fake.listReleasesMutex.RLock() defer fake.listReleasesMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} + copiedInvocations := map[string][][]any{} for key, value := range fake.invocations { copiedInvocations[key] = value } return copiedInvocations } -func (fake *ReleaseService) recordInvocation(key string, args []interface{}) { +func (fake *ReleaseService) recordInvocation(key string, args []any) { fake.invocationsMutex.Lock() defer fake.invocationsMutex.Unlock() if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} + fake.invocations = map[string][][]any{} } if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} + fake.invocations[key] = [][]any{} } fake.invocations[key] = append(fake.invocations[key], args) } diff --git a/pkg/notes/internal/fakes/revision_resolver.go b/pkg/notes/internal/fakes/revision_resolver.go index 68269f21a..5d0e54f9b 100644 --- a/pkg/notes/internal/fakes/revision_resolver.go +++ b/pkg/notes/internal/fakes/revision_resolver.go @@ -21,7 +21,7 @@ type RevisionResolver struct { result1 *plumbing.Hash result2 error } - invocations map[string][][]interface{} + invocations map[string][][]any invocationsMutex sync.RWMutex } @@ -33,7 +33,7 @@ func (fake *RevisionResolver) ResolveRevision(arg1 plumbing.Revision) (*plumbing }{arg1}) stub := fake.ResolveRevisionStub fakeReturns := fake.resolveRevisionReturns - fake.recordInvocation("ResolveRevision", []interface{}{arg1}) + fake.recordInvocation("ResolveRevision", []any{arg1}) fake.resolveRevisionMutex.Unlock() if stub != nil { return stub(arg1) @@ -89,26 +89,26 @@ func (fake *RevisionResolver) ResolveRevisionReturnsOnCall(i int, result1 *plumb }{result1, result2} } -func (fake *RevisionResolver) Invocations() map[string][][]interface{} { +func (fake *RevisionResolver) Invocations() map[string][][]any { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() fake.resolveRevisionMutex.RLock() defer fake.resolveRevisionMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} + copiedInvocations := map[string][][]any{} for key, value := range fake.invocations { copiedInvocations[key] = value } return copiedInvocations } -func (fake *RevisionResolver) recordInvocation(key string, args []interface{}) { +func (fake *RevisionResolver) recordInvocation(key string, args []any) { fake.invocationsMutex.Lock() defer fake.invocationsMutex.Unlock() if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} + fake.invocations = map[string][][]any{} } if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} + fake.invocations[key] = [][]any{} } fake.invocations[key] = append(fake.invocations[key], args) } diff --git a/pkg/notes/internal/fakes/trainstat_client.go b/pkg/notes/internal/fakes/trainstat_client.go index 148f224a6..a2b72fe4a 100644 --- a/pkg/notes/internal/fakes/trainstat_client.go +++ b/pkg/notes/internal/fakes/trainstat_client.go @@ -22,7 +22,7 @@ type TrainstatClient struct { result1 []string result2 error } - invocations map[string][][]interface{} + invocations map[string][][]any invocationsMutex sync.RWMutex } @@ -37,7 +37,7 @@ func (fake *TrainstatClient) FetchTrainstatNotes(ctx context.Context, arg1 strin }{ctx, arg1, arg2, arg3}) stub := fake.FetchStub fakeReturns := fake.fetchReturns - fake.recordInvocation("Get", []interface{}{arg1, arg2, arg3}) + fake.recordInvocation("Get", []any{arg1, arg2, arg3}) fake.fetchMutex.Unlock() if stub != nil { return stub(arg1, arg2, arg3) @@ -83,24 +83,24 @@ func (fake *TrainstatClient) GetArgsForCall(i int) (string, string, string) { return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 } -func (fake *TrainstatClient) Invocations() map[string][][]interface{} { +func (fake *TrainstatClient) Invocations() map[string][][]any { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} + copiedInvocations := map[string][][]any{} for key, value := range fake.invocations { copiedInvocations[key] = value } return copiedInvocations } -func (fake *TrainstatClient) recordInvocation(key string, args []interface{}) { +func (fake *TrainstatClient) recordInvocation(key string, args []any) { fake.invocationsMutex.Lock() defer fake.invocationsMutex.Unlock() if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} + fake.invocations = map[string][][]any{} } if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} + fake.invocations[key] = [][]any{} } fake.invocations[key] = append(fake.invocations[key], args) } diff --git a/pkg/planitest/example_product_service_test.go b/pkg/planitest/example_product_service_test.go index 8a6115901..9a97dc60e 100644 --- a/pkg/planitest/example_product_service_test.go +++ b/pkg/planitest/example_product_service_test.go @@ -37,7 +37,7 @@ product-properties: {} panic(err) } - manifest, err := product.RenderManifest(map[string]interface{}{ + manifest, err := product.RenderManifest(map[string]any{ ".properties.required": "foo", }) if err != nil { diff --git a/pkg/planitest/internal/config.go b/pkg/planitest/internal/config.go index 3579eec8f..7e5b40463 100644 --- a/pkg/planitest/internal/config.go +++ b/pkg/planitest/internal/config.go @@ -23,11 +23,11 @@ import ( // To work around this, we now have our own copy of ProductConfiguration without omit-empty on product-properties type ProductConfiguration struct { ProductName string `yaml:"product-name,omitempty"` - ProductProperties map[string]interface{} `yaml:"product-properties"` // remove omitempty - NetworkProperties map[string]interface{} `yaml:"network-properties,omitempty"` + ProductProperties map[string]any `yaml:"product-properties"` // remove omitempty + NetworkProperties map[string]any `yaml:"network-properties,omitempty"` ResourceConfigProperties map[string]config.ResourceConfig `yaml:"resource-config,omitempty"` ErrandConfigs map[string]config.ErrandConfig `yaml:"errand-config,omitempty"` - SyslogProperties map[string]interface{} `yaml:"syslog-properties,omitempty"` + SyslogProperties map[string]any `yaml:"syslog-properties,omitempty"` } // Force our "fork" of ProductConfiguration to have the same fields as the version in om/config @@ -35,7 +35,7 @@ var _ = config.ProductConfiguration(ProductConfiguration{}) // MergeAdditionalProductProperties takes product properties from the provided reader and merges them with data from the // additionalProperties parameter. It also does some validation to ensure required fields are set. -func MergeAdditionalProductProperties(configFile io.Reader, additionalProperties map[string]interface{}) (io.Reader, error) { +func MergeAdditionalProductProperties(configFile io.Reader, additionalProperties map[string]any) (io.Reader, error) { yamlInput, err := io.ReadAll(configFile) if err != nil { return nil, err @@ -67,14 +67,14 @@ func MergeAdditionalProductProperties(configFile io.Reader, additionalProperties return modifiedConfigFile, nil } -func mergeProperties(minimalProperties, additionalProperties map[string]interface{}) map[string]interface{} { - combinedProperties := make(map[string]interface{}, len(minimalProperties)+len(additionalProperties)) +func mergeProperties(minimalProperties, additionalProperties map[string]any) map[string]any { + combinedProperties := make(map[string]any, len(minimalProperties)+len(additionalProperties)) for k, v := range minimalProperties { combinedProperties[k] = v } for k, v := range additionalProperties { - combinedProperties[k] = map[string]interface{}{ + combinedProperties[k] = map[string]any{ "value": v, } } diff --git a/pkg/planitest/internal/fakes/command_runner.go b/pkg/planitest/internal/fakes/command_runner.go index e64ca7ab1..15f707195 100644 --- a/pkg/planitest/internal/fakes/command_runner.go +++ b/pkg/planitest/internal/fakes/command_runner.go @@ -24,7 +24,7 @@ type CommandRunner struct { result2 string result3 error } - invocations map[string][][]interface{} + invocations map[string][][]any invocationsMutex sync.RWMutex } @@ -35,7 +35,7 @@ func (fake *CommandRunner) Run(arg1 string, arg2 ...string) (string, string, err arg1 string arg2 []string }{arg1, arg2}) - fake.recordInvocation("Run", []interface{}{arg1, arg2}) + fake.recordInvocation("Run", []any{arg1, arg2}) fake.runMutex.Unlock() if fake.RunStub != nil { return fake.RunStub(arg1, arg2...) @@ -95,26 +95,26 @@ func (fake *CommandRunner) RunReturnsOnCall(i int, result1 string, result2 strin }{result1, result2, result3} } -func (fake *CommandRunner) Invocations() map[string][][]interface{} { +func (fake *CommandRunner) Invocations() map[string][][]any { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() fake.runMutex.RLock() defer fake.runMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} + copiedInvocations := map[string][][]any{} for key, value := range fake.invocations { copiedInvocations[key] = value } return copiedInvocations } -func (fake *CommandRunner) recordInvocation(key string, args []interface{}) { +func (fake *CommandRunner) recordInvocation(key string, args []any) { fake.invocationsMutex.Lock() defer fake.invocationsMutex.Unlock() if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} + fake.invocations = map[string][][]any{} } if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} + fake.invocations[key] = [][]any{} } fake.invocations[key] = append(fake.invocations[key], args) } diff --git a/pkg/planitest/internal/fakes/file_io.go b/pkg/planitest/internal/fakes/file_io.go index 990469f03..8280f8dc5 100644 --- a/pkg/planitest/internal/fakes/file_io.go +++ b/pkg/planitest/internal/fakes/file_io.go @@ -34,7 +34,7 @@ type FileIO struct { result1 *os.File result2 error } - invocations map[string][][]interface{} + invocations map[string][][]any invocationsMutex sync.RWMutex } @@ -44,7 +44,7 @@ func (fake *FileIO) Remove(arg1 string) error { fake.removeArgsForCall = append(fake.removeArgsForCall, struct { arg1 string }{arg1}) - fake.recordInvocation("Remove", []interface{}{arg1}) + fake.recordInvocation("Remove", []any{arg1}) fake.removeMutex.Unlock() if fake.RemoveStub != nil { return fake.RemoveStub(arg1) @@ -105,7 +105,7 @@ func (fake *FileIO) TempFile(arg1 string, arg2 string) (*os.File, error) { arg1 string arg2 string }{arg1, arg2}) - fake.recordInvocation("TempFile", []interface{}{arg1, arg2}) + fake.recordInvocation("TempFile", []any{arg1, arg2}) fake.tempFileMutex.Unlock() if fake.TempFileStub != nil { return fake.TempFileStub(arg1, arg2) @@ -162,28 +162,28 @@ func (fake *FileIO) TempFileReturnsOnCall(i int, result1 *os.File, result2 error }{result1, result2} } -func (fake *FileIO) Invocations() map[string][][]interface{} { +func (fake *FileIO) Invocations() map[string][][]any { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() fake.removeMutex.RLock() defer fake.removeMutex.RUnlock() fake.tempFileMutex.RLock() defer fake.tempFileMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} + copiedInvocations := map[string][][]any{} for key, value := range fake.invocations { copiedInvocations[key] = value } return copiedInvocations } -func (fake *FileIO) recordInvocation(key string, args []interface{}) { +func (fake *FileIO) recordInvocation(key string, args []any) { fake.invocationsMutex.Lock() defer fake.invocationsMutex.Unlock() if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} + fake.invocations = map[string][][]any{} } if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} + fake.invocations[key] = [][]any{} } fake.invocations[key] = append(fake.invocations[key], args) } diff --git a/pkg/planitest/internal/fakes/om_runner.go b/pkg/planitest/internal/fakes/om_runner.go index b590534f0..a056d9872 100644 --- a/pkg/planitest/internal/fakes/om_runner.go +++ b/pkg/planitest/internal/fakes/om_runner.go @@ -21,17 +21,17 @@ type OMRunner struct { result1 internal.StagedProduct result2 error } - GetManifestStub func(string) (map[string]interface{}, error) + GetManifestStub func(string) (map[string]any, error) getManifestMutex sync.RWMutex getManifestArgsForCall []struct { arg1 string } getManifestReturns struct { - result1 map[string]interface{} + result1 map[string]any result2 error } getManifestReturnsOnCall map[int]struct { - result1 map[string]interface{} + result1 map[string]any result2 error } ResetAndConfigureStub func(string, string, string) error @@ -47,7 +47,7 @@ type OMRunner struct { resetAndConfigureReturnsOnCall map[int]struct { result1 error } - invocations map[string][][]interface{} + invocations map[string][][]any invocationsMutex sync.RWMutex } @@ -57,7 +57,7 @@ func (fake *OMRunner) FindStagedProduct(arg1 string) (internal.StagedProduct, er fake.findStagedProductArgsForCall = append(fake.findStagedProductArgsForCall, struct { arg1 string }{arg1}) - fake.recordInvocation("FindStagedProduct", []interface{}{arg1}) + fake.recordInvocation("FindStagedProduct", []any{arg1}) fake.findStagedProductMutex.Unlock() if fake.FindStagedProductStub != nil { return fake.FindStagedProductStub(arg1) @@ -114,13 +114,13 @@ func (fake *OMRunner) FindStagedProductReturnsOnCall(i int, result1 internal.Sta }{result1, result2} } -func (fake *OMRunner) GetManifest(arg1 string) (map[string]interface{}, error) { +func (fake *OMRunner) GetManifest(arg1 string) (map[string]any, error) { fake.getManifestMutex.Lock() ret, specificReturn := fake.getManifestReturnsOnCall[len(fake.getManifestArgsForCall)] fake.getManifestArgsForCall = append(fake.getManifestArgsForCall, struct { arg1 string }{arg1}) - fake.recordInvocation("GetManifest", []interface{}{arg1}) + fake.recordInvocation("GetManifest", []any{arg1}) fake.getManifestMutex.Unlock() if fake.GetManifestStub != nil { return fake.GetManifestStub(arg1) @@ -138,7 +138,7 @@ func (fake *OMRunner) GetManifestCallCount() int { return len(fake.getManifestArgsForCall) } -func (fake *OMRunner) GetManifestCalls(stub func(string) (map[string]interface{}, error)) { +func (fake *OMRunner) GetManifestCalls(stub func(string) (map[string]any, error)) { fake.getManifestMutex.Lock() defer fake.getManifestMutex.Unlock() fake.GetManifestStub = stub @@ -151,28 +151,28 @@ func (fake *OMRunner) GetManifestArgsForCall(i int) string { return argsForCall.arg1 } -func (fake *OMRunner) GetManifestReturns(result1 map[string]interface{}, result2 error) { +func (fake *OMRunner) GetManifestReturns(result1 map[string]any, result2 error) { fake.getManifestMutex.Lock() defer fake.getManifestMutex.Unlock() fake.GetManifestStub = nil fake.getManifestReturns = struct { - result1 map[string]interface{} + result1 map[string]any result2 error }{result1, result2} } -func (fake *OMRunner) GetManifestReturnsOnCall(i int, result1 map[string]interface{}, result2 error) { +func (fake *OMRunner) GetManifestReturnsOnCall(i int, result1 map[string]any, result2 error) { fake.getManifestMutex.Lock() defer fake.getManifestMutex.Unlock() fake.GetManifestStub = nil if fake.getManifestReturnsOnCall == nil { fake.getManifestReturnsOnCall = make(map[int]struct { - result1 map[string]interface{} + result1 map[string]any result2 error }) } fake.getManifestReturnsOnCall[i] = struct { - result1 map[string]interface{} + result1 map[string]any result2 error }{result1, result2} } @@ -185,7 +185,7 @@ func (fake *OMRunner) ResetAndConfigure(arg1 string, arg2 string, arg3 string) e arg2 string arg3 string }{arg1, arg2, arg3}) - fake.recordInvocation("ResetAndConfigure", []interface{}{arg1, arg2, arg3}) + fake.recordInvocation("ResetAndConfigure", []any{arg1, arg2, arg3}) fake.resetAndConfigureMutex.Unlock() if fake.ResetAndConfigureStub != nil { return fake.ResetAndConfigureStub(arg1, arg2, arg3) @@ -239,7 +239,7 @@ func (fake *OMRunner) ResetAndConfigureReturnsOnCall(i int, result1 error) { }{result1} } -func (fake *OMRunner) Invocations() map[string][][]interface{} { +func (fake *OMRunner) Invocations() map[string][][]any { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() fake.findStagedProductMutex.RLock() @@ -248,21 +248,21 @@ func (fake *OMRunner) Invocations() map[string][][]interface{} { defer fake.getManifestMutex.RUnlock() fake.resetAndConfigureMutex.RLock() defer fake.resetAndConfigureMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} + copiedInvocations := map[string][][]any{} for key, value := range fake.invocations { copiedInvocations[key] = value } return copiedInvocations } -func (fake *OMRunner) recordInvocation(key string, args []interface{}) { +func (fake *OMRunner) recordInvocation(key string, args []any) { fake.invocationsMutex.Lock() defer fake.invocationsMutex.Unlock() if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} + fake.invocations = map[string][][]any{} } if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} + fake.invocations[key] = [][]any{} } fake.invocations[key] = append(fake.invocations[key], args) } diff --git a/pkg/planitest/internal/fakes/ops_manifest_runner.go b/pkg/planitest/internal/fakes/ops_manifest_runner.go index 491ca63ef..bbdb987cd 100644 --- a/pkg/planitest/internal/fakes/ops_manifest_runner.go +++ b/pkg/planitest/internal/fakes/ops_manifest_runner.go @@ -8,32 +8,32 @@ import ( ) type OpsManifestRunner struct { - GetManifestStub func(string, string) (map[string]interface{}, error) + GetManifestStub func(string, string) (map[string]any, error) getManifestMutex sync.RWMutex getManifestArgsForCall []struct { arg1 string arg2 string } getManifestReturns struct { - result1 map[string]interface{} + result1 map[string]any result2 error } getManifestReturnsOnCall map[int]struct { - result1 map[string]interface{} + result1 map[string]any result2 error } - invocations map[string][][]interface{} + invocations map[string][][]any invocationsMutex sync.RWMutex } -func (fake *OpsManifestRunner) GetManifest(arg1 string, arg2 string) (map[string]interface{}, error) { +func (fake *OpsManifestRunner) GetManifest(arg1 string, arg2 string) (map[string]any, error) { fake.getManifestMutex.Lock() ret, specificReturn := fake.getManifestReturnsOnCall[len(fake.getManifestArgsForCall)] fake.getManifestArgsForCall = append(fake.getManifestArgsForCall, struct { arg1 string arg2 string }{arg1, arg2}) - fake.recordInvocation("GetManifest", []interface{}{arg1, arg2}) + fake.recordInvocation("GetManifest", []any{arg1, arg2}) fake.getManifestMutex.Unlock() if fake.GetManifestStub != nil { return fake.GetManifestStub(arg1, arg2) @@ -51,7 +51,7 @@ func (fake *OpsManifestRunner) GetManifestCallCount() int { return len(fake.getManifestArgsForCall) } -func (fake *OpsManifestRunner) GetManifestCalls(stub func(string, string) (map[string]interface{}, error)) { +func (fake *OpsManifestRunner) GetManifestCalls(stub func(string, string) (map[string]any, error)) { fake.getManifestMutex.Lock() defer fake.getManifestMutex.Unlock() fake.GetManifestStub = stub @@ -64,52 +64,52 @@ func (fake *OpsManifestRunner) GetManifestArgsForCall(i int) (string, string) { return argsForCall.arg1, argsForCall.arg2 } -func (fake *OpsManifestRunner) GetManifestReturns(result1 map[string]interface{}, result2 error) { +func (fake *OpsManifestRunner) GetManifestReturns(result1 map[string]any, result2 error) { fake.getManifestMutex.Lock() defer fake.getManifestMutex.Unlock() fake.GetManifestStub = nil fake.getManifestReturns = struct { - result1 map[string]interface{} + result1 map[string]any result2 error }{result1, result2} } -func (fake *OpsManifestRunner) GetManifestReturnsOnCall(i int, result1 map[string]interface{}, result2 error) { +func (fake *OpsManifestRunner) GetManifestReturnsOnCall(i int, result1 map[string]any, result2 error) { fake.getManifestMutex.Lock() defer fake.getManifestMutex.Unlock() fake.GetManifestStub = nil if fake.getManifestReturnsOnCall == nil { fake.getManifestReturnsOnCall = make(map[int]struct { - result1 map[string]interface{} + result1 map[string]any result2 error }) } fake.getManifestReturnsOnCall[i] = struct { - result1 map[string]interface{} + result1 map[string]any result2 error }{result1, result2} } -func (fake *OpsManifestRunner) Invocations() map[string][][]interface{} { +func (fake *OpsManifestRunner) Invocations() map[string][][]any { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() fake.getManifestMutex.RLock() defer fake.getManifestMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} + copiedInvocations := map[string][][]any{} for key, value := range fake.invocations { copiedInvocations[key] = value } return copiedInvocations } -func (fake *OpsManifestRunner) recordInvocation(key string, args []interface{}) { +func (fake *OpsManifestRunner) recordInvocation(key string, args []any) { fake.invocationsMutex.Lock() defer fake.invocationsMutex.Unlock() if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} + fake.invocations = map[string][][]any{} } if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} + fake.invocations[key] = [][]any{} } fake.invocations[key] = append(fake.invocations[key], args) } diff --git a/pkg/planitest/internal/fakes/render_service.go b/pkg/planitest/internal/fakes/render_service.go index 18cdce01c..2f92be93c 100644 --- a/pkg/planitest/internal/fakes/render_service.go +++ b/pkg/planitest/internal/fakes/render_service.go @@ -23,7 +23,7 @@ type RenderService struct { result1 string result2 error } - invocations map[string][][]interface{} + invocations map[string][][]any invocationsMutex sync.RWMutex } @@ -34,7 +34,7 @@ func (fake *RenderService) RenderManifest(arg1 io.Reader, arg2 io.Reader) (strin arg1 io.Reader arg2 io.Reader }{arg1, arg2}) - fake.recordInvocation("RenderManifest", []interface{}{arg1, arg2}) + fake.recordInvocation("RenderManifest", []any{arg1, arg2}) fake.renderManifestMutex.Unlock() if fake.RenderManifestStub != nil { return fake.RenderManifestStub(arg1, arg2) @@ -91,26 +91,26 @@ func (fake *RenderService) RenderManifestReturnsOnCall(i int, result1 string, re }{result1, result2} } -func (fake *RenderService) Invocations() map[string][][]interface{} { +func (fake *RenderService) Invocations() map[string][][]any { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() fake.renderManifestMutex.RLock() defer fake.renderManifestMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} + copiedInvocations := map[string][][]any{} for key, value := range fake.invocations { copiedInvocations[key] = value } return copiedInvocations } -func (fake *RenderService) recordInvocation(key string, args []interface{}) { +func (fake *RenderService) recordInvocation(key string, args []any) { fake.invocationsMutex.Lock() defer fake.invocationsMutex.Unlock() if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} + fake.invocations = map[string][][]any{} } if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} + fake.invocations[key] = [][]any{} } fake.invocations[key] = append(fake.invocations[key], args) } diff --git a/pkg/planitest/internal/internal.go b/pkg/planitest/internal/internal.go index 5877eae5d..9e8cdc67c 100644 --- a/pkg/planitest/internal/internal.go +++ b/pkg/planitest/internal/internal.go @@ -7,13 +7,13 @@ import ( //counterfeiter:generate ./fakes/om_runner.go --fake-name OMRunner . OMRunnerI type OMRunnerI interface { ResetAndConfigure(productName string, productVersion string, configJSON string) error - GetManifest(productGUID string) (map[string]interface{}, error) + GetManifest(productGUID string) (map[string]any, error) FindStagedProduct(productName string) (StagedProduct, error) } //counterfeiter:generate ./fakes/ops_manifest_runner.go --fake-name OpsManifestRunner . OpsManifestRunnerI type OpsManifestRunnerI interface { - GetManifest(productProperties, metadataFilePath string) (map[string]interface{}, error) + GetManifest(productProperties, metadataFilePath string) (map[string]any, error) } //counterfeiter:generate ./fakes/file_io.go --fake-name FileIO . FileIO diff --git a/pkg/planitest/internal/om_runner.go b/pkg/planitest/internal/om_runner.go index 5c8f24b18..40fc80249 100644 --- a/pkg/planitest/internal/om_runner.go +++ b/pkg/planitest/internal/om_runner.go @@ -18,7 +18,7 @@ type StagedProduct struct { } type stagedManifestResponse struct { - Manifest map[string]interface{} + Manifest map[string]any Errors OMError `json:"errors"` } @@ -122,7 +122,7 @@ func (o OMRunner) ResetAndConfigure(productName string, productVersion string, c return nil } -func (o OMRunner) GetManifest(productGUID string) (map[string]interface{}, error) { +func (o OMRunner) GetManifest(productGUID string) (map[string]any, error) { response, errOutput, err := o.cmdRunner.Run( "om", "--skip-ssl-validation", diff --git a/pkg/planitest/internal/om_runner_test.go b/pkg/planitest/internal/om_runner_test.go index ab7fc26d3..a12bde77c 100644 --- a/pkg/planitest/internal/om_runner_test.go +++ b/pkg/planitest/internal/om_runner_test.go @@ -258,10 +258,10 @@ network-properties: "--path", "/api/v0/staged/products/some-guid/manifest", })) - Expect(manifest).To(Equal(map[string]interface{}{ + Expect(manifest).To(Equal(map[string]any{ "name": "cf-some-guid", - "releases": []interface{}{ - map[string]interface{}{ + "releases": []any{ + map[string]any{ "name": "some-release", "version": "1.2.3", }, diff --git a/pkg/planitest/internal/om_service_test.go b/pkg/planitest/internal/om_service_test.go index 4d76564bb..9dad3bd06 100644 --- a/pkg/planitest/internal/om_service_test.go +++ b/pkg/planitest/internal/om_service_test.go @@ -64,7 +64,7 @@ product_version: 1.2.3 Type: "some-type", ProductVersion: "some-version", }, nil) - omRunner.GetManifestReturns(map[string]interface{}{ + omRunner.GetManifestReturns(map[string]any{ "some-key": "some-value", }, nil) }) diff --git a/pkg/planitest/internal/ops_manifest_runner.go b/pkg/planitest/internal/ops_manifest_runner.go index 38dd85773..bca0452d4 100644 --- a/pkg/planitest/internal/ops_manifest_runner.go +++ b/pkg/planitest/internal/ops_manifest_runner.go @@ -21,7 +21,7 @@ func NewOpsManifestRunner(cmdRunner CommandRunner, fileIO FileIO, additionalArgs } } -func (o OpsManifestRunner) GetManifest(productProperties, metadataFilePath string) (map[string]interface{}, error) { +func (o OpsManifestRunner) GetManifest(productProperties, metadataFilePath string) (map[string]any, error) { configFile, err := o.FileIO.TempFile("", "") configFileYML := fmt.Sprintf("%s.yml", configFile.Name()) _ = os.Rename(configFile.Name(), configFileYML) @@ -43,7 +43,7 @@ func (o OpsManifestRunner) GetManifest(productProperties, metadataFilePath strin return nil, fmt.Errorf("Unable to retrieve manifest: %s: %s", err, errOutput) } - var manifest map[string]interface{} + var manifest map[string]any err = yaml.Unmarshal([]byte(response), &manifest) if err != nil { return nil, fmt.Errorf("Unable to unmarshal yaml: %s", err) diff --git a/pkg/planitest/internal/ops_manifest_runner_test.go b/pkg/planitest/internal/ops_manifest_runner_test.go index a67644156..8550d0020 100644 --- a/pkg/planitest/internal/ops_manifest_runner_test.go +++ b/pkg/planitest/internal/ops_manifest_runner_test.go @@ -50,10 +50,10 @@ var _ = Describe("OMRunner", func() { Expect(args[2]).To(ContainSubstring("--metadata-path")) Expect(args[3]).To(ContainSubstring("some/metadata/path")) - Expect(manifest).To(Equal(map[string]interface{}{ + Expect(manifest).To(Equal(map[string]any{ "name": "cf-some-guid", - "releases": []interface{}{ - map[interface{}]interface{}{ + "releases": []any{ + map[any]any{ "name": "some-release", "version": "1.2.3", }, @@ -94,10 +94,10 @@ var _ = Describe("OMRunner", func() { Expect(args[6]).To(Equal("--tas-config-file")) Expect(args[7]).To(Equal(tasConfigPath)) - Expect(manifest).To(Equal(map[string]interface{}{ + Expect(manifest).To(Equal(map[string]any{ "name": "cf-some-guid", - "releases": []interface{}{ - map[interface{}]interface{}{ + "releases": []any{ + map[any]any{ "name": "some-release", "version": "1.2.3", }, diff --git a/pkg/planitest/internal/ops_manifest_service_test.go b/pkg/planitest/internal/ops_manifest_service_test.go index d4ae278d0..6b26af59a 100644 --- a/pkg/planitest/internal/ops_manifest_service_test.go +++ b/pkg/planitest/internal/ops_manifest_service_test.go @@ -29,7 +29,7 @@ var _ = Describe("OpsManifest Service", func() { Describe("RenderManifest", func() { It("calls ops-manifest to retrieve the manifest", func() { - opsManifestRunner.GetManifestReturns(map[string]interface{}{ + opsManifestRunner.GetManifestReturns(map[string]any{ "some-key": "some-value", }, nil) diff --git a/pkg/planitest/manifest.go b/pkg/planitest/manifest.go index f787f2a4a..36fc9c9a1 100644 --- a/pkg/planitest/manifest.go +++ b/pkg/planitest/manifest.go @@ -24,16 +24,16 @@ func (m Manifest) FindInstanceGroupJob(instanceGroup, job string) (Manifest, err return Manifest(content), nil } -func (m Manifest) Property(path string) (interface{}, error) { +func (m Manifest) Property(path string) (any, error) { return m.interpolate(fmt.Sprintf("/properties/%s", path)) } -func (m Manifest) Path(path string) (interface{}, error) { +func (m Manifest) Path(path string) (any, error) { return m.interpolate(path) } -func (m Manifest) interpolate(path string) (interface{}, error) { - var content interface{} +func (m Manifest) interpolate(path string) (any, error) { + var content any err := yaml.Unmarshal([]byte(m), &content) if err != nil { return "", fmt.Errorf("failed to parse manifest: %s", err) diff --git a/pkg/planitest/product_service.go b/pkg/planitest/product_service.go index ff30d18ad..e972851ee 100644 --- a/pkg/planitest/product_service.go +++ b/pkg/planitest/product_service.go @@ -67,7 +67,7 @@ func opsManifestAdditionalArgs() []string { return args } -func (p *ProductService) RenderManifest(additionalProperties map[string]interface{}) (Manifest, error) { +func (p *ProductService) RenderManifest(additionalProperties map[string]any) (Manifest, error) { _, err := p.config.ConfigFile.Seek(0, 0) if err != nil { return "", err diff --git a/pkg/proofing/install_time_verifier.go b/pkg/proofing/install_time_verifier.go index 18c67cfff..62e924396 100644 --- a/pkg/proofing/install_time_verifier.go +++ b/pkg/proofing/install_time_verifier.go @@ -1,7 +1,7 @@ package proofing type InstallTimeVerifier struct { - Ignorable bool `yaml:"ignorable,omitempty"` - Name string `yaml:"name"` - Properties interface{} `yaml:"properties"` // TODO: schema? + Ignorable bool `yaml:"ignorable,omitempty"` + Name string `yaml:"name"` + Properties any `yaml:"properties"` // TODO: schema? } diff --git a/pkg/proofing/job_type.go b/pkg/proofing/job_type.go index b18ac0893..3a640a247 100644 --- a/pkg/proofing/job_type.go +++ b/pkg/proofing/job_type.go @@ -5,8 +5,8 @@ type JobType struct { ResourceLabel string `yaml:"resource_label"` Description string `yaml:"description,omitempty"` - Manifest string `yaml:"manifest"` - MaxInFlight interface{} `yaml:"max_in_flight"` + Manifest string `yaml:"manifest"` + MaxInFlight any `yaml:"max_in_flight"` Canaries int `yaml:"canaries"` Serial bool `yaml:"serial,omitempty"` diff --git a/pkg/proofing/resource_definition.go b/pkg/proofing/resource_definition.go index 7c5f82db7..69ddc3e62 100644 --- a/pkg/proofing/resource_definition.go +++ b/pkg/proofing/resource_definition.go @@ -1,10 +1,10 @@ package proofing type ResourceDefinition struct { - Name string `yaml:"name"` - Default int `yaml:"default"` - Configurable bool `yaml:"configurable"` - Constraints interface{} `yaml:"constraints,omitempty"` // TODO: schema? + Name string `yaml:"name"` + Default int `yaml:"default"` + Configurable bool `yaml:"configurable"` + Constraints any `yaml:"constraints,omitempty"` // TODO: schema? // TODO: validations: https://github.com/pivotal-cf/installation/blob/039a2ef3f751ef5915c425da8150a29af4b764dd/web/app/models/persistence/metadata/resource_definition.rb#L9 } diff --git a/pkg/proofing/simple_property_blueprint.go b/pkg/proofing/simple_property_blueprint.go index b57f4f25c..167a7700a 100644 --- a/pkg/proofing/simple_property_blueprint.go +++ b/pkg/proofing/simple_property_blueprint.go @@ -3,8 +3,8 @@ package proofing type SimplePropertyBlueprint struct { Name string `yaml:"name"` Type string `yaml:"type"` - Default interface{} `yaml:"default"` // TODO: schema? - Constraints interface{} `yaml:"constraints"` // TODO: schema? + Default any `yaml:"default"` // TODO: schema? + Constraints any `yaml:"constraints"` // TODO: schema? Options []PropertyBlueprintOption `yaml:"options"` // TODO: schema? Configurable bool `yaml:"configurable"` Optional bool `yaml:"optional"` diff --git a/pkg/proofing/upgrade/breaking_changes_test.go b/pkg/proofing/upgrade/breaking_changes_test.go index 65e6cb11d..a04dd261a 100644 --- a/pkg/proofing/upgrade/breaking_changes_test.go +++ b/pkg/proofing/upgrade/breaking_changes_test.go @@ -194,7 +194,7 @@ func loadMetadataProperties(t *testing.T) (initial, patch proofing.ProductTempla return } -func readYAMLFile(t *testing.T, filePath string, data interface{}) { +func readYAMLFile(t *testing.T, filePath string, data any) { iBuf, err := os.ReadFile(filePath) if err != nil { t.Fatal(err) diff --git a/pkg/proofing/validation_error.go b/pkg/proofing/validation_error.go index 148a1df71..1cd07a075 100644 --- a/pkg/proofing/validation_error.go +++ b/pkg/proofing/validation_error.go @@ -7,11 +7,11 @@ import ( ) type ValidationError struct { - Kind interface{} + Kind any Message string } -func NewValidationError(kind interface{}, message string) ValidationError { +func NewValidationError(kind any, message string) ValidationError { return ValidationError{ Kind: kind, Message: message, @@ -23,7 +23,7 @@ func (ve ValidationError) Error() string { return fmt.Sprintf("%s %s", strings.ToLower(t.Name()), ve.Message) } -func ValidatePresence(err error, v interface{}, field string) error { +func ValidatePresence(err error, v any, field string) error { value := reflect.ValueOf(v).FieldByName(field) if value.Len() == 0 { validationError := NewValidationError(v, fmt.Sprintf("%s must be present", strings.ToLower(field))) diff --git a/pkg/proofing/variable.go b/pkg/proofing/variable.go index 0ae950e69..92dc21aee 100644 --- a/pkg/proofing/variable.go +++ b/pkg/proofing/variable.go @@ -1,7 +1,7 @@ package proofing type Variable struct { - Name string `yaml:"name"` - Options interface{} `yaml:"options,omitempty"` // TODO: schema? - Type string `yaml:"type"` + Name string `yaml:"name"` + Options any `yaml:"options,omitempty"` // TODO: schema? + Type string `yaml:"type"` } diff --git a/pkg/proofing/verifier_blueprint.go b/pkg/proofing/verifier_blueprint.go index bb01812ba..6979614ea 100644 --- a/pkg/proofing/verifier_blueprint.go +++ b/pkg/proofing/verifier_blueprint.go @@ -1,6 +1,6 @@ package proofing type VerifierBlueprint struct { - Name string `yaml:"name"` - Properties interface{} `yaml:"properties"` // TODO: schema? + Name string `yaml:"name"` + Properties any `yaml:"properties"` // TODO: schema? }