-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
upload: add local file copy uploader
Add a new BuildOutput uploader that copies the build artifacts to a local directory. This can be useful when baur is run on a CI server and the build outputs are stored directly in the filesystem, it might be a network mount. The section is called "[Build.Output.File.FileCopy]" in the .app.toml config and has a parameter to set the destination path. The Uploader creates the director if it does not exist. If a file already exist with the same path it is overwritten. The copied file has the same permission bits then the source file.
- Loading branch information
Showing
8 changed files
with
231 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package filecopy | ||
|
||
import ( | ||
"io" | ||
"os" | ||
"path" | ||
|
||
"github.com/pkg/errors" | ||
|
||
"github.com/simplesurance/baur/fs" | ||
) | ||
|
||
var defLogFn = func(string, ...interface{}) { return } | ||
|
||
// Client copies files from one path to another | ||
type Client struct { | ||
debugLogFn func(string, ...interface{}) | ||
} | ||
|
||
// New returns a client | ||
func New(debugLogFn func(string, ...interface{})) *Client { | ||
logFn := defLogFn | ||
if debugLogFn != nil { | ||
logFn = debugLogFn | ||
} | ||
|
||
return &Client{debugLogFn: logFn} | ||
} | ||
|
||
func copyFile(src, dst string) error { | ||
srcFd, err := os.Open(src) | ||
if err != nil { | ||
return errors.Wrapf(err, "opening %s failed", src) | ||
} | ||
|
||
srcFi, err := os.Stat(src) | ||
if err != nil { | ||
return errors.Wrapf(err, "stat %s failed", src) | ||
} | ||
|
||
srcFileMode := srcFi.Mode().Perm() | ||
|
||
dstFd, err := os.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, srcFileMode) | ||
if err != nil { | ||
srcFd.Close() | ||
return errors.Wrapf(err, "opening %s failed", dst) | ||
} | ||
|
||
_, err = io.Copy(dstFd, srcFd) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if err = srcFd.Close(); err != nil { | ||
return err | ||
} | ||
|
||
if err = dstFd.Close(); err != nil { | ||
return err | ||
} | ||
|
||
return err | ||
} | ||
|
||
// Upload copies the file with src path to the dst path. | ||
// If the destination directory does not exist, it is created. | ||
// If the destination path exist and is not a regular file an error is returned. | ||
// If it exist and is a file, the file is overwritten if it's not the same. | ||
func (c *Client) Upload(src string, dst string) (string, error) { | ||
destDir := path.Dir(dst) | ||
|
||
isDir, err := fs.IsDir(destDir) | ||
if err != nil { | ||
if !os.IsNotExist(err) { | ||
return "", err | ||
} | ||
|
||
err = fs.Mkdir(destDir) | ||
if err != nil { | ||
return "", errors.Wrapf(err, "creating directory '%s' failed", destDir) | ||
} | ||
|
||
c.debugLogFn("filecopy: created directory '%s'", destDir) | ||
} else { | ||
if !isDir { | ||
return "", errors.Wrapf(err, "%s is not a directory", destDir) | ||
} | ||
} | ||
|
||
regFile, err := fs.IsRegularFile(dst) | ||
if err != nil { | ||
if !os.IsNotExist(err) { | ||
return "", err | ||
} | ||
|
||
return dst, copyFile(src, dst) | ||
} | ||
|
||
if !regFile { | ||
return "", errors.Wrapf(err, "'%s' exist but is not a regular file", dst) | ||
} | ||
|
||
sameFile, err := fs.SameFile(src, dst) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
if sameFile { | ||
c.debugLogFn("filecopy: '%s' already exist and is the same then '%s'", dst, src) | ||
return dst, nil | ||
} | ||
|
||
c.debugLogFn("filecopy: '%s' already exist, overwriting file", dst) | ||
|
||
return dst, copyFile(src, dst) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters