Documentation ¶
Overview ¶
Package cmd registers cobra commands for CLI tool. Some commands use an "app" build tag to speed up compilation while developing by ignoring UX specific dependencies (systray, webview)
Index ¶
Constants ¶
This section is empty.
Variables ¶
var AddCmd = &cobra.Command{ Use: "add", Short: "Add a new task via command line", Long: `Define a new sync task using two URI and a direction. Endpoint URI support the following schemes: - router: Direct connexion to Cells server running on the same machine - fs: Path to a local folder - s3: S3 compliant - memdb: In-memory DB for testing purposes Direction can be: - Bi: Bidirectionnal sync between two endpoints - Left: Changes are only propagated from right to left - Right: Changes are only propagated from left to right Example - LeftUri : "router:///personal/admin/folder" - RightUri: "fs:///Users/name/Pydio/folder" - Direction: "Bi" `, Run: func(cmd *cobra.Command, args []string) { t := &config.Task{ Uuid: uuid.New(), } var e error l := &promptui.Prompt{Label: "Left endpoint URI"} r := &promptui.Prompt{Label: "Right endpoint URI"} s := promptui.Select{Label: "Sync Direction", Items: []string{"Bi", "Left", "Right"}} t.LeftURI, e = l.Run() if e != nil { exit(e) } t.RightURI, e = r.Run() if e != nil { exit(e) } _, t.Direction, e = s.Run() if e != nil { exit(e) } config.Default().Tasks = append(config.Default().Tasks, t) er := config.Save() if er != nil { exit(er) } }, }
AddCmd adds a task to the config via the command line
var AutoTestCmd = &cobra.Command{ Use: "autotest", Short: "Basic unidirectional sync between two local folders (under your temporary directory)", Run: func(cmd *cobra.Command, args []string) { tmpDir := os.TempDir() syncId := uuid.New() leftDir := filepath.Join(tmpDir, syncId, "left") os.MkdirAll(leftDir, 0777) rightDir := filepath.Join(tmpDir, syncId, "right") os.MkdirAll(rightDir, 0777) if !autoTestSkipClean { defer func() { fmt.Println("Cleaning resources after test (" + filepath.Join(tmpDir, syncId) + ")") os.RemoveAll(filepath.Join(tmpDir, syncId)) }() } left, e := filesystem.NewFSClient(leftDir, model.EndpointOptions{}) if e != nil { log.Fatal("cannot init left dir " + leftDir) } if e := ioutil.WriteFile(filepath.Join(leftDir, "basic-file.txt"), []byte("hello world"), 0755); e != nil { log.Fatal("cannot write a file for testing on left " + leftDir) } right, e := filesystem.NewFSClient(rightDir, model.EndpointOptions{}) if e != nil { log.Fatal("cannot init right dir " + rightDir) } statusChan := make(chan model.Status) doneChan := make(chan interface{}) waitChan := make(chan bool, 1) var err error syncTask := task.NewSync(left, right, model.DirectionRight) syncTask.SkipTargetChecks = true syncTask.Start(context.Background(), false) syncTask.SetupEventsChan(statusChan, doneChan, nil) go func() { defer func() { close(waitChan) }() for { select { case status := <-statusChan: fmt.Println("Task Status Received: ", status) case p := <-doneChan: if patch, ok := p.(merger.Patch); ok { fmt.Println("Patch Processing Finished") fmt.Println(patch.Stats()) if patch.Size() == 0 { err = fmt.Errorf("processed patch has size 0, this is not normal") return } if data, e := ioutil.ReadFile(filepath.Join(rightDir, "basic-file.txt")); e != nil { err = fmt.Errorf("cannot read right file %v", e) } else if string(data) != "hello world" { err = fmt.Errorf("right file does not have proper content: %v", string(data)) } } else { err = fmt.Errorf("doneChan did not send a patch") } return case <-time.After(30 * time.Second): err = fmt.Errorf("breaking test after 30s, this is not normal") return } } }() syncTask.Run(context.Background(), false, true) <-waitChan syncTask.Shutdown() if err != nil { log.Fatal(err) } }, }
AutoTestCmd performs a simple test of a unidirectional sync between two local folders (created inside TmpDir)
var CaptureCmd = &cobra.Command{ Use: "capture", Short: "Capture snapshots inside JSON file - do not perform any actual tasks", Run: func(cmd *cobra.Command, args []string) { if captureTarget == "" { log.Fatal("Please provide a target folder for storing JSON files") } ctx := servicecontext.WithServiceName(context.Background(), "supervisor") ctx = servicecontext.WithServiceColor(ctx, servicecontext.ServiceColorRest) conf := config.Default() if len(conf.Tasks) > 0 { for _, t := range conf.Tasks { leftEndpoint, err := endpoint.EndpointFromURI(t.LeftURI, t.RightURI) if err != nil { log.Fatal(err.Error()) } rightEndpoint, err := endpoint.EndpointFromURI(t.RightURI, t.LeftURI) if err != nil { log.Fatal(err.Error()) } var dir model.DirectionType switch t.Direction { case "Bi": dir = model.DirectionBi case "Left": dir = model.DirectionLeft case "Right": dir = model.DirectionRight default: log.Fatal("unsupported direction type, please use one of Bi, Left, Right") } syncTask := task.NewSync(leftEndpoint, rightEndpoint, dir) configPath := filepath.Join(config.SyncClientDataDir(), t.Uuid) syncTask.SetSnapshotFactory(endpoint.NewSnapshotFactory(configPath, leftEndpoint, rightEndpoint)) e := syncTask.Capture(ctx, captureTarget) if e != nil { log.Fatal(e) } else { fmt.Println("Captured snapshots inside " + captureTarget) } } } }, }
CaptureCmd captures snapshots inside JSON file - do not perform any actual tasks
var DeleteCmd = &cobra.Command{ Use: "delete", Short: "Delete existing sync via command line", Run: func(cmd *cobra.Command, args []string) { tS := promptui.Select{Label: "Select Sync to Edit", Items: config.Default().Items()} i, _, e := tS.Run() if e != nil { exit(e) } tasks := config.Default().Tasks last := len(tasks) - 1 lastTask := tasks[last] tasks[last] = tasks[i] tasks[i] = lastTask tasks = tasks[:last] config.Default().Tasks = tasks er := config.Save() if er != nil { exit(er) } }, }
DeleteCmd removes a task via the command line.
var EditCmd = &cobra.Command{ Use: "edit", Short: "Exit existing sync via command line", Run: func(cmd *cobra.Command, args []string) { tS := promptui.Select{Label: "Select Sync to Edit", Items: config.Default().Items()} i, _, e := tS.Run() if e != nil { exit(e) } task := config.Default().Tasks[i] l := &promptui.Prompt{Label: "Left endpoint URI", Default: task.LeftURI} r := &promptui.Prompt{Label: "Right endpoint URI", Default: task.RightURI} s := promptui.Select{Label: "Sync Direction", Items: []string{"Bi", "Left", "Right"}} task.LeftURI, e = l.Run() if e != nil { exit(e) } task.RightURI, e = r.Run() if e != nil { exit(e) } _, task.Direction, e = s.Run() if e != nil { exit(e) } er := config.Save() if er != nil { exit(er) } }, }
EditCmd edits a task via the command line
var RootCmd = &cobra.Command{ Use: os.Args[0], Short: "Cells Sync desktop client", Long: `Cells Sync desktop client. Realtime, bidirectional synchronization tool for Pydio Cells server. Launching without command is the same as './cells-sync start' on Mac and Windows. `, PersistentPreRun: func(cmd *cobra.Command, args []string) { log.Init() handleSignals() }, Run: func(cmd *cobra.Command, args []string) { if runtime.GOOS == "windows" || runtime.GOOS == "darwin" { StartCmd.PreRun(cmd, args) StartCmd.Run(cmd, args) } else { cmd.Usage() } }, }
RootCmd is the Cobra root command
var ServiceCmd = &cobra.Command{ Use: "service", Short: "Manage service: install,uninstall,stop,start,restart", Run: func(cmd *cobra.Command, args []string) { if len(args) == 0 { log.Fatal("please provide one of install,uninstall,stop,start,restart,status") } if args[0] == "status" { s, e := config.Status() if e != nil { log.Fatal("Cannot get service status: ", e) } fmt.Print("Service status : ") switch s { case service.StatusUnknown: fmt.Println("Unknown") case service.StatusRunning: fmt.Println("Running") case service.StatusStopped: fmt.Println("Stopped") } return } if !config.AllowedServiceCmd(args[0]) { log.Fatal(fmt.Errorf("Valid actions are: %q\n", service.ControlAction)) } if err := config.ControlAppService(config.ServiceCmd(args[0])); err != nil { log.Fatal(err) } }, }
ServiceCmd provides access to the service install, uninstall, start, stop commands.
var StartCmd = &cobra.Command{ Use: "start", Short: "Start Cells Sync and fork a process for starting system tray", PreRun: func(cmd *cobra.Command, args []string) { logs := config.Default().Logs os.MkdirAll(logs.Folder, 0755) log.RegisterWriteSyncer(zapcore.AddSync(&lumberjack.Logger{ Filename: filepath.Join(logs.Folder, "sync.log"), MaxAge: logs.MaxAgeDays, MaxSize: logs.MaxFilesSize, MaxBackups: logs.MaxFilesNumber, })) }, Run: func(cmd *cobra.Command, args []string) { s := control.NewSupervisor(startNoUi) s.Serve() }, }
StartCmd starts the client.
var SystrayCmd = &cobra.Command{ Use: "systray", Short: "Launch Systray", Run: func(cmd *cobra.Command, args []string) { tray.Run(url) }, }
SystrayCmd starts the System Tray
var VersionCmd = &cobra.Command{ Use: "version", Short: "Display version", Run: func(cmd *cobra.Command, args []string) { common.PrintVersion() }, }
VersionCmd displays the current binary version
var WebviewCmd = &cobra.Command{ Use: "webview", Short: "Launch WebView", Run: func(cmd *cobra.Command, args []string) { lang := i18n.JsonLang() if lang != "" { url += "?lang=" + lang } w := webview.New(webview.Settings{ Width: 900, Height: 600, Resizable: true, Title: i18n.T("application.title"), URL: url, Debug: true, ExternalInvokeCallback: func(w webview.WebView, data string) { switch data { case "DOMContentLoaded": w.Bind("linkOpener", &LinkOpener{}) break } }, }) w.Run() }, }
WebviewCmd opens a webview pointing to the http server URL.
Functions ¶
This section is empty.
Types ¶
type LinkOpener ¶
type LinkOpener struct{}
LinkOpener is bound to JS inside the webview
func (*LinkOpener) Open ¶
func (w *LinkOpener) Open(url string)
Open opens an url (http or file) using OS stuff.