fix(install): fixed installing symlinks

This commit is contained in:
Paul Fey 2025-05-07 14:29:50 +02:00
parent 52c7d05e76
commit 8371232323
3 changed files with 124 additions and 310 deletions

View file

@ -1,14 +1,16 @@
package main
import (
"context"
"encoding/json"
"errors"
"github.com/codeclysm/extract/v3"
"io"
"io/fs"
"net"
"os"
"path/filepath"
"github.com/mholt/archiver/v4"
"strings"
)
func installMap(conn net.Conn, instance string, objmap map[string]interface{}) error {
@ -34,19 +36,31 @@ func install(conn net.Conn, instance string, package_path string) error {
}
}
err = os.MkdirAll(unpack_path, 0775)
if err != nil {
return err
}
package_path, err = filepath.Abs(package_path)
if err != nil {
return err
}
fsys, err := archiver.FileSystem(nil, package_path, nil)
if err != nil {
return err
}
if is_dir, _ := is_directory(package_path); is_dir {
err = copy_directory(unpack_path, package_path)
if err != nil {
return err
}
} else {
archive, err := os.Open(package_path)
if err != nil {
return err
}
err = os.CopyFS(unpack_path, fsys)
if err != nil {
return err
err = extract.Archive(context.TODO(), archive, unpack_path, nil)
if err != nil {
return err
}
}
dir, _, err := find_infofile(unpack_path)
@ -83,7 +97,12 @@ func install(conn net.Conn, instance string, package_path string) error {
}
}
err = os.CopyFS(package_path, os.DirFS(dir))
err = os.MkdirAll(package_path, 0775)
if err != nil {
return err
}
err = copy_directory(package_path, dir)
if err != nil {
return err
}
@ -216,3 +235,65 @@ func find_infofile(source string) (string, string, error) {
return "", "", errors.New("no infofile found")
}
}
// Stolen from https://stackoverflow.com/a/72246196/19680146
func copy_directory(dst, src string) error {
return filepath.Walk(src, func(path string, info fs.FileInfo, err error) error {
if err != nil {
return err
}
// copy to this path
outpath := filepath.Join(dst, strings.TrimPrefix(path, src))
if info.IsDir() {
os.MkdirAll(outpath, info.Mode())
return nil // means recursive
}
// handle irregular files
if !info.Mode().IsRegular() {
switch info.Mode().Type() & os.ModeType {
case os.ModeSymlink:
link, err := os.Readlink(path)
if err != nil {
return err
}
return os.Symlink(link, outpath)
}
return nil
}
// copy contents of regular file efficiently
// open input
in, _ := os.Open(path)
if err != nil {
return err
}
defer in.Close()
// create output
fh, err := os.Create(outpath)
if err != nil {
return err
}
defer fh.Close()
// make it the same
fh.Chmod(info.Mode())
// copy content
_, err = io.Copy(fh, in)
return err
})
}
func is_directory(path string) (bool, error) {
fileInfo, err := os.Stat(path)
if err != nil {
return false, err
}
return fileInfo.IsDir(), err
}