MCPcopy Index your code
hub / github.com/dagger/dagger / WriteFile

Method WriteFile

engine/filesync/localfs.go:967–1037  ·  view source on GitHub ↗
(ctx context.Context, expectedChangeKind ChangeKind, path string, upperStat *types.Stat, upperFS ReadFS)

Source from the content-addressed store, hash-verified

965}
966
967func (local *localFS) WriteFile(ctx context.Context, expectedChangeKind ChangeKind, path string, upperStat *types.Stat, upperFS ReadFS) (CachedChange, int64, error) {
968 var writtenBytes int64
969 appliedChange, err := local.changeCache.getOrInit(ctx, local.cacheKey(path), func(ctx context.Context) (*ChangeWithStat, error) {
970 reader, err := upperFS.ReadFile(ctx, path)
971 if err != nil {
972 return nil, fmt.Errorf("failed to read file %q: %w", path, err)
973 }
974 defer reader.Close()
975
976 fullPath := local.toFullPath(path)
977
978 lowerStat, err := os.Lstat(fullPath)
979 if err != nil && !os.IsNotExist(err) {
980 return nil, fmt.Errorf("failed to stat existing path: %w", err)
981 }
982
983 replacesExisting := lowerStat != nil
984
985 if replacesExisting {
986 if err := os.RemoveAll(fullPath); err != nil {
987 return nil, fmt.Errorf("failed to remove existing file: %w", err)
988 }
989 }
990
991 f, err := os.OpenFile(fullPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(upperStat.Mode)&os.ModePerm)
992 if err != nil {
993 return nil, err
994 }
995 defer f.Close()
996
997 h := newHashFromStat(upperStat)
998
999 copyBuf := copyBufferPool.Get().(*[]byte)
1000 written, err := io.CopyBuffer(io.MultiWriter(f, h), reader, *copyBuf)
1001 writtenBytes = written
1002 copyBufferPool.Put(copyBuf)
1003 if err != nil {
1004 return nil, fmt.Errorf("failed to copy contents: %w", err)
1005 }
1006 if err := f.Close(); err != nil {
1007 return nil, fmt.Errorf("failed to close file: %w", err)
1008 }
1009
1010 if err := rewriteMetadata(fullPath, upperStat); err != nil {
1011 return nil, fmt.Errorf("failed to rewrite file metadata: %w", err)
1012 }
1013
1014 // store the hash in an xattr so GetPreviousChange above can use that instead of re-hashing the file
1015 dgst := digest.NewDigest(hashutil.XXH3, h)
1016 if err := sysx.Setxattr(fullPath, hashXattrKey, []byte(dgst.String()), 0); err != nil {
1017 return nil, fmt.Errorf("failed to set content hash xattr: %w", err)
1018 }
1019
1020 return &ChangeWithStat{
1021 kind: expectedChangeKind,
1022 stat: &HashedStatInfo{
1023 StatInfo: StatInfo{upperStat},
1024 dgst: dgst,

Calls 15

cacheKeyMethod · 0.95
toFullPathMethod · 0.95
newHashFromStatFunction · 0.85
verifyExpectedChangeFunction · 0.85
getOrInitMethod · 0.80
LstatMethod · 0.80
OpenFileMethod · 0.80
PutMethod · 0.80
resultMethod · 0.80
rewriteMetadataFunction · 0.70
ReadFileMethod · 0.65
CloseMethod · 0.65