mirror of
				https://github.com/vbatts/tar-split.git
				synced 2025-10-25 16:20:57 +00:00 
			
		
		
		
	*: have gomtree always evaluate tar_time if it is present
if the keyword "tar_time" is present when evaluating an Entry, gomtree should use the tar_time when evaluating the "time" keyword as well. This commit also adds a test that makes sure "tar_time" wins against "time" if both are present. Some minor clean-ups as well, such as checking if KeywordFunc[keyword] actually retrieves a function. Signed-off-by: Stephen Chung <schung@redhat.com>
This commit is contained in:
		
							parent
							
								
									bc6f3bf902
								
							
						
					
					
						commit
						656e577ecc
					
				
					 7 changed files with 106 additions and 25 deletions
				
			
		
							
								
								
									
										11
									
								
								check.go
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								check.go
									
										
									
									
									
								
							|  | @ -4,6 +4,7 @@ import ( | |||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"sort" | ||||
| 	"strings" | ||||
| ) | ||||
| 
 | ||||
| // Result of a Check | ||||
|  | @ -66,7 +67,15 @@ func Check(root string, dh *DirectoryHierarchy, keywords []string) (*Result, err | |||
| 			} | ||||
| 
 | ||||
| 			for _, kv := range kvs { | ||||
| 				keywordFunc, ok := KeywordFuncs[kv.Keyword()] | ||||
| 				kw := kv.Keyword() | ||||
| 				// 'tar_time' keyword evaluation wins against 'time' keyword evaluation | ||||
| 				if kv.Keyword() == "time" && inSlice("tar_time", keywords) { | ||||
| 					kw = "tar_time" | ||||
| 					tartime := fmt.Sprintf("%s.%s", (strings.Split(kv.Value(), ".")[0]), "000000000") | ||||
| 					kv = KeyVal(KeyVal(kw).ChangeValue(tartime)) | ||||
| 				} | ||||
| 
 | ||||
| 				keywordFunc, ok := KeywordFuncs[kw] | ||||
| 				if !ok { | ||||
| 					return nil, fmt.Errorf("Unknown keyword %q for file %q", kv.Keyword(), e.Path()) | ||||
| 				} | ||||
|  |  | |||
|  | @ -143,6 +143,58 @@ func TestTimeComparison(t *testing.T) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestTarTime(t *testing.T) { | ||||
| 	dir, err := ioutil.TempDir("", "test-tar-time.") | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	defer os.RemoveAll(dir) | ||||
| 
 | ||||
| 	// This is the format of time from FreeBSD | ||||
| 	spec := ` | ||||
| /set type=file time=5.454353132 | ||||
| .               type=dir time=5.123456789 | ||||
|     file       time=5.911134111 | ||||
| .. | ||||
| ` | ||||
| 
 | ||||
| 	fh, err := os.Create(filepath.Join(dir, "file")) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	// This is what mode we're checking for. Round integer of epoch seconds | ||||
| 	epoch := time.Unix(5, 0) | ||||
| 	if err := os.Chtimes(fh.Name(), epoch, epoch); err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	if err := os.Chtimes(dir, epoch, epoch); err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	if err := fh.Close(); err != nil { | ||||
| 		t.Error(err) | ||||
| 	} | ||||
| 
 | ||||
| 	dh, err := ParseSpec(bytes.NewBufferString(spec)) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	// make sure "time" keyword works | ||||
| 	_, err = Check(dir, dh, DefaultKeywords) | ||||
| 	if err != nil { | ||||
| 		t.Error(err) | ||||
| 	} | ||||
| 
 | ||||
| 	// make sure tar_time wins | ||||
| 	res, err := Check(dir, dh, append(DefaultKeywords, "tar_time")) | ||||
| 	if err != nil { | ||||
| 		t.Error(err) | ||||
| 	} | ||||
| 	if len(res.Failures) > 0 { | ||||
| 		t.Fatal(res.Failures) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestIgnoreComments(t *testing.T) { | ||||
| 	dir, err := ioutil.TempDir("", "test-comments.") | ||||
| 	if err != nil { | ||||
|  |  | |||
|  | @ -94,7 +94,11 @@ func main() { | |||
| 			currentKeywords = append([]string{"type"}, currentKeywords...) | ||||
| 		} | ||||
| 	} else { | ||||
| 		currentKeywords = mtree.DefaultKeywords[:] | ||||
| 		if *flTar != "" { | ||||
| 			currentKeywords = mtree.DefaultTarKeywords[:] | ||||
| 		} else { | ||||
| 			currentKeywords = mtree.DefaultKeywords[:] | ||||
| 		} | ||||
| 	} | ||||
| 	// -K <keywords> | ||||
| 	if *flAddKeywords != "" { | ||||
|  | @ -192,13 +196,9 @@ func main() { | |||
| 				log.Println(err) | ||||
| 				isErr = true | ||||
| 				return | ||||
| 		if res != nil { | ||||
| 			if len(res.Failures) > 0 { | ||||
| 				defer os.Exit(1) | ||||
| 				for _, failure := range res.Failures { | ||||
| 					fmt.Println(failure) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		if res != nil { | ||||
| 			if len(res.Extra) > 0 { | ||||
| 				defer os.Exit(1) | ||||
| 				for _, extra := range res.Extra { | ||||
|  |  | |||
							
								
								
									
										22
									
								
								keywords.go
									
										
									
									
									
								
							
							
						
						
									
										22
									
								
								keywords.go
									
										
									
									
									
								
							|  | @ -59,6 +59,11 @@ func (kv KeyVal) Value() string { | |||
| 	return strings.SplitN(strings.TrimSpace(string(kv)), "=", 2)[1] | ||||
| } | ||||
| 
 | ||||
| // ChangeValue changes the value of a KeyVal | ||||
| func (kv KeyVal) ChangeValue(newval string) string { | ||||
| 	return fmt.Sprintf("%s=%s", kv.Keyword(), newval) | ||||
| } | ||||
| 
 | ||||
| // keywordSelector takes an array of "keyword=value" and filters out that only the set of words | ||||
| func keywordSelector(keyval, words []string) []string { | ||||
| 	retList := []string{} | ||||
|  | @ -129,6 +134,17 @@ var ( | |||
| 		"nlink", | ||||
| 		"time", | ||||
| 	} | ||||
| 	// DefaultTarKeywords has keywords that should be used when creating a manifest from | ||||
| 	// an archive. Currently, evaluating the # of hardlinks has not been implemented yet | ||||
| 	DefaultTarKeywords = []string{ | ||||
| 		"size", | ||||
| 		"type", | ||||
| 		"uid", | ||||
| 		"gid", | ||||
| 		"mode", | ||||
| 		"link", | ||||
| 		"tar_time", | ||||
| 	} | ||||
| 	// SetKeywords is the default set of keywords calculated for a `/set` SpecialType | ||||
| 	SetKeywords = []string{ | ||||
| 		"uid", | ||||
|  | @ -213,11 +229,7 @@ var ( | |||
| 		} | ||||
| 	} | ||||
| 	tartimeKeywordFunc = func(path string, info os.FileInfo, r io.Reader) (string, error) { | ||||
| 		t := info.ModTime().Unix() | ||||
| 		if t == 0 { | ||||
| 			return "tar_time=0.000000000", nil | ||||
| 		} | ||||
| 		return fmt.Sprintf("tar_time=%d.000000000", t), nil | ||||
| 		return fmt.Sprintf("tar_time=%d.000000000", info.ModTime().Unix()), nil | ||||
| 	} | ||||
| 	timeKeywordFunc = func(path string, info os.FileInfo, r io.Reader) (string, error) { | ||||
| 		t := info.ModTime().UnixNano() | ||||
|  |  | |||
							
								
								
									
										7
									
								
								tar.go
									
										
									
									
									
								
							
							
						
						
									
										7
									
								
								tar.go
									
										
									
									
									
								
							|  | @ -93,6 +93,8 @@ func (ts *tarStream) readHeaders() { | |||
| 			ts.pipeReader.CloseWithError(err) | ||||
| 			return | ||||
| 		} | ||||
| 		defer tmpFile.Close() | ||||
| 		defer os.Remove(tmpFile.Name()) | ||||
| 
 | ||||
| 		// Alright, it's either file or directory | ||||
| 		e := Entry{ | ||||
|  | @ -119,7 +121,6 @@ func (ts *tarStream) readHeaders() { | |||
| 				if err != nil { | ||||
| 					ts.setErr(err) | ||||
| 				} | ||||
| 
 | ||||
| 				// for good measure, check that we actually get a value for a keyword | ||||
| 				if val != "" { | ||||
| 					e.Keywords = append(e.Keywords, val) | ||||
|  | @ -134,7 +135,6 @@ func (ts *tarStream) readHeaders() { | |||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		// collect meta-set keywords for a directory so that we can build the | ||||
| 		// actual sets in `flatten` | ||||
| 		if hdr.FileInfo().IsDir() { | ||||
|  | @ -168,9 +168,6 @@ func (ts *tarStream) readHeaders() { | |||
| 			} | ||||
| 		} | ||||
| 		populateTree(&root, &e, hdr, ts) | ||||
| 
 | ||||
| 		tmpFile.Close() | ||||
| 		os.Remove(tmpFile.Name()) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,7 +3,6 @@ package mtree | |||
| import ( | ||||
| 	"archive/tar" | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
|  | @ -115,17 +114,17 @@ func TestTar(t *testing.T) { | |||
| 		switch { | ||||
| 		case len(res.Failures) > 0: | ||||
| 			for _, f := range res.Failures { | ||||
| 				fmt.Printf("%s\n", f) | ||||
| 				t.Errorf("%s\n", f) | ||||
| 			} | ||||
| 			errors += "Keyword validation errors\n" | ||||
| 		case len(res.Missing) > 0: | ||||
| 			for _, m := range res.Missing { | ||||
| 				fmt.Printf("Missing file: %s\n", m.Path()) | ||||
| 				t.Errorf("Missing file: %s\n", m.Path()) | ||||
| 			} | ||||
| 			errors += "Missing files not expected for this test\n" | ||||
| 		case len(res.Extra) > 0: | ||||
| 			for _, e := range res.Extra { | ||||
| 				fmt.Printf("Extra file: %s\n", e.Path()) | ||||
| 				t.Errorf("Extra file: %s\n", e.Path()) | ||||
| 			} | ||||
| 			errors += "Extra files not expected for this test\n" | ||||
| 		} | ||||
|  |  | |||
							
								
								
									
										18
									
								
								walk.go
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								walk.go
									
										
									
									
									
								
							|  | @ -80,7 +80,11 @@ func Walk(root string, exlcudes []ExcludeFunc, keywords []string) (*DirectoryHie | |||
| 							defer fh.Close() | ||||
| 							r = fh | ||||
| 						} | ||||
| 						if str, err := KeywordFuncs[keyword](path, info, r); err == nil && str != "" { | ||||
| 						keywordFunc, ok := KeywordFuncs[keyword] | ||||
| 						if !ok { | ||||
| 							return fmt.Errorf("Unknown keyword %q for file %q", keyword, path) | ||||
| 						} | ||||
| 						if str, err := keywordFunc(path, info, r); err == nil && str != "" { | ||||
| 							e.Keywords = append(e.Keywords, str) | ||||
| 						} else if err != nil { | ||||
| 							return err | ||||
|  | @ -107,7 +111,11 @@ func Walk(root string, exlcudes []ExcludeFunc, keywords []string) (*DirectoryHie | |||
| 							defer fh.Close() | ||||
| 							r = fh | ||||
| 						} | ||||
| 						str, err := KeywordFuncs[keyword](path, info, r) | ||||
| 						keywordFunc, ok := KeywordFuncs[keyword] | ||||
| 						if !ok { | ||||
| 							return fmt.Errorf("Unknown keyword %q for file %q", keyword, path) | ||||
| 						} | ||||
| 						str, err := keywordFunc(path, info, r) | ||||
| 						if err != nil { | ||||
| 							return err | ||||
| 						} | ||||
|  | @ -158,7 +166,11 @@ func Walk(root string, exlcudes []ExcludeFunc, keywords []string) (*DirectoryHie | |||
| 					defer fh.Close() | ||||
| 					r = fh | ||||
| 				} | ||||
| 				str, err := KeywordFuncs[keyword](path, info, r) | ||||
| 				keywordFunc, ok := KeywordFuncs[keyword] | ||||
| 				if !ok { | ||||
| 					return fmt.Errorf("Unknown keyword %q for file %q", keyword, path) | ||||
| 				} | ||||
| 				str, err := keywordFunc(path, info, r) | ||||
| 				if err != nil { | ||||
| 					return err | ||||
| 				} | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue