github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/fly/commands/internal/executehelpers/uploads.go (about) 1 package executehelpers 2 3 import ( 4 "bufio" 5 "bytes" 6 "io" 7 "os/exec" 8 9 "github.com/pf-qiu/concourse/v6/atc" 10 "github.com/pf-qiu/concourse/v6/go-concourse/concourse" 11 "github.com/concourse/go-archive/tgzfs" 12 "github.com/vbauerster/mpb/v4" 13 ) 14 15 func Upload(bar *mpb.Bar, team concourse.Team, path string, includeIgnored bool, platform string, tags []string) (atc.WorkerArtifact, error) { 16 files := getFiles(path, includeIgnored) 17 18 archiveStream, archiveWriter := io.Pipe() 19 20 go func() { 21 archiveWriter.CloseWithError(tgzfs.Compress(archiveWriter, path, files...)) 22 }() 23 24 return team.CreateArtifact(bar.ProxyReader(archiveStream), platform, tags) 25 } 26 27 func getFiles(dir string, includeIgnored bool) []string { 28 var files []string 29 var err error 30 31 if includeIgnored { 32 files = []string{"."} 33 } else { 34 files, err = getGitFiles(dir) 35 if err != nil { 36 files = []string{"."} 37 } 38 } 39 40 return files 41 } 42 43 func getGitFiles(dir string) ([]string, error) { 44 tracked, err := gitLS(dir) 45 if err != nil { 46 return nil, err 47 } 48 49 deleted, err := gitLS(dir, "--deleted") 50 if err != nil { 51 return nil, err 52 } 53 54 existingFiles := difference(tracked, deleted) 55 56 untracked, err := gitLS(dir, "--others", "--exclude-standard") 57 if err != nil { 58 return nil, err 59 } 60 61 return append(existingFiles, untracked...), nil 62 } 63 64 func gitLS(dir string, flags ...string) ([]string, error) { 65 files := []string{} 66 67 gitLS := exec.Command("git", append([]string{"ls-files", "-z"}, flags...)...) 68 gitLS.Dir = dir 69 70 gitOut, err := gitLS.StdoutPipe() 71 if err != nil { 72 return nil, err 73 } 74 75 outScan := bufio.NewScanner(gitOut) 76 outScan.Split(scanNull) 77 78 err = gitLS.Start() 79 if err != nil { 80 return nil, err 81 } 82 83 for outScan.Scan() { 84 files = append(files, outScan.Text()) 85 } 86 87 err = gitLS.Wait() 88 if err != nil { 89 return nil, err 90 } 91 92 return files, nil 93 } 94 95 func scanNull(data []byte, atEOF bool) (int, []byte, error) { 96 // eof, no more data; terminate 97 if atEOF && len(data) == 0 { 98 return 0, nil, nil 99 } 100 101 // look for terminating null byte 102 if i := bytes.IndexByte(data, 0); i >= 0 { 103 return i + 1, data[0:i], nil 104 } 105 106 // no final terminator; return what's left 107 if atEOF { 108 return len(data), data, nil 109 } 110 111 // request more data 112 return 0, nil, nil 113 } 114 115 func difference(a, b []string) []string { 116 mb := map[string]bool{} 117 for _, x := range b { 118 mb[x] = true 119 } 120 ab := []string{} 121 for _, x := range a { 122 if _, ok := mb[x]; !ok { 123 ab = append(ab, x) 124 } 125 } 126 return ab 127 }