go.dedis.ch/onet/v3@v3.2.11-0.20210930124529-e36530bca7ef/app/io.go (about)

     1  package app
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  	"os/user"
     9  	"path"
    10  	"strings"
    11  
    12  	"go.dedis.ch/onet/v3/log"
    13  	"golang.org/x/xerrors"
    14  )
    15  
    16  var in *bufio.Reader
    17  var out io.Writer
    18  
    19  func init() {
    20  	in = bufio.NewReader(os.Stdin)
    21  	out = os.Stdout
    22  }
    23  
    24  // TildeToHome takes a path and replaces an eventual "~" with the home-directory.
    25  // If the user-directory is not defined it will return a path relative to the
    26  // root-directory "/".
    27  func TildeToHome(path string) string {
    28  	if strings.HasPrefix(path, "~/") {
    29  		usr, err := user.Current()
    30  		log.ErrFatal(err, "Got error while fetching home-directory")
    31  		return usr.HomeDir + path[1:]
    32  	}
    33  	return path
    34  }
    35  
    36  // Input prints the arguments given with an 'input'-format and
    37  // proposes the 'def' string as default. If the user presses
    38  // 'enter', the 'dev' will be returned.
    39  // In the case of an error it will Fatal.
    40  func Input(def string, args ...interface{}) string {
    41  	fmt.Fprintln(out)
    42  	fmt.Fprint(out, args...)
    43  	fmt.Fprintf(out, " [%s]: ", def)
    44  	str, err := in.ReadString('\n')
    45  	if err != nil {
    46  		log.Fatal("Could not read input.")
    47  	}
    48  	str = strings.TrimSpace(str)
    49  	if str == "" {
    50  		return def
    51  	}
    52  	return str
    53  }
    54  
    55  // Inputf takes a format string and arguments and calls
    56  // Input.
    57  func Inputf(def string, f string, args ...interface{}) string {
    58  	return Input(def, fmt.Sprintf(f, args...))
    59  }
    60  
    61  // InputYN asks a Yes/No question. Anything else than upper/lower-case
    62  // 'y' will be interpreted as no.
    63  func InputYN(def bool, args ...interface{}) bool {
    64  	defStr := "Yn"
    65  	if !def {
    66  		defStr = "Ny"
    67  	}
    68  	return strings.ToLower(string(Input(defStr, args...)[0])) == "y"
    69  }
    70  
    71  // Copy makes a copy of a local file with the same file-mode-bits set.
    72  func Copy(dst, src string) error {
    73  	info, err := os.Stat(dst)
    74  	if err == nil && info.IsDir() {
    75  		if err := Copy(path.Join(dst, path.Base(src)), src); err != nil {
    76  			return xerrors.Errorf("copying folder: %v", err)
    77  		}
    78  		return nil
    79  	}
    80  	fSrc, err := os.Open(src)
    81  	if err != nil {
    82  		return xerrors.Errorf("opening file: %v", err)
    83  	}
    84  	defer fSrc.Close()
    85  	stat, err := fSrc.Stat()
    86  	if err != nil {
    87  		return xerrors.Errorf("file info: %v", err)
    88  	}
    89  	fDst, err := os.OpenFile(dst, os.O_CREATE|os.O_RDWR, stat.Mode())
    90  	if err != nil {
    91  		return xerrors.Errorf("opening file: %v", err)
    92  	}
    93  	defer fDst.Close()
    94  	_, err = io.Copy(fDst, fSrc)
    95  	if err != nil {
    96  		return xerrors.Errorf("copying file: %v", err)
    97  	}
    98  
    99  	return nil
   100  }