code: func copyFiles(ctx context.Context, comm communicator.Communicator, src, dst string) error {
  	retryCtx, cancel := context.WithTimeout(ctx, comm.Timeout())
  	defer cancel()
  
  	// Wait and retry until we establish the connection
  	err := communicator.Retry(retryCtx, func() error {
  		return comm.Connect(nil)
  	})
  	if err != nil {
  		return err
  	}
  
  	// disconnect when the context is canceled, which will close this after
  	// Apply as well.
  	go func() {
  		<-ctx.Done()
  		comm.Disconnect()
  	}()
  
  	info, err := os.Stat(src)
  	if err != nil {
  		return err
  	}
  
  	// If we're uploading a directory, short circuit and do that
  	if info.IsDir() {
  		if err := comm.UploadDir(dst, src); err != nil {
  			return fmt.Errorf("Upload failed: %v", err)
  		}
  		return nil
  	}
  
  	// We're uploading a file...
  	f, err := os.Open(src)
  	if err != nil {
  		return err
  	}
  	defer f.Close()
  
  	err = comm.Upload(dst, f)
  	if err != nil {
  		return fmt.Errorf("Upload failed: %v", err)
  	}
  	return err
  }
docs: // copyFiles is used to copy the files from a source to a destination