Rich Enhanced Shell History - Contextual shell history for zsh and bash
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
resh/internal/device/device.go

145 lines
3.5 KiB

// device implements helpers that get/set device config files
package device
import (
"bufio"
"fmt"
"os"
"path"
"strings"
"github.com/curusarn/resh/internal/futil"
"github.com/curusarn/resh/internal/output"
"github.com/google/uuid"
isatty "github.com/mattn/go-isatty"
)
const fnameID = "device-id"
const fnameName = "device-name"
const fpathIDLegacy = ".resh/resh-uuid"
const filePerm = 0644
// Getters
func GetID(dataDir string) (string, error) {
return readValue(dataDir, fnameID)
}
func GetName(dataDir string) (string, error) {
return readValue(dataDir, fnameName)
}
// Install helpers
func SetupID(dataDir string) error {
return setIDIfUnset(dataDir)
}
func SetupName(out *output.Output, dataDir string) error {
return promptAndWriteNameIfUnset(out, dataDir)
}
func readValue(dataDir, fname string) (string, error) {
fpath := path.Join(dataDir, fname)
dat, err := os.ReadFile(fpath)
if err != nil {
return "", fmt.Errorf("could not read file with %s: %w", fname, err)
}
val := strings.TrimRight(string(dat), "\n")
return val, nil
}
func setIDIfUnset(dataDir string) error {
fpath := path.Join(dataDir, fnameID)
exists, err := futil.FileExists(fpath)
if err != nil {
return err
}
if exists {
return nil
}
// Try copy device ID from legacy location
homeDir, err := os.UserHomeDir()
if err != nil {
return fmt.Errorf("could not get user home: %w", err)
}
fpathLegacy := path.Join(homeDir, fpathIDLegacy)
exists, err = futil.FileExists(fpath)
if err != nil {
return err
}
if exists {
futil.CopyFile(fpathLegacy, fpath)
if err != nil {
return fmt.Errorf("could not copy device ID from legacy location: %w", err)
}
return nil
}
// Generate new device ID
rnd, err := uuid.NewRandom()
if err != nil {
return fmt.Errorf("could not get new random source: %w", err)
}
id := rnd.String()
if id == "" {
return fmt.Errorf("got invalid UUID from package")
}
err = os.WriteFile(fpath, []byte(id), filePerm)
if err != nil {
return fmt.Errorf("could not write generated ID to file: %w", err)
}
return nil
}
func promptAndWriteNameIfUnset(out *output.Output, dataDir string) error {
fpath := path.Join(dataDir, fnameName)
exists, err := futil.FileExists(fpath)
if err != nil {
return err
}
if exists {
return nil
}
name, err := promptForName(out, fpath)
if err != nil {
return fmt.Errorf("error while prompting for input: %w", err)
}
err = os.WriteFile(fpath, []byte(name), filePerm)
if err != nil {
return fmt.Errorf("could not write name to file: %w", err)
}
return nil
}
func promptForName(out *output.Output, fpath string) (string, error) {
// This function should be only ran from install-utils with attached terminal
if !isatty.IsTerminal(os.Stdout.Fd()) {
return "", fmt.Errorf("output is not a terminal - write name of this device to '%s' to bypass this error", fpath)
}
host, err := os.Hostname()
if err != nil {
return "", fmt.Errorf("could not get hostname (prompt default): %w", err)
}
hostStub := strings.Split(host, ".")[0]
fmt.Printf("\nPlease choose a short name for this device (default: '%s'): ", hostStub)
var input string
scanner := bufio.NewScanner(os.Stdin)
if scanner.Scan() {
input = scanner.Text()
}
if err = scanner.Err(); err != nil {
return "", fmt.Errorf("scanner error: %w", err)
}
if input == "" {
out.Info("Got no input - using default ...")
input = hostStub
}
out.Info(fmt.Sprintf("Device name set to '%s'", input))
fmt.Printf("You can change the device name at any time by editing '%s' file\n", fpath)
return input, nil
}