123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- /*
- * Rufs - Remote Union File System
- *
- * Copyright 2017 Matthias Ladkau. All rights reserved.
- *
- * This Source Code Form is subject to the terms of the MIT
- * License, If a copy of the MIT License was not distributed with this
- * file, You can obtain one at https://opensource.org/licenses/MIT.
- */
- package term
- import (
- "fmt"
- "io"
- "path"
- "sort"
- "strings"
- "unicode/utf8"
- "devt.de/krotik/common/stringutil"
- "devt.de/krotik/rufs"
- )
- /*
- TreeTerm models a command processor for Rufs trees.
- */
- type TreeTerm struct {
- tree *rufs.Tree // Tree which we operate on
- cd string // Current directory
- out io.Writer // Output writer
- lastStatus string // Last status line
- }
- /*
- NewTreeTerm returns a new command processor for Rufs trees.
- */
- func NewTreeTerm(t *rufs.Tree, out io.Writer) *TreeTerm {
- return &TreeTerm{t, "/", out, ""}
- }
- /*
- WriteStatus writes a status line to the output writer.
- */
- func (tt *TreeTerm) WriteStatus(line string) {
- fmt.Fprint(tt.out, "\r")
- fmt.Fprint(tt.out, line)
- ll := len(tt.lastStatus)
- lc := len(line)
- if ll > lc {
- fmt.Fprint(tt.out, stringutil.GenerateRollingString(" ", ll-lc))
- }
- tt.lastStatus = line
- }
- /*
- ClearStatus removes the last status line and returns the cursor to the initial position.
- */
- func (tt *TreeTerm) ClearStatus() {
- if tt.lastStatus != "" {
- toClear := utf8.RuneCountInString(tt.lastStatus)
- fmt.Fprint(tt.out, "\r")
- fmt.Fprint(tt.out, stringutil.GenerateRollingString(" ", toClear))
- fmt.Fprint(tt.out, "\r")
- }
- }
- /*
- CurrentDir returns the current directory of this TreeTerm.
- */
- func (tt *TreeTerm) CurrentDir() string {
- return tt.cd
- }
- /*
- AddCmd adds a new command to the terminal
- */
- func (tt *TreeTerm) AddCmd(cmd, helpusage, help string,
- cmdFunc func(*TreeTerm, ...string) (string, error)) {
- cmdMap[cmd] = cmdFunc
- helpMap[helpusage] = help
- }
- /*
- Cmds returns a list of available terminal commands.
- */
- func (tt *TreeTerm) Cmds() []string {
- var cmds []string
- for k := range cmdMap {
- cmds = append(cmds, k)
- }
- sort.Strings(cmds)
- return cmds
- }
- /*
- Run executes a given command line. And return its output as a string. File
- output and other streams to the console are written to the output writer.
- */
- func (tt *TreeTerm) Run(line string) (string, error) {
- var err error
- var res string
- var arg []string
- // Parse the input
- c := strings.Split(line, " ")
- cmd := c[0]
- if len(c) > 1 {
- arg = c[1:]
- }
- // Execute the given command
- if f, ok := cmdMap[cmd]; ok {
- res, err = f(tt, arg...)
- } else {
- err = fmt.Errorf("Unknown command: %s", cmd)
- }
- return res, err
- }
- /*
- cmdPing pings a remote branch.
- */
- func cmdPing(tt *TreeTerm, arg ...string) (string, error) {
- var res string
- err := fmt.Errorf("ping requires at least a branch name")
- if len(arg) > 0 {
- var fp, rpc string
- if len(arg) > 1 {
- rpc = arg[1]
- }
- if fp, err = tt.tree.PingBranch(arg[0], rpc); err == nil {
- res = fmt.Sprint("Response ok - fingerprint: ", fp, "\n")
- }
- }
- return res, err
- }
- /*
- cmdRefresh refreshes all known branches and connects depending on if the
- branches are reachable.
- */
- func cmdRefresh(tt *TreeTerm, arg ...string) (string, error) {
- tt.tree.Refresh()
- return "Done", nil
- }
- /*
- parsePathParam parse a given path parameter and return an absolute path.
- */
- func (tt *TreeTerm) parsePathParam(p string) string {
- if !strings.HasPrefix(p, "/") {
- p = path.Join(tt.cd, p) // Take care of relative paths
- }
- return p
- }
|