Remove unnecessary output restrictions and simplify report tests
This commit is contained in:
@@ -16,11 +16,13 @@ const (
|
||||
|
||||
// OutputSelection contains only active destinations. ProtectedPaths are inputs
|
||||
// and loaded configuration/profile sources that must never be overwritten.
|
||||
// InputTranscriptPath may be replaced by final transcript publication, but not reports.
|
||||
type OutputSelection struct {
|
||||
TranscriptPath string
|
||||
ReportDir string
|
||||
ReportingEnabled bool
|
||||
ProtectedPaths []string
|
||||
InputTranscriptPath string
|
||||
TranscriptPath string
|
||||
ReportDir string
|
||||
ReportingEnabled bool
|
||||
ProtectedPaths []string
|
||||
}
|
||||
|
||||
type ReportBundle struct {
|
||||
@@ -88,7 +90,11 @@ func PrepareOutput(selection OutputSelection) (*OutputSession, error) {
|
||||
return nil, fmt.Errorf("report output %q: %w", path, err)
|
||||
}
|
||||
}
|
||||
for _, source := range protected {
|
||||
sources := protected
|
||||
if path != session.transcript && selection.InputTranscriptPath != "" {
|
||||
sources = append(append([]string(nil), protected...), selection.InputTranscriptPath)
|
||||
}
|
||||
for _, source := range sources {
|
||||
collision, err := sameDestination(path, source)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -157,7 +163,7 @@ func (s *OutputSession) Finalize(transcript []byte, reports ReportBundle, failed
|
||||
}
|
||||
failures := make([]FileFailure, 0)
|
||||
if transcript != nil && s.transcript != "" {
|
||||
if err := s.replace(s.transcript, transcript); err != nil {
|
||||
if err := s.writeTranscript(transcript); err != nil {
|
||||
failures = append(failures, FileFailure{Path: s.transcript, Kind: "transcript write", Err: err})
|
||||
}
|
||||
}
|
||||
@@ -176,6 +182,24 @@ func (s *OutputSession) Finalize(transcript []byte, reports ReportBundle, failed
|
||||
return failures
|
||||
}
|
||||
|
||||
// Stream destinations use ordinary writes; replacing their directory entry would
|
||||
// destroy the device or pipe. Regular files retain per-file replacement.
|
||||
func (s *OutputSession) writeTranscript(payload []byte) error {
|
||||
info, err := os.Stat(s.transcript)
|
||||
if err != nil && !errors.Is(err, os.ErrNotExist) {
|
||||
return err
|
||||
}
|
||||
if err == nil && !info.Mode().IsRegular() {
|
||||
file, err := os.OpenFile(s.transcript, os.O_WRONLY, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, writeErr := file.Write(payload)
|
||||
return errors.Join(writeErr, file.Close())
|
||||
}
|
||||
return s.replace(s.transcript, payload)
|
||||
}
|
||||
|
||||
func bundleParts(bundle ReportBundle) [3][]byte {
|
||||
return [3][]byte{bundle.Errors, bundle.Recoveries, bundle.Markdown}
|
||||
}
|
||||
@@ -183,8 +207,12 @@ func bundleParts(bundle ReportBundle) [3][]byte {
|
||||
func preflightTranscript(path string) error {
|
||||
info, err := os.Stat(path)
|
||||
if err == nil {
|
||||
if info.IsDir() {
|
||||
return fmt.Errorf("transcript output %q is a directory", path)
|
||||
}
|
||||
if !info.Mode().IsRegular() {
|
||||
return fmt.Errorf("transcript output %q is not a regular file", path)
|
||||
// Opening a pipe here can block before its reader is ready.
|
||||
return nil
|
||||
}
|
||||
file, openErr := os.OpenFile(path, os.O_WRONLY, 0)
|
||||
if openErr != nil {
|
||||
|
||||
Reference in New Issue
Block a user