From 33d8ccb2ea2c2f112d8debb881af05dc92e0cce5 Mon Sep 17 00:00:00 2001 From: Chris Selzo Date: Fri, 23 Oct 2026 10:41:59 -0700 Subject: [PATCH 1/2] Add compile-time package fields to release manifest A trimmed compiled release lists the packages it omits under compile_time_packages, and each compiled package whose identity changes records its source fingerprint as original_fingerprint. Both fields are omitted when empty, so existing manifests marshal unchanged. Co-Authored-By: Claude Opus 5.5 --- release/manifest/release.go | 31 +++++++++----- release/manifest/release_test.go | 73 ++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 11 deletions(-) diff --git a/release/manifest/release.go b/release/manifest/release.go index e806cde6e7..0942620c4e 100644 --- a/release/manifest/release.go +++ b/release/manifest/release.go @@ -15,11 +15,12 @@ type Manifest struct { CommitHash string `yaml:"commit_hash"` UncommittedChanges bool `yaml:"uncommitted_changes"` - Jobs []JobRef `yaml:"jobs,omitempty"` - Packages []PackageRef `yaml:"packages,omitempty"` - CompiledPkgs []CompiledPackageRef `yaml:"compiled_packages,omitempty"` - License *LicenseRef `yaml:"license,omitempty"` - NoCompression bool `yaml:"no_compression"` + Jobs []JobRef `yaml:"jobs,omitempty"` + Packages []PackageRef `yaml:"packages,omitempty"` + CompiledPkgs []CompiledPackageRef `yaml:"compiled_packages,omitempty"` + CompileTimePackages []CompileTimePackageRef `yaml:"compile_time_packages,omitempty"` + License *LicenseRef `yaml:"license,omitempty"` + NoCompression bool `yaml:"no_compression"` } type JobRef struct { @@ -39,12 +40,20 @@ type PackageRef struct { } type CompiledPackageRef struct { - Name string `yaml:"name"` - Version string `yaml:"version"` // todo deprecate - Fingerprint string `yaml:"fingerprint"` - SHA1 string `yaml:"sha1"` - OSVersionSlug string `yaml:"stemcell"` - Dependencies []string `yaml:"dependencies"` + Name string `yaml:"name"` + Version string `yaml:"version"` // todo deprecate + Fingerprint string `yaml:"fingerprint"` + OriginalFingerprint string `yaml:"original_fingerprint,omitempty"` + SHA1 string `yaml:"sha1"` + OSVersionSlug string `yaml:"stemcell"` + Dependencies []string `yaml:"dependencies"` +} + +type CompileTimePackageRef struct { + Name string `yaml:"name"` + Version string `yaml:"version"` + Fingerprint string `yaml:"fingerprint"` + Dependencies []string `yaml:"dependencies"` } type LicenseRef struct { diff --git a/release/manifest/release_test.go b/release/manifest/release_test.go index afd6819fd3..51c62c494f 100644 --- a/release/manifest/release_test.go +++ b/release/manifest/release_test.go @@ -4,6 +4,7 @@ import ( fakesys "github.com/cloudfoundry/bosh-utils/system/fakes" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "gopkg.in/yaml.v3" . "github.com/cloudfoundry/bosh-cli/v7/release/manifest" ) @@ -41,6 +42,11 @@ packages: cGtnMS1mcA== version: !binary |- cGtnMS12ZXJzaW9u + +compiled_packages: +- name: compiled-pkg + fingerprint: compiled-fingerprint + sha1: compiled-sha1 `) Expect(err).ToNot(HaveOccurred()) @@ -54,5 +60,72 @@ packages: Expect(manifest.Packages[0].SHA1).To(Equal("pkg1-sha1")) Expect(manifest.Packages[0].Fingerprint).To(Equal("pkg1-fp")) Expect(manifest.Packages[0].Version).To(Equal("pkg1-version")) + Expect(manifest.CompileTimePackages).To(BeEmpty()) + Expect(manifest.CompiledPkgs[0].OriginalFingerprint).To(BeEmpty()) + }) + + It("decodes compile-time package metadata and original compiled package fingerprints", func() { + err := fs.WriteFileString("/release.yml", `--- +name: release +version: version +compile_time_packages: +- name: compile-pkg + version: compile-version + fingerprint: compile-fingerprint + dependencies: + - dependency +compiled_packages: +- name: compiled-pkg + version: compiled-version + fingerprint: compiled-fingerprint + original_fingerprint: original-fingerprint + sha1: compiled-sha1 + stemcell: ubuntu-jammy + dependencies: + - dependency +`) + Expect(err).NotTo(HaveOccurred()) + + manifest, err := NewManifestFromPath("/release.yml", fs) + Expect(err).NotTo(HaveOccurred()) + + Expect(manifest.CompileTimePackages).To(Equal([]CompileTimePackageRef{{ + Name: "compile-pkg", + Version: "compile-version", + Fingerprint: "compile-fingerprint", + Dependencies: []string{"dependency"}, + }})) + Expect(manifest.CompiledPkgs[0].OriginalFingerprint).To(Equal("original-fingerprint")) + }) + + It("omits compile-time package metadata and original fingerprints when empty", func() { + data, err := yaml.Marshal(Manifest{ + Name: "release", + Version: "version", + CompiledPkgs: []CompiledPackageRef{{Name: "compiled-pkg"}}, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(string(data)).NotTo(ContainSubstring("compile_time_packages:")) + Expect(string(data)).NotTo(ContainSubstring("original_fingerprint:")) + }) + + It("marshals compile-time package metadata and original fingerprints when set", func() { + manifest := Manifest{ + CompileTimePackages: []CompileTimePackageRef{{ + Name: "compile-pkg", + Version: "compile-version", + Fingerprint: "compile-fingerprint", + Dependencies: []string{"dependency"}, + }}, + CompiledPkgs: []CompiledPackageRef{{ + Name: "compiled-pkg", + OriginalFingerprint: "original-fingerprint", + }}, + } + + data, err := yaml.Marshal(manifest) + Expect(err).NotTo(HaveOccurred()) + Expect(string(data)).To(ContainSubstring("compile_time_packages:")) + Expect(string(data)).To(ContainSubstring("original_fingerprint: original-fingerprint")) }) }) From 2cf7369ee21ec3431b9fa6e289721cf165d5b444 Mon Sep 17 00:00:00 2001 From: Chris Selzo Date: Thu, 22 Oct 2026 18:42:53 -0700 Subject: [PATCH 2/2] Preserve compile-time package metadata across release rewrites compile_time_packages and original_fingerprint have no archive blob, so release rewrites such as sha2ify carry them from the source manifest into the rewritten one. Co-Authored-By: Claude Opus 5.5 --- cmd/inspect_local_release_test.go | 1 + cmd/redigest_release_test.go | 3 +- cmd/release_tables_test.go | 4 +- .../state/remote_package_compiler_test.go | 4 +- installation/pkg/compiler_test.go | 3 ++ release/archive_reader.go | 13 +++--- release/archive_reader_test.go | 14 +++++- release/archive_writer_test.go | 14 +++--- release/job/job_test.go | 8 ++-- release/manifest_reader.go | 11 +++-- release/manifest_reader_test.go | 22 ++++++++- release/pkg/compiled_package.go | 34 ++++++++------ release/pkg/compiled_package_test.go | 29 ++++++------ release/release.go | 46 ++++++++++--------- release/release_test.go | 19 ++++---- 15 files changed, 136 insertions(+), 89 deletions(-) diff --git a/cmd/inspect_local_release_test.go b/cmd/inspect_local_release_test.go index 08da2834fd..5b3809b451 100644 --- a/cmd/inspect_local_release_test.go +++ b/cmd/inspect_local_release_test.go @@ -62,6 +62,7 @@ var _ = Describe("InspectLocalReleaseCmd", func() { compiledPkg := boshpkg.NewCompiledPackageWithoutArchive( "compiled-pkg-name", "compiled-pkg-fp", + "", "my-fancy-linux/1.33.7", "compiled-pkg-digest", []string{"some-package"}, diff --git a/cmd/redigest_release_test.go b/cmd/redigest_release_test.go index a5b70d8e46..12c2311082 100644 --- a/cmd/redigest_release_test.go +++ b/cmd/redigest_release_test.go @@ -70,7 +70,7 @@ var _ = Describe("RedigestRelease", func() { } jobSha128 := boshjob.NewJob(NewResourceWithBuiltArchive("job-resource-1", "job-sha128-fp", job1ResourcePath, fileContentSha1)) packageSha128 := boshpkg.NewPackage(NewResourceWithBuiltArchive("pkg-resource-1", "pkg-sha128-fp", pkg1ResourcePath, fileContentSha1), nil) - compiledPackageSha128 := boshpkg.NewCompiledPackageWithArchive("compiledpkg-resource-1", "compiledpkg-sha128-fp", "1", compiledPackage1ResourcePath, fileContentSha1, nil) + compiledPackageSha128 := boshpkg.NewCompiledPackageWithArchive("compiledpkg-resource-1", "compiledpkg-sha128-fp", "original-compiledpkg-fp", "1", compiledPackage1ResourcePath, fileContentSha1, nil) fakeSha128Release.JobsReturns([]*boshjob.Job{jobSha128}) fakeSha128Release.PackagesReturns([]*boshpkg.Package{packageSha128}) @@ -137,6 +137,7 @@ var _ = Describe("RedigestRelease", func() { Expect(sha2ifyRelease.CompiledPackages()).To(HaveLen(1)) Expect(sha2ifyRelease.CompiledPackages()[0].ArchiveDigest()).To(Equal("sha256:compiledpkgsha256")) + Expect(sha2ifyRelease.CompiledPackages()[0].OriginalFingerprint()).To(Equal("original-compiledpkg-fp")) Expect(fmv.MoveCallCount()).To(Equal(1)) diff --git a/cmd/release_tables_test.go b/cmd/release_tables_test.go index 6274cf2d45..5f11ca08d6 100644 --- a/cmd/release_tables_test.go +++ b/cmd/release_tables_test.go @@ -122,11 +122,11 @@ var _ = Describe("ReleaseTables", func() { Context("when there are compiled packages", func() { BeforeEach(func() { compiledpkg := boshpkg.NewCompiledPackageWithoutArchive( - "compiledpkg-name", "compiledpkg-fp", "super-cool-linux/42.0", "compiledpkg-sha1", []string{"pkg1-name"}, + "compiledpkg-name", "compiledpkg-fp", "", "super-cool-linux/42.0", "compiledpkg-sha1", []string{"pkg1-name"}, ) compiledpkg2 := boshpkg.NewCompiledPackageWithoutArchive( - "compiledpkg2-name", "compiledpkg2-fp", "super-cool-linux", "compiledpkg2-sha1", []string{"pkg1-name"}, + "compiledpkg2-name", "compiledpkg2-fp", "", "super-cool-linux", "compiledpkg2-sha1", []string{"pkg1-name"}, ) release.CompiledPackagesReturns([]*boshpkg.CompiledPackage{compiledpkg, compiledpkg2}) diff --git a/deployment/instance/state/remote_package_compiler_test.go b/deployment/instance/state/remote_package_compiler_test.go index dfc188b680..ac8b369323 100644 --- a/deployment/instance/state/remote_package_compiler_test.go +++ b/deployment/instance/state/remote_package_compiler_test.go @@ -137,10 +137,10 @@ var _ = Describe("RemotePackageCompiler", func() { BeforeEach(func() { pkgDependency = boshpkg.NewCompiledPackageWithoutArchive( - "fake-package-name-dep", "fake-package-fingerprint-dep", "", "", nil) + "fake-package-name-dep", "fake-package-fingerprint-dep", "", "", "", nil) pkg = boshpkg.NewCompiledPackageWithArchive( - "fake-package-name", "fake-package-fingerprint", "", archivePath, "fake-source-package-sha1", []string{"fake-package-name-dep"}) + "fake-package-name", "fake-package-fingerprint", "", "", archivePath, "fake-source-package-sha1", []string{"fake-package-name-dep"}) err := pkg.AttachDependencies([]*boshpkg.CompiledPackage{pkgDependency}) Expect(err).ToNot(HaveOccurred()) }) diff --git a/installation/pkg/compiler_test.go b/installation/pkg/compiler_test.go index 39b8c0a9f5..b932ee0f8f 100644 --- a/installation/pkg/compiler_test.go +++ b/installation/pkg/compiler_test.go @@ -363,6 +363,7 @@ var _ = Describe("PackageCompiler", func() { compiledPkg = birelpkg.NewCompiledPackageWithArchive( "compiled-pkg1-name", "compiled-pkg1-fingerprint", + "", "compiled-pkg1-os-version-slug", "compiled-pkg1-path", "compiled-pkg1-sha1", @@ -371,6 +372,7 @@ var _ = Describe("PackageCompiler", func() { dependency1 = birelpkg.NewCompiledPackageWithArchive( "compiled-pkg1-dep1-name", "compiled-pkg1-dep1-fingerprint", + "", "compiled-pkg1-dep1-os-version-slug", "compiled-pkg1-dep1-path", "compiled-pkg1-dep1-sha1", @@ -379,6 +381,7 @@ var _ = Describe("PackageCompiler", func() { dependency2 = birelpkg.NewCompiledPackageWithArchive( "compiled-pkg1-dep2-name", "compiled-pkg1-dep2-fingerprint", + "", "compiled-pkg1-dep2-os-version-slug", "compiled-pkg1-dep2-path", "compiled-pkg1-dep2-sha1", diff --git a/release/archive_reader.go b/release/archive_reader.go index fdb83a0ed2..d68b9836ff 100644 --- a/release/archive_reader.go +++ b/release/archive_reader.go @@ -114,11 +114,12 @@ func (r ArchiveReader) newRelease(manifest boshman.Manifest, extractPath string) commitHash: manifest.CommitHash, uncommittedChanges: manifest.UncommittedChanges, - jobs: jobs, - packages: packages, - compiledPkgs: compiledPkgs, - license: license, - noCompression: manifest.NoCompression, + jobs: jobs, + packages: packages, + compiledPkgs: compiledPkgs, + compileTimePkgs: manifest.CompileTimePackages, + license: license, + noCompression: manifest.NoCompression, extractedPath: extractPath, fs: r.fs, @@ -194,7 +195,7 @@ func (r ArchiveReader) newCompiledPackages(refs []boshman.CompiledPackageRef, ex archivePath := filepath.Join(extractPath, "compiled_packages", ref.Name+".tgz") compiledPkg := boshpkg.NewCompiledPackageWithArchive( - ref.Name, ref.Fingerprint, ref.OSVersionSlug, archivePath, ref.SHA1, ref.Dependencies) + ref.Name, ref.Fingerprint, ref.OriginalFingerprint, ref.OSVersionSlug, archivePath, ref.SHA1, ref.Dependencies) compiledPkgs = append(compiledPkgs, compiledPkg) } diff --git a/release/archive_reader_test.go b/release/archive_reader_test.go index 588c45168b..cf98bbf311 100644 --- a/release/archive_reader_test.go +++ b/release/archive_reader_test.go @@ -251,10 +251,17 @@ compiled_packages: - name: pkg1 version: pkg1-version fingerprint: pkg1-fp + original_fingerprint: original-pkg1-fp stemcell: pkg1-stemcell sha1: pkg1-sha dependencies: [pkg2] +compile_time_packages: +- name: compile-time-pkg + version: compile-time-version + fingerprint: compile-time-fingerprint + dependencies: [pkg1] + license: version: lic-version fingerprint: lic-fp @@ -273,10 +280,10 @@ license: job2 := boshjob.NewJob(NewResource("job2", "job2-fp", nil)) compiledPkg1 := boshpkg.NewCompiledPackageWithArchive( - "pkg1", "pkg1-fp", "pkg1-stemcell", + "pkg1", "pkg1-fp", "original-pkg1-fp", "pkg1-stemcell", filepath.Join("/", "extracted", "release", "compiled_packages", "pkg1.tgz"), "pkg1-sha", []string{"pkg2"}) compiledPkg2 := boshpkg.NewCompiledPackageWithArchive( - "pkg2", "pkg2-fp", "pkg2-stemcell", + "pkg2", "pkg2-fp", "", "pkg2-stemcell", filepath.Join("/", "extracted", "release", "compiled_packages", "pkg2.tgz"), "pkg2-sha", nil) err := compiledPkg1.AttachDependencies([]*boshpkg.CompiledPackage{compiledPkg2}) Expect(err).ToNot(HaveOccurred()) @@ -318,6 +325,9 @@ license: Expect(release.Packages()).To(BeEmpty()) Expect(release.CompiledPackages()).To(Equal( []*boshpkg.CompiledPackage{compiledPkg2, compiledPkg1})) + Expect(release.CompiledPackages()[1].OriginalFingerprint()).To(Equal("original-pkg1-fp")) + Expect(release.CopyWith(nil, nil, nil, nil).Manifest().CompileTimePackages).To(HaveLen(1)) + Expect(release.CopyWith(nil, nil, nil, nil).Manifest().CompileTimePackages[0].Name).To(Equal("compile-time-pkg")) Expect(release.IsCompiled()).To(BeTrue()) Expect(release.License()).To(Equal(lic)) diff --git a/release/archive_writer_test.go b/release/archive_writer_test.go index c9c5d542e0..81d92948c7 100644 --- a/release/archive_writer_test.go +++ b/release/archive_writer_test.go @@ -249,8 +249,8 @@ no_compression: true Expect(err).ToNot(HaveOccurred()) release.CompiledPackagesReturns([]*boshpkg.CompiledPackage{ - boshpkg.NewCompiledPackageWithArchive("cp1", "", "", filepath.Join("/", "tmp", "cp1.tgz"), "", nil), - boshpkg.NewCompiledPackageWithArchive("cp2", "", "", filepath.Join("/", "tmp", "cp2.tgz"), "", nil), + boshpkg.NewCompiledPackageWithArchive("cp1", "", "", "", filepath.Join("/", "tmp", "cp1.tgz"), "", nil), + boshpkg.NewCompiledPackageWithArchive("cp2", "", "", "", filepath.Join("/", "tmp", "cp2.tgz"), "", nil), }) err = fs.WriteFileString(filepath.Join("/", "tmp", "lic.tgz"), "license-content") @@ -417,8 +417,8 @@ no_compression: true Expect(err).ToNot(HaveOccurred()) release.CompiledPackagesReturns([]*boshpkg.CompiledPackage{ - boshpkg.NewCompiledPackageWithArchive("cp1", "", "", filepath.Join("/", "tmp", "cp1.tgz"), "", nil), - boshpkg.NewCompiledPackageWithArchive("cp2", "", "", filepath.Join("/", "tmp", "cp2.tgz"), "", nil), + boshpkg.NewCompiledPackageWithArchive("cp1", "", "", "", filepath.Join("/", "tmp", "cp1.tgz"), "", nil), + boshpkg.NewCompiledPackageWithArchive("cp2", "", "", "", filepath.Join("/", "tmp", "cp2.tgz"), "", nil), }) compressor.CompressSpecificFilesInDirCallBack = func() { @@ -445,8 +445,8 @@ no_compression: true Expect(err).ToNot(HaveOccurred()) release.CompiledPackagesReturns([]*boshpkg.CompiledPackage{ - boshpkg.NewCompiledPackageWithArchive("cp1", "cp1-fp", "", filepath.Join("/", "tmp", "cp1.tgz"), "", nil), - boshpkg.NewCompiledPackageWithArchive("cp2", "cp2-fp", "", filepath.Join("/", "tmp", "cp2.tgz"), "", nil), + boshpkg.NewCompiledPackageWithArchive("cp1", "cp1-fp", "", "", filepath.Join("/", "tmp", "cp1.tgz"), "", nil), + boshpkg.NewCompiledPackageWithArchive("cp2", "cp2-fp", "", "", filepath.Join("/", "tmp", "cp2.tgz"), "", nil), }) compressor.CompressSpecificFilesInDirCallBack = func() { @@ -467,7 +467,7 @@ no_compression: true fs.CopyFileError = errors.New("fake-err") release.CompiledPackagesReturns([]*boshpkg.CompiledPackage{ - boshpkg.NewCompiledPackageWithArchive("cp1", "", "", filepath.Join("/", "tmp", "cp1.tgz"), "", nil), + boshpkg.NewCompiledPackageWithArchive("cp1", "", "", "", filepath.Join("/", "tmp", "cp1.tgz"), "", nil), }) _, err := act() diff --git a/release/job/job_test.go b/release/job/job_test.go index 1f6eb5c703..4d01be9950 100644 --- a/release/job/job_test.go +++ b/release/job/job_test.go @@ -98,9 +98,9 @@ var _ = Describe("Job", func() { job := NewJob(NewResource("name", "fp", nil)) job.PackageNames = []string{"pkg1", "pkg2"} - pkg1 := boshpkg.NewCompiledPackageWithArchive("pkg1", "fp", "", "path", "sha1", nil) - pkg2 := boshpkg.NewCompiledPackageWithArchive("pkg2", "fp", "", "path", "sha1", nil) - unusedPkg := boshpkg.NewCompiledPackageWithArchive("unused", "fp", "", "path", "sha1", nil) + pkg1 := boshpkg.NewCompiledPackageWithArchive("pkg1", "fp", "", "", "path", "sha1", nil) + pkg2 := boshpkg.NewCompiledPackageWithArchive("pkg2", "fp", "", "", "path", "sha1", nil) + unusedPkg := boshpkg.NewCompiledPackageWithArchive("unused", "fp", "", "", "path", "sha1", nil) err := job.AttachCompilablePackages([]boshpkg.Compilable{pkg1, unusedPkg, pkg2}) Expect(err).ToNot(HaveOccurred()) @@ -112,7 +112,7 @@ var _ = Describe("Job", func() { job := NewJob(NewResource("name", "fp", nil)) job.PackageNames = []string{"pkg1"} - pkg2 := boshpkg.NewCompiledPackageWithArchive("pkg2", "fp", "", "path", "sha1", nil) + pkg2 := boshpkg.NewCompiledPackageWithArchive("pkg2", "fp", "", "", "path", "sha1", nil) err := job.AttachCompilablePackages([]boshpkg.Compilable{pkg2}) Expect(err).To(HaveOccurred()) diff --git a/release/manifest_reader.go b/release/manifest_reader.go index 48276f06de..f2d36f23ac 100644 --- a/release/manifest_reader.go +++ b/release/manifest_reader.go @@ -75,10 +75,11 @@ func (r ManifestReader) newRelease(manifest boshman.Manifest) (Release, error) { commitHash: manifest.CommitHash, uncommittedChanges: manifest.UncommittedChanges, - jobs: jobs, - packages: packages, - compiledPkgs: compiledPkgs, - license: license, + jobs: jobs, + packages: packages, + compiledPkgs: compiledPkgs, + compileTimePkgs: manifest.CompileTimePackages, + license: license, fs: r.fs, } @@ -137,7 +138,7 @@ func (r ManifestReader) newCompiledPackages(refs []boshman.CompiledPackageRef) ( for _, ref := range refs { compiledPkg := boshpkg.NewCompiledPackageWithoutArchive( - ref.Name, ref.Fingerprint, ref.OSVersionSlug, ref.SHA1, ref.Dependencies) + ref.Name, ref.Fingerprint, ref.OriginalFingerprint, ref.OSVersionSlug, ref.SHA1, ref.Dependencies) compiledPkgs = append(compiledPkgs, compiledPkg) } diff --git a/release/manifest_reader_test.go b/release/manifest_reader_test.go index cfa7fa6d61..a3957323f6 100644 --- a/release/manifest_reader_test.go +++ b/release/manifest_reader_test.go @@ -140,10 +140,17 @@ compiled_packages: - name: pkg1 version: pkg1-version fingerprint: pkg1-fp + original_fingerprint: original-pkg1-fp stemcell: pkg1-stemcell sha1: pkg1-sha dependencies: [pkg2] +compile_time_packages: +- name: compile-time-pkg + version: compile-time-version + fingerprint: compile-time-fingerprint + dependencies: [pkg1] + license: version: lic-version fingerprint: lic-fp @@ -158,9 +165,9 @@ license: job2 := boshjob.NewJob(NewExistingResource("job2", "job2-fp", "job2-sha")) compiledPkg1 := boshpkg.NewCompiledPackageWithoutArchive( - "pkg1", "pkg1-fp", "pkg1-stemcell", "pkg1-sha", []string{"pkg2"}) + "pkg1", "pkg1-fp", "original-pkg1-fp", "pkg1-stemcell", "pkg1-sha", []string{"pkg2"}) compiledPkg2 := boshpkg.NewCompiledPackageWithoutArchive( - "pkg2", "pkg2-fp", "pkg2-stemcell", "pkg2-sha", nil) + "pkg2", "pkg2-fp", "", "pkg2-stemcell", "pkg2-sha", nil) err = compiledPkg1.AttachDependencies([]*boshpkg.CompiledPackage{compiledPkg2}) Expect(err).ToNot(HaveOccurred()) @@ -176,6 +183,17 @@ license: Expect(release.Packages()).To(BeEmpty()) Expect(release.CompiledPackages()).To(Equal( []*boshpkg.CompiledPackage{compiledPkg2, compiledPkg1})) + Expect(release.Manifest().CompiledPkgs[1].OriginalFingerprint).To(Equal("original-pkg1-fp")) + Expect(release.Manifest().CompileTimePackages).To(HaveLen(1)) + Expect(release.Manifest().CompileTimePackages[0].Name).To(Equal("compile-time-pkg")) + rehashedPkg1 := boshpkg.NewCompiledPackageWithoutArchive( + compiledPkg1.Name(), compiledPkg1.Fingerprint(), compiledPkg1.OriginalFingerprint(), + compiledPkg1.OSVersionSlug(), "sha256:pkg1-sha256", compiledPkg1.DependencyNames()) + copiedRelease := release.CopyWith(release.Jobs(), release.Packages(), release.License(), []*boshpkg.CompiledPackage{compiledPkg2, rehashedPkg1}) + copiedManifest := copiedRelease.Manifest() + Expect(copiedManifest.CompileTimePackages).To(Equal(release.Manifest().CompileTimePackages)) + Expect(copiedManifest.CompiledPkgs[1].SHA1).To(Equal("sha256:pkg1-sha256")) + Expect(copiedManifest.CompiledPkgs[1].OriginalFingerprint).To(Equal("original-pkg1-fp")) Expect(release.IsCompiled()).To(BeTrue()) Expect(release.License()).To(Equal(lic)) }) diff --git a/release/pkg/compiled_package.go b/release/pkg/compiled_package.go index 997f74671d..62dead7560 100644 --- a/release/pkg/compiled_package.go +++ b/release/pkg/compiled_package.go @@ -11,9 +11,10 @@ import ( ) type CompiledPackage struct { - name string - fingerprint string - osVersionSlug string + name string + fingerprint string + originalFingerprint string + osVersionSlug string Dependencies []*CompiledPackage // todo privatize dependencyNames []string @@ -22,23 +23,25 @@ type CompiledPackage struct { archiveDigest string } -func NewCompiledPackageWithoutArchive(name, fp, osVersionSlug, sha1 string, dependencyNames []string) *CompiledPackage { +func NewCompiledPackageWithoutArchive(name, fp, originalFingerprint, osVersionSlug, sha1 string, dependencyNames []string) *CompiledPackage { return &CompiledPackage{ - name: name, - fingerprint: fp, - osVersionSlug: osVersionSlug, - archiveDigest: sha1, + name: name, + fingerprint: fp, + originalFingerprint: originalFingerprint, + osVersionSlug: osVersionSlug, + archiveDigest: sha1, Dependencies: []*CompiledPackage{}, dependencyNames: dependencyNames, } } -func NewCompiledPackageWithArchive(name, fp, osVersionSlug, path, sha1 string, dependencyNames []string) *CompiledPackage { +func NewCompiledPackageWithArchive(name, fp, originalFingerprint, osVersionSlug, path, sha1 string, dependencyNames []string) *CompiledPackage { return &CompiledPackage{ - name: name, - fingerprint: fp, - osVersionSlug: osVersionSlug, + name: name, + fingerprint: fp, + originalFingerprint: originalFingerprint, + osVersionSlug: osVersionSlug, archivePath: path, archiveDigest: sha1, @@ -50,9 +53,10 @@ func NewCompiledPackageWithArchive(name, fp, osVersionSlug, path, sha1 string, d func (p CompiledPackage) String() string { return p.Name() } -func (p CompiledPackage) Name() string { return p.name } -func (p CompiledPackage) Fingerprint() string { return p.fingerprint } -func (p CompiledPackage) OSVersionSlug() string { return p.osVersionSlug } +func (p CompiledPackage) Name() string { return p.name } +func (p CompiledPackage) Fingerprint() string { return p.fingerprint } +func (p CompiledPackage) OriginalFingerprint() string { return p.originalFingerprint } +func (p CompiledPackage) OSVersionSlug() string { return p.osVersionSlug } func (p CompiledPackage) ArchivePath() string { if len(p.archivePath) == 0 { diff --git a/release/pkg/compiled_package_test.go b/release/pkg/compiled_package_test.go index a0906c0142..882959f80a 100644 --- a/release/pkg/compiled_package_test.go +++ b/release/pkg/compiled_package_test.go @@ -21,13 +21,14 @@ var _ = Describe("NewCompiledPackageWithoutArchive", func() { BeforeEach(func() { compiledPkg = NewCompiledPackageWithoutArchive( - "name", "fp", "os-slug", "sha1", []string{"pkg1", "pkg2"}) + "name", "fp", "original-fp", "os-slug", "sha1", []string{"pkg1", "pkg2"}) }) Describe("common methods", func() { It("returns values", func() { Expect(compiledPkg.Name()).To(Equal("name")) Expect(compiledPkg.Fingerprint()).To(Equal("fp")) + Expect(compiledPkg.OriginalFingerprint()).To(Equal("original-fp")) Expect(compiledPkg.OSVersionSlug()).To(Equal("os-slug")) Expect(func() { compiledPkg.ArchivePath() }).To(Panic()) @@ -39,9 +40,9 @@ var _ = Describe("NewCompiledPackageWithoutArchive", func() { Describe("AttachDependencies", func() { It("attaches dependencies based on their names", func() { - pkg1 := NewCompiledPackageWithoutArchive("pkg1", "fp", "os-slug", "sha1", nil) - pkg2 := NewCompiledPackageWithoutArchive("pkg2", "fp", "os-slug", "sha1", nil) - unusedPkg := NewCompiledPackageWithoutArchive("unused", "fp", "os-slug", "sha1", nil) + pkg1 := NewCompiledPackageWithoutArchive("pkg1", "fp", "", "os-slug", "sha1", nil) + pkg2 := NewCompiledPackageWithoutArchive("pkg2", "fp", "", "os-slug", "sha1", nil) + unusedPkg := NewCompiledPackageWithoutArchive("unused", "fp", "", "os-slug", "sha1", nil) err := compiledPkg.AttachDependencies([]*CompiledPackage{pkg1, unusedPkg, pkg2}) Expect(err).ToNot(HaveOccurred()) @@ -50,7 +51,7 @@ var _ = Describe("NewCompiledPackageWithoutArchive", func() { }) It("returns error if dependency cannot be found", func() { - pkg2 := NewCompiledPackageWithoutArchive("pkg2", "fp", "os-slug", "sha1", nil) + pkg2 := NewCompiledPackageWithoutArchive("pkg2", "fp", "", "os-slug", "sha1", nil) err := compiledPkg.AttachDependencies([]*CompiledPackage{pkg2}) Expect(err).To(HaveOccurred()) @@ -71,13 +72,14 @@ var _ = Describe("NewCompiledPackageWithArchive", func() { BeforeEach(func() { fakeFileContentSha1 = "" compiledPkg = NewCompiledPackageWithArchive( - "name", "fp", "os-slug", "path", "sha1", []string{"pkg1", "pkg2"}) + "name", "fp", "original-fp", "os-slug", "path", "sha1", []string{"pkg1", "pkg2"}) }) Describe("common methods", func() { It("returns values", func() { Expect(compiledPkg.Name()).To(Equal("name")) Expect(compiledPkg.Fingerprint()).To(Equal("fp")) + Expect(compiledPkg.OriginalFingerprint()).To(Equal("original-fp")) Expect(compiledPkg.OSVersionSlug()).To(Equal("os-slug")) Expect(compiledPkg.ArchivePath()).To(Equal("path")) @@ -89,9 +91,9 @@ var _ = Describe("NewCompiledPackageWithArchive", func() { Describe("AttachDependencies", func() { It("attaches dependencies based on their names", func() { - pkg1 := NewCompiledPackageWithArchive("pkg1", "fp", "os-slug", "path", "sha1", nil) - pkg2 := NewCompiledPackageWithArchive("pkg2", "fp", "os-slug", "path", "sha1", nil) - unusedPkg := NewCompiledPackageWithArchive("unused", "fp", "os-slug", "path", "sha1", nil) + pkg1 := NewCompiledPackageWithArchive("pkg1", "fp", "", "os-slug", "path", "sha1", nil) + pkg2 := NewCompiledPackageWithArchive("pkg2", "fp", "", "os-slug", "path", "sha1", nil) + unusedPkg := NewCompiledPackageWithArchive("unused", "fp", "", "os-slug", "path", "sha1", nil) err := compiledPkg.AttachDependencies([]*CompiledPackage{pkg1, unusedPkg, pkg2}) Expect(err).ToNot(HaveOccurred()) @@ -100,7 +102,7 @@ var _ = Describe("NewCompiledPackageWithArchive", func() { }) It("returns error if dependency cannot be found", func() { - pkg2 := NewCompiledPackageWithArchive("pkg2", "fp", "os-slug", "path", "sha1", nil) + pkg2 := NewCompiledPackageWithArchive("pkg2", "fp", "", "os-slug", "path", "sha1", nil) err := compiledPkg.AttachDependencies([]*CompiledPackage{pkg2}) Expect(err).To(HaveOccurred()) @@ -130,13 +132,14 @@ var _ = Describe("NewCompiledPackageWithArchive", func() { fakeArchiveReader.OpenFileReturns(fakeFile, nil) compiledPkg = NewCompiledPackageWithArchive( - "name", "fp", "os-slug", "path", fakeFileContentSha1, []string{"pkg1", "pkg2"}) + "name", "fp", "original-fp", "os-slug", "path", fakeFileContentSha1, []string{"pkg1", "pkg2"}) }) It("returns new compiled package with sha 256 digest", func() { newCompiledPkg, err := compiledPkg.RehashWithCalculator(fakeDigestCalculator, fakeArchiveReader) Expect(err).ToNot(HaveOccurred()) Expect(newCompiledPkg.ArchiveDigest()).To(Equal("sha256:compiledpkgsha256")) + Expect(newCompiledPkg.OriginalFingerprint()).To(Equal("original-fp")) }) }) @@ -168,7 +171,7 @@ var _ = Describe("NewCompiledPackageWithArchive", func() { Context("When digest calculator fails to calculate digest", func() { BeforeEach(func() { compiledPkg = NewCompiledPackageWithArchive( - "name", "fp", "os-slug", "path", fakeFileContentSha1, []string{"pkg1", "pkg2"}) + "name", "fp", "original-fp", "os-slug", "path", fakeFileContentSha1, []string{"pkg1", "pkg2"}) fakeArchiveReader.OpenFileReturns(fakeFile, nil) @@ -195,7 +198,7 @@ var _ = Describe("NewCompiledPackageWithArchive", func() { fakeArchiveReader.OpenFileReturns(fakeFile, nil) compiledPkg = NewCompiledPackageWithArchive( - "name", "fp", "os-slug", "path", "", []string{"pkg1", "pkg2"}) + "name", "fp", "original-fp", "os-slug", "path", "", []string{"pkg1", "pkg2"}) }) It("returns an error parsing the current digest", func() { diff --git a/release/release.go b/release/release.go index fb2b7403ca..b103f1ca27 100644 --- a/release/release.go +++ b/release/release.go @@ -17,11 +17,12 @@ type release struct { commitHash string uncommittedChanges bool - jobs []*bireljob.Job - packages []*birelpkg.Package - compiledPkgs []*birelpkg.CompiledPackage - license *birellic.License - noCompression bool + jobs []*bireljob.Job + packages []*birelpkg.Package + compiledPkgs []*birelpkg.CompiledPackage + compileTimePkgs []birelman.CompileTimePackageRef + license *birellic.License + noCompression bool extractedPath string fs boshsys.FileSystem @@ -120,12 +121,13 @@ func (r *release) Manifest() birelman.Manifest { for _, compiledPkg := range r.CompiledPackages() { compiledPkgRefs = append(compiledPkgRefs, birelman.CompiledPackageRef{ - Name: compiledPkg.Name(), - Version: compiledPkg.Fingerprint(), - Fingerprint: compiledPkg.Fingerprint(), - SHA1: compiledPkg.ArchiveDigest(), - OSVersionSlug: compiledPkg.OSVersionSlug(), - Dependencies: compiledPkg.DependencyNames(), + Name: compiledPkg.Name(), + Version: compiledPkg.Fingerprint(), + Fingerprint: compiledPkg.Fingerprint(), + OriginalFingerprint: compiledPkg.OriginalFingerprint(), + SHA1: compiledPkg.ArchiveDigest(), + OSVersionSlug: compiledPkg.OSVersionSlug(), + Dependencies: compiledPkg.DependencyNames(), }) } @@ -148,11 +150,12 @@ func (r *release) Manifest() birelman.Manifest { CommitHash: r.commitHash, UncommittedChanges: r.uncommittedChanges, - Jobs: jobRefs, - Packages: packageRefs, - CompiledPkgs: compiledPkgRefs, - License: licenseRef, - NoCompression: r.noCompression, + Jobs: jobRefs, + Packages: packageRefs, + CompiledPkgs: compiledPkgRefs, + CompileTimePackages: r.compileTimePkgs, + License: licenseRef, + NoCompression: r.noCompression, } } @@ -236,11 +239,12 @@ func (r *release) CopyWith(jobs []*bireljob.Job, packages []*birelpkg.Package, l commitHash: r.commitHash, uncommittedChanges: r.uncommittedChanges, - jobs: jobs, - packages: packages, - compiledPkgs: compiledPkgs, - license: license, - noCompression: r.noCompression, + jobs: jobs, + packages: packages, + compiledPkgs: compiledPkgs, + compileTimePkgs: r.compileTimePkgs, + license: license, + noCompression: r.noCompression, extractedPath: r.extractedPath, fs: r.fs, diff --git a/release/release_test.go b/release/release_test.go index 46fb081b74..b3355f50a1 100644 --- a/release/release_test.go +++ b/release/release_test.go @@ -76,7 +76,7 @@ var _ = Describe("Release", func() { compiledPkgs := []*boshpkg.CompiledPackage{ boshpkg.NewCompiledPackageWithoutArchive( - "name", "fp", "os-slug", "sha1", []string{"pkg1", "pkg2"}), + "name", "fp", "", "os-slug", "sha1", []string{"pkg1", "pkg2"}), } license := boshlic.NewLicense(NewResource("license", "", nil)) @@ -96,7 +96,7 @@ var _ = Describe("Release", func() { It("returns whether or not release has compiled packages", func() { compiledPkgs := []*boshpkg.CompiledPackage{ boshpkg.NewCompiledPackageWithoutArchive( - "name", "fp", "os-slug", "sha1", []string{"pkg1", "pkg2"}), + "name", "fp", "", "os-slug", "sha1", []string{"pkg1", "pkg2"}), } release = NewRelease("", "", "", true, nil, nil, compiledPkgs, nil, false, "", fs) @@ -146,7 +146,7 @@ var _ = Describe("Release", func() { compiledPkgs := []*boshpkg.CompiledPackage{ boshpkg.NewCompiledPackageWithoutArchive( - "cp", "cp-fp", "cp-os-slug", "cp-sha1", []string{"pkg1", "pkg2"}), + "cp", "cp-fp", "original-cp-fp", "cp-os-slug", "cp-sha1", []string{"pkg1", "pkg2"}), } license := boshlic.NewLicense(NewExistingResource("license", "lic-fp", "lic-sha1")) @@ -178,12 +178,13 @@ var _ = Describe("Release", func() { }, CompiledPkgs: []boshman.CompiledPackageRef{ { - Name: "cp", - Version: "cp-fp", - Fingerprint: "cp-fp", - SHA1: "cp-sha1", - OSVersionSlug: "cp-os-slug", - Dependencies: []string{"pkg1", "pkg2"}, + Name: "cp", + Version: "cp-fp", + Fingerprint: "cp-fp", + OriginalFingerprint: "original-cp-fp", + SHA1: "cp-sha1", + OSVersionSlug: "cp-os-slug", + Dependencies: []string{"pkg1", "pkg2"}, }, }, License: &boshman.LicenseRef{