@@ -29,6 +29,8 @@ import (
2929
3030 "github.com/livekit/livekit-cli/v2/pkg/util"
3131 "github.com/livekit/protocol/logger"
32+
33+ "github.com/moby/patternmatcher"
3234)
3335
3436var (
@@ -48,26 +50,65 @@ var (
4850 }
4951)
5052
51- func UploadTarball (directory string , presignedUrl string , excludeFiles []string ) error {
52- excludeFiles = append (defaultExcludePatterns , excludeFiles ... )
53+ func UploadTarball (directory string , presignedUrl string , excludeFiles []string , projectType ProjectType ) error {
54+ excludeFiles = append (excludeFiles , defaultExcludePatterns ... )
5355
54- for _ , exclude := range ignoreFilePatterns {
55- ignore := filepath .Join (directory , exclude )
56- if _ , err := os .Stat (ignore ); err == nil {
57- content , err := os .ReadFile (ignore )
56+ loadExcludeFiles := func (filename string ) (bool , string , error ) {
57+ if _ , err := os .Stat (filename ); err == nil {
58+ content , err := os .ReadFile (filename )
5859 if err != nil {
59- return fmt . Errorf ( "failed to read %s: %w" , ignore , err )
60+ return false , "" , err
6061 }
61- excludeFiles = append ( excludeFiles , strings . Split ( string (content ), " \n " ) ... )
62+ return true , string (content ), nil
6263 }
64+ return false , "" , nil
65+ }
66+
67+ foundDockerIgnore := false
68+ for _ , exclude := range ignoreFilePatterns {
69+ found , content , err := loadExcludeFiles (filepath .Join (directory , exclude ))
70+ if err != nil {
71+ logger .Debugw ("failed to load exclude file" , "filename" , exclude , "error" , err )
72+ continue
73+ }
74+ if exclude == ".dockerignore" && found {
75+ foundDockerIgnore = true
76+ }
77+ excludeFiles = append (excludeFiles , strings .Split (content , "\n " )... )
78+ }
79+
80+ // need to ensure we use a dockerignore file
81+ // if we fail to load a dockerignore file, we have to exit
82+ if ! foundDockerIgnore {
83+ dockerIgnoreContent , err := fs .ReadFile (filepath .Join ("examples" , string (projectType )+ ".dockerignore" ))
84+ if err != nil {
85+ return fmt .Errorf ("failed to load exclude file %s: %w" , string (projectType ), err )
86+ }
87+ excludeFiles = append (excludeFiles , strings .Split (string (dockerIgnoreContent ), "\n " )... )
88+ }
89+
90+ matcher , err := patternmatcher .New (excludeFiles )
91+ if err != nil {
92+ return fmt .Errorf ("failed to create pattern matcher: %w" , err )
6393 }
6494
6595 for i , exclude := range excludeFiles {
6696 excludeFiles [i ] = strings .TrimSpace (exclude )
6797 }
6898
99+ checkFilesToInclude := func (path string , info os.FileInfo ) bool {
100+ if ignored , err := matcher .MatchesOrParentMatches (path ); ignored {
101+ return false
102+ } else if err != nil {
103+ return false
104+ }
105+ return true
106+ }
107+
108+ // we walk the directory first to calculate the total size of the tarball
109+ // this lets the progress bar show the correct progress
69110 var totalSize int64
70- err : = filepath .Walk (directory , func (path string , info os.FileInfo , err error ) error {
111+ err = filepath .Walk (directory , func (path string , info os.FileInfo , err error ) error {
71112 if err != nil {
72113 return err
73114 }
@@ -77,22 +118,8 @@ func UploadTarball(directory string, presignedUrl string, excludeFiles []string)
77118 return nil
78119 }
79120
80- for _ , exclude := range excludeFiles {
81- if exclude == "" || strings .Contains (exclude , "Dockerfile" ) {
82- continue
83- }
84- if info .IsDir () {
85- if strings .HasPrefix (relPath , exclude + "/" ) || strings .HasPrefix (relPath , exclude ) {
86- return filepath .SkipDir
87- }
88- }
89- matched , err := filepath .Match (exclude , relPath )
90- if err != nil {
91- return nil
92- }
93- if matched {
94- return nil
95- }
121+ if ! checkFilesToInclude (relPath , info ) {
122+ return nil
96123 }
97124
98125 if ! info .IsDir () && info .Mode ().IsRegular () {
@@ -134,26 +161,9 @@ func UploadTarball(directory string, presignedUrl string, excludeFiles []string)
134161 return fmt .Errorf ("failed to calculate relative path for %s: %w" , path , err )
135162 }
136163
137- for _ , exclude := range excludeFiles {
138- if exclude == "" || strings .Contains (exclude , "Dockerfile" ) {
139- continue
140- }
141-
142- if info .IsDir () {
143- if strings .HasPrefix (relPath , exclude + "/" ) || strings .HasPrefix (relPath , exclude ) {
144- logger .Debugw ("excluding directory from tarball" , "path" , path )
145- return filepath .SkipDir
146- }
147- }
148-
149- matched , err := filepath .Match (exclude , relPath )
150- if err != nil {
151- return nil
152- }
153- if matched {
154- logger .Debugw ("excluding file from tarball" , "path" , path )
155- return nil
156- }
164+ if ! checkFilesToInclude (relPath , info ) {
165+ logger .Debugw ("excluding file from tarball" , "path" , path )
166+ return nil
157167 }
158168
159169 // Follow symlinks and include the actual file contents
0 commit comments