mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-08 22:28:24 +02:00
Finish implementation of config file parsing
Still needs tests
This commit is contained in:
@@ -3,8 +3,16 @@
|
||||
package ssh
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"kitty/tools/utils/paths"
|
||||
"kitty/tools/utils/shlex"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
@@ -19,9 +27,9 @@ type CopyInstruction struct {
|
||||
exclude_patterns []string
|
||||
}
|
||||
|
||||
func NewEnvInstruction(spec string) (ei *EnvInstruction, err error) {
|
||||
func ParseEnvInstruction(spec string) (ans []*EnvInstruction, err error) {
|
||||
const COPY_FROM_LOCAL string = "_kitty_copy_env_var_"
|
||||
ei = &EnvInstruction{}
|
||||
ei := &EnvInstruction{}
|
||||
found := false
|
||||
ei.key, ei.val, found = strings.Cut(spec, "=")
|
||||
ei.key = strings.TrimSpace(ei.key)
|
||||
@@ -37,10 +45,98 @@ func NewEnvInstruction(spec string) (ei *EnvInstruction, err error) {
|
||||
if ei.key == "" {
|
||||
err = fmt.Errorf("The env directive must not be empty")
|
||||
}
|
||||
ans = []*EnvInstruction{ei}
|
||||
return
|
||||
}
|
||||
|
||||
func NewCopyInstruction(spec string) (ci *CopyInstruction, err error) {
|
||||
ci = &CopyInstruction{}
|
||||
var paths_ctx *paths.Ctx
|
||||
|
||||
func resolve_file_spec(spec string, is_glob bool) ([]string, error) {
|
||||
if paths_ctx == nil {
|
||||
paths_ctx = &paths.Ctx{}
|
||||
}
|
||||
ans := os.ExpandEnv(paths_ctx.ExpandHome(spec))
|
||||
if !filepath.IsAbs(ans) {
|
||||
ans = paths_ctx.AbspathFromHome(ans)
|
||||
}
|
||||
if is_glob {
|
||||
files, err := filepath.Glob(ans)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(files) == 0 {
|
||||
return nil, fmt.Errorf("%s does not exist", spec)
|
||||
}
|
||||
return files, nil
|
||||
}
|
||||
err := unix.Access(ans, unix.R_OK)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return nil, fmt.Errorf("%s does not exist", spec)
|
||||
}
|
||||
return nil, fmt.Errorf("Cannot read from: %s with error: %w", spec, err)
|
||||
}
|
||||
return []string{ans}, nil
|
||||
}
|
||||
|
||||
func get_arcname(loc, dest, home string) (arcname string) {
|
||||
if dest != "" {
|
||||
arcname = dest
|
||||
} else {
|
||||
arcname = filepath.Clean(loc)
|
||||
if filepath.HasPrefix(arcname, home) {
|
||||
ra, err := filepath.Rel(home, arcname)
|
||||
if err == nil {
|
||||
arcname = ra
|
||||
}
|
||||
}
|
||||
}
|
||||
prefix := "home/"
|
||||
if strings.HasPrefix(arcname, "/") {
|
||||
prefix = "root"
|
||||
}
|
||||
return prefix + arcname
|
||||
}
|
||||
|
||||
func ParseCopyInstruction(spec string) (ans []*CopyInstruction, err error) {
|
||||
args, err := shlex.Split(spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
opts, args, err := parse_copy_args(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
locations := make([]string, 0, len(args))
|
||||
for _, arg := range args {
|
||||
locs, err := resolve_file_spec(arg, opts.Glob)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
locations = append(locations, locs...)
|
||||
}
|
||||
if len(locations) == 0 {
|
||||
return nil, fmt.Errorf("No files to copy specified")
|
||||
}
|
||||
if len(locations) > 1 && opts.Dest != "" {
|
||||
return nil, fmt.Errorf("Specifying a remote location with more than one file is not supported")
|
||||
}
|
||||
home := paths_ctx.HomePath()
|
||||
ans = make([]*CopyInstruction, 0, len(locations))
|
||||
for _, loc := range locations {
|
||||
ci := CopyInstruction{local_path: loc, exclude_patterns: opts.Exclude}
|
||||
if opts.SymlinkStrategy != "preserve" {
|
||||
ci.local_path, err = filepath.EvalSymlinks(loc)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to resolve symlinks in %#v with error: %w", loc, err)
|
||||
}
|
||||
}
|
||||
if opts.SymlinkStrategy == "resolve" {
|
||||
ci.arcname = get_arcname(ci.local_path, opts.Dest, home)
|
||||
} else {
|
||||
ci.arcname = get_arcname(loc, opts.Dest, home)
|
||||
}
|
||||
ans = append(ans, &ci)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user