Repository navigation
Expand file tree
/
Copy pathhost.go
More file actions
122 lines (106 loc) · 3.02 KB
/
Copy pathhost.go
File metadata and controls
122 lines (106 loc) · 3.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package core
import (
"context"
"encoding/json"
"errors"
"fmt"
"maps"
"path/filepath"
"slices"
"github.com/dagger/dagger/dagql"
"github.com/dagger/dagger/engine"
"github.com/dagger/dagger/engine/engineutil"
"github.com/vektah/gqlparser/v2/ast"
)
type Host struct{}
func (*Host) Type() *ast.Type {
return &ast.Type{
NamedType: "Host",
NonNull: true,
}
}
func (*Host) TypeDescription() string {
return "Information about the host environment."
}
func (*Host) EncodePersistedObject(context.Context, *dagql.PersistEncodeContext) (dagql.PersistedObjectEncoding, error) {
return dagql.PersistedObjectEncoding{JSON: json.RawMessage(`{}`)}, nil
}
func (*Host) DecodePersistedObject(context.Context, *dagql.PersistDecodeContext, json.RawMessage) (dagql.Typed, error) {
return &Host{}, nil
}
// Lookup an environment variable in the host system from the current context
func (Host) GetEnv(ctx context.Context, name string) string {
clientMetadata, err := engine.ClientMetadataFromContext(ctx)
if err != nil {
return ""
}
plaintext, err := (&Secret{
URIVal: "env://" + name,
SourceClientID: clientMetadata.ClientID,
}).Plaintext(ctx)
if err != nil {
return ""
}
return string(plaintext)
}
// find-up a given soughtName in curDirPath and its parent directories,
// return the absolute path to the dir it was found in, if any
func (Host) FindUp(
ctx context.Context,
statFS StatFS,
curDirPath string,
soughtName string,
) (string, bool, error) {
found, err := Host{}.FindUpAll(ctx, statFS, curDirPath, map[string]struct{}{soughtName: {}})
if err != nil {
return "", false, err
}
p, ok := found[soughtName]
return p, ok, nil
}
// find-up a set of soughtNames in curDirPath and its parent directories return what
// was found (name -> absolute path of dir containing it)
func (Host) FindUpAll(
ctx context.Context,
statFS StatFS,
curDirPath string,
soughtNames map[string]struct{},
) (map[string]string, error) {
if fuFS, ok := statFS.(FindUpFS); ok {
found, err := fuFS.FindUpAll(ctx, curDirPath, slices.Collect(maps.Keys(soughtNames)))
if !errors.Is(err, engineutil.ErrFindUpUnsupported) {
return found, err
}
}
found := make(map[string]string, len(soughtNames))
for {
for soughtName := range soughtNames {
dirName, exists, err := StatFSExists(ctx, statFS, filepath.Join(curDirPath, soughtName))
if err != nil {
return nil, fmt.Errorf("failed to lstat %s: %w", soughtName, err)
}
if exists {
delete(soughtNames, soughtName)
// NOTE: important that we use dirName here rather than curDirPath since the stat also
// does some normalization of paths when the client is using case-insensitive filesystems
// and we are stat'ing caller host filesystems
found[soughtName] = dirName
}
}
if len(soughtNames) == 0 {
// found everything
break
}
nextDirPath := filepath.Dir(curDirPath)
if curDirPath == nextDirPath {
// hit root, nowhere else to look
break
}
curDirPath = nextDirPath
}
return found, nil
}
func (h *Host) Clone() *Host {
cp := *h
return &cp
}