github.com/davidmanzanares/dsd@v0.1.2-0.20210106152357-a35988f5d245/dsdl/deploy.go (about)

     1  package dsdl
     2  
     3  import (
     4  	"archive/tar"
     5  	"compress/gzip"
     6  	"encoding/hex"
     7  	"errors"
     8  	"io"
     9  	"log"
    10  	"os"
    11  	"path"
    12  	"path/filepath"
    13  	"strings"
    14  	"sync"
    15  	"time"
    16  
    17  	"github.com/davidmanzanares/dsd/types"
    18  )
    19  
    20  // Deploy deploys the target patterned matches files to the target provider service
    21  func Deploy(target Target) (types.Version, error) {
    22  	p, err := getProviderFromService(target.Service)
    23  	if err != nil {
    24  		return types.Version{}, err
    25  	}
    26  
    27  	/*gzipOutput, err := os.Create("out.tar.gzip")
    28  	if err != nil {
    29  		return err
    30  	}*/
    31  
    32  	uid := hex.EncodeToString(uid())
    33  	providerInput, gzipOutput := io.Pipe()
    34  	gzipInput := gzip.NewWriter(gzipOutput)
    35  	tarInput := tar.NewWriter(gzipInput)
    36  	var pushError error
    37  	var barrier sync.WaitGroup
    38  	barrier.Add(1)
    39  	go func() {
    40  		pushError = p.PushAsset(uid+".tar.gz", providerInput)
    41  		barrier.Done()
    42  	}()
    43  
    44  	folders := make(map[string]bool)
    45  
    46  	numExecutables := 0
    47  	for _, p := range target.Patterns {
    48  		matches, err := filepath.Glob(p)
    49  		if err != nil {
    50  			return types.Version{}, err
    51  		}
    52  		for _, filepath := range matches {
    53  			func() {
    54  				dir := path.Dir("./" + filepath)
    55  
    56  				for i := 0; dir != "."; i++ {
    57  					if i == 1000 {
    58  						panic(i)
    59  					}
    60  					if !folders[dir] {
    61  						folders[dir] = true
    62  						fi, err := os.Stat(dir)
    63  						if err == nil {
    64  							hdr, err := tar.FileInfoHeader(fi, "")
    65  							if err != nil {
    66  								log.Println(err)
    67  							} else {
    68  								hdr.Name = dir
    69  								defer tarInput.WriteHeader(hdr)
    70  							}
    71  						} else {
    72  							log.Println(err)
    73  						}
    74  					}
    75  					dir = path.Dir(dir)
    76  				}
    77  			}()
    78  			f, err := os.Open(filepath)
    79  			if err != nil {
    80  				log.Println(err)
    81  				continue
    82  			}
    83  			defer f.Close()
    84  			fi, err := f.Stat()
    85  			if err != nil {
    86  				log.Println(err)
    87  				continue
    88  			}
    89  			if fi.IsDir() {
    90  				continue
    91  			}
    92  
    93  			isExecutable := (fi.Mode()&0100) != 0 || strings.HasSuffix(filepath, ".exe")
    94  			if isExecutable {
    95  				numExecutables++
    96  			}
    97  			hdr, err := tar.FileInfoHeader(fi, "")
    98  			if err != nil {
    99  				log.Println(err)
   100  				continue
   101  			}
   102  			if strings.HasSuffix(filepath, ".exe") {
   103  				// Ensure .exe files are exeutable
   104  				hdr.Mode = hdr.Mode | 0100
   105  			}
   106  			hdr.Name = filepath
   107  			tarInput.WriteHeader(hdr)
   108  			_, err = io.Copy(tarInput, f)
   109  			if err != nil {
   110  				log.Println(err)
   111  				continue
   112  			}
   113  		}
   114  	}
   115  	if numExecutables == 0 {
   116  		return types.Version{}, errors.New("No executables")
   117  	}
   118  	err = tarInput.Close()
   119  	if err != nil {
   120  		return types.Version{}, err
   121  	}
   122  	err = gzipInput.Close()
   123  	if err != nil {
   124  		return types.Version{}, err
   125  	}
   126  	gzipOutput.Close()
   127  	if err != nil {
   128  		return types.Version{}, err
   129  	}
   130  	barrier.Wait()
   131  	if pushError != nil {
   132  		return types.Version{}, pushError
   133  	}
   134  
   135  	v := types.Version{Name: uid, Time: time.Now()}
   136  	err = p.PushVersion(v)
   137  	if err != nil {
   138  		return types.Version{}, err
   139  	}
   140  	return v, nil
   141  }