github.com/paketoio/libpak@v1.3.1/internal/entry_writer.go (about) 1 /* 2 * Copyright 2018-2020 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * https://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package internal 18 19 import ( 20 "fmt" 21 "io" 22 "os" 23 "path/filepath" 24 ) 25 26 type EntryWriter struct{} 27 28 func (e EntryWriter) Write(source string, destination string) error { 29 p := filepath.Dir(destination) 30 if err := os.MkdirAll(p, 0755); err != nil { 31 return fmt.Errorf("unable to create destination directory %s: %w", p, err) 32 } 33 34 var perm os.FileMode 35 if x, err := e.isExecutable(source); err != nil { 36 return fmt.Errorf("unable to determine if %s is executable: %w", source, err) 37 } else if x { 38 perm = 0755 39 } else { 40 perm = 0644 41 } 42 43 in, err := os.OpenFile(source, os.O_RDONLY, 0) 44 if err != nil { 45 return fmt.Errorf("unable to open source file %s: %w", source, err) 46 } 47 defer in.Close() 48 49 out, err := os.OpenFile(destination, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, perm) 50 if err != nil { 51 return fmt.Errorf("unable to open destination file %s: %w", destination, err) 52 } 53 defer out.Close() 54 55 if _, err := io.Copy(out, in); err != nil { 56 return fmt.Errorf("unable to copy %s to %s: %w", source, destination, err) 57 } 58 59 return nil 60 } 61 62 func (EntryWriter) isExecutable(path string) (bool, error) { 63 s, err := os.Stat(path) 64 if err != nil { 65 return false, fmt.Errorf("unable to stat file %s: %w", path, err) 66 } 67 68 return s.Mode()&0100 == 0100, nil 69 }