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 }