parent
							
								
									43d2eafcf2
								
							
						
					
					
						commit
						90fe22bc2e
					
				|  | @ -783,17 +783,53 @@ func filesToSave(deps []string) ([]string, error) { | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	// remove duplicates
 | 	// remove duplicates
 | ||||||
| 	deduped := []string{} | 	deduped := deduplicatePaths(srcFiles) | ||||||
| 	m := map[string]struct{}{} | 
 | ||||||
| 	for _, f := range srcFiles { |  | ||||||
| 		if _, ok := m[f]; !ok { |  | ||||||
| 			deduped = append(deduped, f) |  | ||||||
| 			m[f] = struct{}{} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return deduped, nil | 	return deduped, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // deduplicatePaths returns a deduplicated slice of shortest paths
 | ||||||
|  | // For example {"usr/lib", "usr/lib/ssl"} will return only {"usr/lib"}
 | ||||||
|  | func deduplicatePaths(paths []string) []string { | ||||||
|  | 	type node struct { | ||||||
|  | 		children map[string]*node | ||||||
|  | 		value    bool | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	root := &node{children: make(map[string]*node)} | ||||||
|  | 
 | ||||||
|  | 	// Create a tree marking all present paths
 | ||||||
|  | 	for _, f := range paths { | ||||||
|  | 		parts := strings.Split(f, "/") | ||||||
|  | 		current := root | ||||||
|  | 		for i := 0; i < len(parts)-1; i++ { | ||||||
|  | 			part := parts[i] | ||||||
|  | 			if _, ok := current.children[part]; !ok { | ||||||
|  | 				current.children[part] = &node{children: make(map[string]*node)} | ||||||
|  | 			} | ||||||
|  | 			current = current.children[part] | ||||||
|  | 		} | ||||||
|  | 		current.children[parts[len(parts)-1]] = &node{children: make(map[string]*node), value: true} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Collect all paths
 | ||||||
|  | 	deduped := []string{} | ||||||
|  | 	var traverse func(*node, string) | ||||||
|  | 	traverse = func(n *node, path string) { | ||||||
|  | 		if n.value { | ||||||
|  | 			deduped = append(deduped, strings.TrimPrefix(path, "/")) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		for k, v := range n.children { | ||||||
|  | 			traverse(v, path+"/"+k) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	traverse(root, "") | ||||||
|  | 
 | ||||||
|  | 	return deduped | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func fetchExtraStages(stages []config.KanikoStage, opts *config.KanikoOptions) error { | func fetchExtraStages(stages []config.KanikoStage, opts *config.KanikoOptions) error { | ||||||
| 	t := timing.Start("Fetching Extra Stages") | 	t := timing.Start("Fetching Extra Stages") | ||||||
| 	defer timing.DefaultRun.Stop(t) | 	defer timing.DefaultRun.Stop(t) | ||||||
|  |  | ||||||
|  | @ -468,6 +468,41 @@ func Test_filesToSave(t *testing.T) { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func TestDeduplicatePaths(t *testing.T) { | ||||||
|  | 	tests := []struct { | ||||||
|  | 		name  string | ||||||
|  | 		input []string | ||||||
|  | 		want  []string | ||||||
|  | 	}{ | ||||||
|  | 		{ | ||||||
|  | 			name:  "no duplicates", | ||||||
|  | 			input: []string{"file1.txt", "file2.txt", "usr/lib"}, | ||||||
|  | 			want:  []string{"file1.txt", "file2.txt", "usr/lib"}, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:  "duplicates", | ||||||
|  | 			input: []string{"file1.txt", "file2.txt", "file2.txt", "usr/lib"}, | ||||||
|  | 			want:  []string{"file1.txt", "file2.txt", "usr/lib"}, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:  "duplicates with paths", | ||||||
|  | 			input: []string{"file1.txt", "file2.txt", "file2.txt", "usr/lib", "usr/lib/ssl"}, | ||||||
|  | 			want:  []string{"file1.txt", "file2.txt", "usr/lib"}, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, tt := range tests { | ||||||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||||||
|  | 			got := deduplicatePaths(tt.input) | ||||||
|  | 			sort.Strings(tt.want) | ||||||
|  | 			sort.Strings(got) | ||||||
|  | 			if !reflect.DeepEqual(got, tt.want) { | ||||||
|  | 				t.Errorf("TestDeduplicatePaths() = %v, want %v", got, tt.want) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func TestInitializeConfig(t *testing.T) { | func TestInitializeConfig(t *testing.T) { | ||||||
| 	tests := []struct { | 	tests := []struct { | ||||||
| 		description string | 		description string | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue