api: introduce TransformLegacyRevision helper
This allows consumers to better handle the transition to the new
RFC-0005 format ("/" -> "@" separation).
Signed-off-by: Hidde Beydals <hello@hidde.co>
			
			
This commit is contained in:
		
							parent
							
								
									469c9387ee
								
							
						
					
					
						commit
						eaa4a4ff31
					
				|  | @ -18,6 +18,7 @@ package v1beta2 | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"path" | 	"path" | ||||||
|  | 	"regexp" | ||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
|  | @ -72,7 +73,7 @@ func (in *Artifact) HasRevision(revision string) bool { | ||||||
| 	if in == nil { | 	if in == nil { | ||||||
| 		return false | 		return false | ||||||
| 	} | 	} | ||||||
| 	return in.Revision == revision | 	return TransformLegacyRevision(in.Revision) == TransformLegacyRevision(revision) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // HasChecksum returns if the given checksum matches the current Checksum of
 | // HasChecksum returns if the given checksum matches the current Checksum of
 | ||||||
|  | @ -96,3 +97,60 @@ func ArtifactDir(kind, namespace, name string) string { | ||||||
| func ArtifactPath(kind, namespace, name, filename string) string { | func ArtifactPath(kind, namespace, name, filename string) string { | ||||||
| 	return path.Join(ArtifactDir(kind, namespace, name), filename) | 	return path.Join(ArtifactDir(kind, namespace, name), filename) | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // TransformLegacyRevision transforms a "legacy" revision string into a "new"
 | ||||||
|  | // revision string. It accepts the following formats:
 | ||||||
|  | //
 | ||||||
|  | //   - main/5394cb7f48332b2de7c17dd8b8384bbc84b7e738
 | ||||||
|  | //   - feature/branch/5394cb7f48332b2de7c17dd8b8384bbc84b7e738
 | ||||||
|  | //   - HEAD/5394cb7f48332b2de7c17dd8b8384bbc84b7e738
 | ||||||
|  | //   - tag/55609ff9d959589ed917ce32e6bc0f0a36809565f308602c15c3668965979edc
 | ||||||
|  | //   - d52bde83c5b2bd0fa7910264e0afc3ac9cfe9b6636ca29c05c09742f01d5a4bd
 | ||||||
|  | //
 | ||||||
|  | // Which are transformed into the following formats respectively:
 | ||||||
|  | //
 | ||||||
|  | //   - main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738
 | ||||||
|  | //   - feature/branch@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738
 | ||||||
|  | //   - sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738
 | ||||||
|  | //   - tag@sha256:55609ff9d959589ed917ce32e6bc0f0a36809565f308602c15c3668965979edc
 | ||||||
|  | //   - sha256:d52bde83c5b2bd0fa7910264e0afc3ac9cfe9b6636ca29c05c09742f01d5a4bd
 | ||||||
|  | //
 | ||||||
|  | // Deprecated, this function exists for backwards compatibility with existing
 | ||||||
|  | // resources, and to provide a transition period. Will be removed in a future
 | ||||||
|  | // release.
 | ||||||
|  | func TransformLegacyRevision(rev string) string { | ||||||
|  | 	if rev != "" && strings.LastIndex(rev, ":") == -1 { | ||||||
|  | 		if i := strings.LastIndex(rev, "/"); i >= 0 { | ||||||
|  | 			sha := rev[i+1:] | ||||||
|  | 			if algo := determineSHAType(sha); algo != "" { | ||||||
|  | 				if name := rev[:i]; name != "HEAD" { | ||||||
|  | 					return name + "@" + algo + ":" + sha | ||||||
|  | 				} | ||||||
|  | 				return algo + ":" + sha | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if algo := determineSHAType(rev); algo != "" { | ||||||
|  | 			return algo + ":" + rev | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return rev | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // isAlphaNumHex returns true if the given string only contains 0-9 and a-f
 | ||||||
|  | // characters.
 | ||||||
|  | var isAlphaNumHex = regexp.MustCompile(`^[0-9a-f]+$`).MatchString | ||||||
|  | 
 | ||||||
|  | // determineSHAType returns the SHA algorithm used to compute the provided hex.
 | ||||||
|  | // The determination is heuristic and based on the length of the hex string. If
 | ||||||
|  | // the size is not recognized, an empty string is returned.
 | ||||||
|  | func determineSHAType(hex string) string { | ||||||
|  | 	if isAlphaNumHex(hex) { | ||||||
|  | 		switch len(hex) { | ||||||
|  | 		case 40: | ||||||
|  | 			return "sha1" | ||||||
|  | 		case 64: | ||||||
|  | 			return "sha256" | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return "" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,78 @@ | ||||||
|  | /* | ||||||
|  | Copyright 2023 The Flux authors | ||||||
|  | 
 | ||||||
|  | Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | you may not use this file except in compliance with the License. | ||||||
|  | You may obtain a copy of the License at | ||||||
|  | 
 | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0
 | ||||||
|  | 
 | ||||||
|  | Unless required by applicable law or agreed to in writing, software | ||||||
|  | distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | See the License for the specific language governing permissions and | ||||||
|  | limitations under the License. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | package v1beta2 | ||||||
|  | 
 | ||||||
|  | import "testing" | ||||||
|  | 
 | ||||||
|  | func TestTransformLegacyRevision(t *testing.T) { | ||||||
|  | 	tests := []struct { | ||||||
|  | 		rev  string | ||||||
|  | 		want string | ||||||
|  | 	}{ | ||||||
|  | 		{ | ||||||
|  | 			rev:  "HEAD/5394cb7f48332b2de7c17dd8b8384bbc84b7e738", | ||||||
|  | 			want: "sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			rev:  "main/5394cb7f48332b2de7c17dd8b8384bbc84b7e738", | ||||||
|  | 			want: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			rev:  "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738", | ||||||
|  | 			want: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			rev:  "feature/branch/5394cb7f48332b2de7c17dd8b8384bbc84b7e738", | ||||||
|  | 			want: "feature/branch@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			rev:  "feature/branch@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738", | ||||||
|  | 			want: "feature/branch@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			rev:  "5ac85ca617f3774baff4ae0a420b810b2546dbc9af9f346b1d55c5ed9873c55c", | ||||||
|  | 			want: "sha256:5ac85ca617f3774baff4ae0a420b810b2546dbc9af9f346b1d55c5ed9873c55c", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			rev:  "v1.0.0", | ||||||
|  | 			want: "v1.0.0", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			rev:  "v1.0.0-rc1", | ||||||
|  | 			want: "v1.0.0-rc1", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			rev:  "v1.0.0-rc1+metadata", | ||||||
|  | 			want: "v1.0.0-rc1+metadata", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			rev:  "arbitrary/revision", | ||||||
|  | 			want: "arbitrary/revision", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			rev:  "5394cb7f48332b2de7c17dd8b8384bbc84b7xxxx", | ||||||
|  | 			want: "5394cb7f48332b2de7c17dd8b8384bbc84b7xxxx", | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	for _, tt := range tests { | ||||||
|  | 		t.Run(tt.rev, func(t *testing.T) { | ||||||
|  | 			if got := TransformLegacyRevision(tt.rev); got != tt.want { | ||||||
|  | 				t.Errorf("TransformLegacyRevision() = %v, want %v", got, tt.want) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue