Make ordinary workspaces group shareable
This commit is contained in:
@@ -138,7 +138,7 @@ func (extractStage) Run(ctx context.Context, env *Env, m *manifest.Manifest) (*S
|
||||
return nil, fmt.Errorf("extract: resolve durable bundle path: %w", err)
|
||||
}
|
||||
for _, directory := range []string{filepath.Dir(receiptPath), outputRoot, filepath.Dir(durableBundle)} {
|
||||
if err := os.MkdirAll(directory, 0o755); err != nil {
|
||||
if err := fileops.EnsureWorkspaceDirectory(directory); err != nil {
|
||||
return nil, fmt.Errorf("extract: create directory %q: %w", directory, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/adapters/seriatim"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/artifacts"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/fileops"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/manifest"
|
||||
)
|
||||
|
||||
@@ -248,7 +249,7 @@ func normalizeMergeInputs(
|
||||
if runLayout.Enabled {
|
||||
normalizedDir = filepath.Join(runLayout.ScratchDir, "normalized")
|
||||
}
|
||||
if err := os.MkdirAll(normalizedDir, 0o755); err != nil {
|
||||
if err := fileops.EnsureWorkspaceDirectory(normalizedDir); err != nil {
|
||||
return nil, nil, nil, nil, fmt.Errorf("merge: ensure normalized transcripts directory %q: %w", normalizedDir, err)
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/artifacts"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/audio"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/config"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/fileops"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/manifest"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
@@ -424,10 +425,10 @@ func materializeS3AudioInputs(ctx context.Context, env *Env, m *manifest.Manifes
|
||||
}
|
||||
workAudioDir := filepath.Join(pathsWorkDirForManifest(env, m, sessionID), "audio")
|
||||
|
||||
if err := os.MkdirAll(spoolAudioDir, 0o755); err != nil {
|
||||
if err := fileops.EnsureWorkspaceDirectory(spoolAudioDir); err != nil {
|
||||
return s3AudioMaterializationStats{}, fmt.Errorf("create spool audio directory %q: %w", spoolAudioDir, err)
|
||||
}
|
||||
if err := os.MkdirAll(workAudioDir, 0o755); err != nil {
|
||||
if err := fileops.EnsureWorkspaceDirectory(workAudioDir); err != nil {
|
||||
return s3AudioMaterializationStats{}, fmt.Errorf("create work audio directory %q: %w", workAudioDir, err)
|
||||
}
|
||||
|
||||
@@ -517,7 +518,7 @@ func clearManagedPreviousState(paths artifacts.SessionPaths) error {
|
||||
if err := os.RemoveAll(previousDir); err != nil {
|
||||
return err
|
||||
}
|
||||
return os.MkdirAll(previousDir, 0o755)
|
||||
return fileops.EnsureWorkspaceDirectory(previousDir)
|
||||
}
|
||||
|
||||
func pathsWorkDirForManifest(env *Env, m *manifest.Manifest, sessionID string) string {
|
||||
@@ -594,7 +595,7 @@ func copyFileIfChanged(store artifacts.Store, src, dst string) (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err := store.WriteFileAtomic(dst, data, 0o644); err != nil {
|
||||
if err := store.WriteFileAtomic(dst, data, fileops.WorkspaceFileMode); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return srcChecksum, nil
|
||||
@@ -618,7 +619,7 @@ func writeBytesIfChanged(store artifacts.Store, dst string, data []byte) (string
|
||||
}
|
||||
}
|
||||
|
||||
if err := store.WriteFileAtomic(dst, data, 0o644); err != nil {
|
||||
if err := store.WriteFileAtomic(dst, data, fileops.WorkspaceFileMode); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return targetChecksum, nil
|
||||
|
||||
@@ -52,7 +52,7 @@ func hydratePreviousSessionArtifacts(
|
||||
}
|
||||
|
||||
for _, record := range plan.Records {
|
||||
if err := os.MkdirAll(filepath.Dir(record.LocalPath), 0o755); err != nil {
|
||||
if err := fileops.EnsureWorkspaceDirectory(filepath.Dir(record.LocalPath)); err != nil {
|
||||
return nil, fmt.Errorf("create previous-session path directory for %q: %w", record.LocalPath, err)
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ func hydratePreviousSessionArtifacts(
|
||||
if err := env.ObjectStore.Download(ctx, record.RemoteKey, tmpPath); err != nil {
|
||||
return fmt.Errorf("download previous-session object %q to temp file: %w", record.RemoteKey, err)
|
||||
}
|
||||
if err := fileops.InstallDownloadedTempFile(tmpPath, record.LocalPath, 0o644); err != nil {
|
||||
if err := fileops.InstallDownloadedTempFile(tmpPath, record.LocalPath, fileops.WorkspaceFileMode); err != nil {
|
||||
return fmt.Errorf("install previous-session object %q at %q: %w", record.RemoteKey, record.LocalPath, err)
|
||||
}
|
||||
removeTmp = false
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/artifacts"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/config"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/fileops"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/manifest"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/pathsafe"
|
||||
)
|
||||
@@ -78,7 +79,7 @@ func resolveRunStageLayout(
|
||||
layout.ConfigDir,
|
||||
layout.ScratchDir,
|
||||
} {
|
||||
if err := os.MkdirAll(dir, 0o755); err != nil {
|
||||
if err := fileops.EnsureWorkspaceDirectory(dir); err != nil {
|
||||
return runStageLayout{}, fmt.Errorf("create run-stage directory %q: %w", dir, err)
|
||||
}
|
||||
}
|
||||
@@ -104,7 +105,7 @@ func runLocalPathForCanonical(layout runStageLayout, sessionPaths artifacts.Sess
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("resolve run-local output path for %q: %w", cleanCanonical, err)
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Dir(localPath), 0o755); err != nil {
|
||||
if err := fileops.EnsureWorkspaceDirectory(filepath.Dir(localPath)); err != nil {
|
||||
return "", fmt.Errorf("create run-local output parent for %q: %w", localPath, err)
|
||||
}
|
||||
return localPath, nil
|
||||
@@ -127,7 +128,7 @@ func materializeRunLocalOutput(
|
||||
if err != nil {
|
||||
return artifacts.Ref{}, fmt.Errorf("read run-local output %q: %w", srcPath, err)
|
||||
}
|
||||
if err := store.WriteFileAtomic(canonicalPath, data, 0o644); err != nil {
|
||||
if err := store.WriteFileAtomic(canonicalPath, data, fileops.WorkspaceFileMode); err != nil {
|
||||
return artifacts.Ref{}, fmt.Errorf("materialize output to %q: %w", canonicalPath, err)
|
||||
}
|
||||
checksum, err := store.Checksum(canonicalPath)
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/artifacts"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/config"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/contracts"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/fileops"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/manifest"
|
||||
)
|
||||
|
||||
@@ -392,7 +393,7 @@ func copyTranscript(store artifacts.Store, src, dst string) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("read source transcript: %w", err)
|
||||
}
|
||||
if err := store.WriteFileAtomic(dst, data, 0o644); err != nil {
|
||||
if err := store.WriteFileAtomic(dst, data, fileops.WorkspaceFileMode); err != nil {
|
||||
return fmt.Errorf("write destination transcript: %w", err)
|
||||
}
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user