@@ -14,6 +14,7 @@ import (
1414 "flag"
1515 "fmt"
1616 "go/build"
17+ "io/fs"
1718 "io/ioutil"
1819 "os"
1920 "os/exec"
@@ -174,6 +175,10 @@ type Params struct {
174175 // executions explicit.
175176 RequireExplicitExec bool
176177
178+ // RequireUniqueNames requires that names in the txtar archive are unique.
179+ // By default, later entries silently overwrite earlier ones.
180+ RequireUniqueNames bool
181+
177182 // ContinueOnError causes a testscript to try to continue in
178183 // the face of errors. Once an error has occurred, the script
179184 // will continue as if in verbose mode.
@@ -372,6 +377,22 @@ type backgroundCmd struct {
372377 neg bool // if true, cmd should fail
373378}
374379
380+ func writeFile (name string , data []byte , perm fs.FileMode , excl bool ) error {
381+ oflags := os .O_WRONLY | os .O_CREATE | os .O_TRUNC
382+ if excl {
383+ oflags |= os .O_EXCL
384+ }
385+ f , err := os .OpenFile (name , oflags , perm )
386+ if err != nil {
387+ return err
388+ }
389+ defer f .Close ()
390+ if _ , err := f .Write (data ); err != nil {
391+ return fmt .Errorf ("cannot write file contents: %v" , err )
392+ }
393+ return nil
394+ }
395+
375396// setup sets up the test execution temporary directory and environment.
376397// It returns the comment section of the txtar archive.
377398func (ts * TestScript ) setup () string {
@@ -433,7 +454,12 @@ func (ts *TestScript) setup() string {
433454 name := ts .MkAbs (ts .expand (f .Name ))
434455 ts .scriptFiles [name ] = f .Name
435456 ts .Check (os .MkdirAll (filepath .Dir (name ), 0o777 ))
436- ts .Check (ioutil .WriteFile (name , f .Data , 0o666 ))
457+ switch err := writeFile (name , f .Data , 0o666 , ts .params .RequireUniqueNames ); {
458+ case ts .params .RequireUniqueNames && errors .Is (err , fs .ErrExist ):
459+ ts .Check (fmt .Errorf ("%s would overwrite %s (because RequireUniqueNames is enabled)" , f .Name , name ))
460+ default :
461+ ts .Check (err )
462+ }
437463 }
438464 // Run any user-defined setup.
439465 if ts .params .Setup != nil {
0 commit comments