github.com/NeowayLabs/nash@v0.2.2-0.20200127205349-a227041ffd50/cmd/nash/install.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"io/ioutil"
     7  	"os"
     8  	"path/filepath"
     9  )
    10  
    11  func NashLibDir(nashpath string) string {
    12  	//FIXME: This is sadly duplicated from the shell implementation =(
    13  	return filepath.Join(nashpath, "lib")
    14  }
    15  
    16  func InstallLib(nashpath string, sourcepath string) error {
    17  	nashlibdir := NashLibDir(nashpath)
    18  	sourcepathAbs, err := filepath.Abs(sourcepath)
    19  	if err != nil {
    20  		return fmt.Errorf("error[%s] getting absolute path of [%s]", err, sourcepath)
    21  	}
    22  	if filepath.HasPrefix(sourcepathAbs, nashlibdir) {
    23  		return fmt.Errorf(
    24  			"lib source path[%s] can't be inside nash lib dir[%s]", sourcepath, nashlibdir)
    25  	}
    26  	return installLib(nashlibdir, sourcepathAbs)
    27  }
    28  
    29  func installLib(targetdir string, sourcepath string) error {
    30  	f, err := os.Stat(sourcepath)
    31  	if err != nil {
    32  		return fmt.Errorf("error[%s] checking if path[%s] is dir", err, sourcepath)
    33  	}
    34  
    35  	if !f.IsDir() {
    36  		return copyfile(targetdir, sourcepath)
    37  	}
    38  
    39  	basedir := filepath.Base(sourcepath)
    40  	targetdir = filepath.Join(targetdir, basedir)
    41  
    42  	files, err := ioutil.ReadDir(sourcepath)
    43  	if err != nil {
    44  		return fmt.Errorf("error[%s] reading dir[%s]", err, sourcepath)
    45  	}
    46  
    47  	for _, file := range files {
    48  		err := installLib(targetdir, filepath.Join(sourcepath, file.Name()))
    49  		if err != nil {
    50  			return err
    51  		}
    52  	}
    53  	return nil
    54  }
    55  
    56  func copyfile(targetdir string, sourcefilepath string) error {
    57  	fail := func(err error) error {
    58  		return fmt.Errorf(
    59  			"error[%s] trying to copy file[%s] to [%s]", err, sourcefilepath, targetdir)
    60  	}
    61  
    62  	err := os.MkdirAll(targetdir, os.ModePerm)
    63  	if err != nil {
    64  		return fail(err)
    65  	}
    66  
    67  	sourcefile, err := os.Open(sourcefilepath)
    68  	if err != nil {
    69  		return fail(err)
    70  	}
    71  	defer sourcefile.Close()
    72  
    73  	targetfilepath := filepath.Join(targetdir, filepath.Base(sourcefilepath))
    74  	targetfile, err := os.Create(targetfilepath)
    75  	if err != nil {
    76  		return fail(err)
    77  	}
    78  	defer targetfile.Close()
    79  
    80  	_, err = io.Copy(targetfile, sourcefile)
    81  	return err
    82  }