1
Unixでは、tar
ユーティリティには、リンクのターゲットをアーカイブする-h
オプションがあります。私はGoでこれを行う方法があるのだろうかと思っています。現在、リンクの内容をシンボリックリンクファイルに設定されたヘッダ名でtarにコピーしようとすると、tar: Damaged tar archive
というエラーが出ます。以下のコードは私が現在使っているものです。この関数の目的は、現在のディレクトリのすべてを再帰的にtarすることです。Goにtar -hオプションを複製する方法はありますか?
私は、シンボリックリンクのサイズをターゲットファイルのサイズに設定するだけで、まだエラーが発生する可能性があると思います。
func createTarFile() {
tarfile, _ := os.Create(buildCtxTar)
defer tarfile.Close()
tarball := tar.NewWriter(tarfile)
defer tarball.Close()
//get the working directory
rootDir, _ := os.Getwd()
//add all the files in the current directory to the tarball
walkFn := func(path string, info os.FileInfo, err error) error {
//don't add the tar file to itself, don't add the working directory either
if info.Name() == buildCtxTar || info.Name() == filepath.Base(rootDir) {
return nil
}
//no absolute paths in the tar file, the "+1" strips the leading file separator
relativePath := path[len(rootDir)+1:]
isSymlink := info.Mode()&os.ModeSymlink == os.ModeSymlink
var size int64 = -1
//evaluate symbolic links
if isSymlink {
path, size, err = handleSymlink(path)
if err != nil {
return err
}
}
header, err := tar.FileInfoHeader(info, path)
if err != nil {
return err
}
//if the OS is windows we need to convert the '\' to '/'
relativePath = filepath.ToSlash(relativePath)
//rename the name of the file to its path for a structured tarball
header.Name = relativePath
if isSymlink {
header.Size = size
}
if err := tarball.WriteHeader(header); err != nil {
return err
}
//don't attempt copy data from special files (like directories)
if !isSymlink && !info.Mode().IsRegular() {
return nil
}
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()
// copy the file data to the tarball
if _, err := io.Copy(tarball, f); err != nil {
return err
}
return nil
}
//walks through all files and subdirectories of the current directory
err := filepath.Walk(rootDir, walkFn)
}
//get the filepath for the symbolic link
func handleSymlink(path string) (string, int64, error) {
//read the link
link, err := os.Readlink(path)
if err != nil {
return "", -1, err
}
//if the filepath isn't an absolute path we need to
//reconstruct it so that it is
if !filepath.IsAbs(link) {
link = filepath.Join(filepath.Dir(path), link)
if err != nil {
return "", -1, err
}
}
fi, err := os.Stat(link)
if err != nil {
return "", -1, err
}
size := fi.Size()
return link, size, nil
}
シンボリックリンクからヘッダーを使用していて、意味がない名前とサイズを変更しています。実ファイルから新しいヘッダーを作成します。 – JimB
@JimB、ヘッダの名前をシンボリックリンクの名前に変更しましたか? – sreya
はい、私はそれがあなたが望むものだと思います。私はもっと見る時間がなかった。 – JimB