mirror of
https://github.com/ddworken/hishtory.git
synced 2025-02-10 23:51:24 +01:00
Add support for enabling/disabling syncing post-install
This commit is contained in:
parent
8cb1216efd
commit
ef12e998bb
@ -155,7 +155,7 @@ If you don't need the ability to sync your shell history, you can install hiSHto
|
|||||||
curl https://hishtory.dev/install.py | HISHTORY_OFFLINE=true python3 -
|
curl https://hishtory.dev/install.py | HISHTORY_OFFLINE=true python3 -
|
||||||
```
|
```
|
||||||
|
|
||||||
This disables syncing and it is not possible to re-enable syncing after doing this.
|
This disables syncing completely so that the client will not rely on the hiSHtory backend at all. You can also change the syncing status via `hishtory syncing enable` or `hishtory syncing disable`.
|
||||||
|
|
||||||
</blockquote></details>
|
</blockquote></details>
|
||||||
|
|
||||||
|
@ -3127,4 +3127,66 @@ func TestForceInit(t *testing.T) {
|
|||||||
require.NotContains(t, tester.RunInteractiveShell(t, `hishtory export`), "echo foobar")
|
require.NotContains(t, tester.RunInteractiveShell(t, `hishtory export`), "echo foobar")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestChangeSyncingStatus(t *testing.T) {
|
||||||
|
markTestForSharding(t, 14)
|
||||||
|
defer testutils.BackupAndRestore(t)()
|
||||||
|
tester := zshTester{}
|
||||||
|
|
||||||
|
// Install it offline and record a command or two
|
||||||
|
userSecret := installWithOnlineStatus(t, tester, Offline)
|
||||||
|
assertOnlineStatus(t, Offline)
|
||||||
|
tester.RunInteractiveShell(t, `echo "device1_whileOffline_1"`)
|
||||||
|
testutils.CompareGoldens(t,
|
||||||
|
tester.RunInteractiveShell(t, `hishtory status -v | grep -v User | grep -v Device | grep -v Secret`),
|
||||||
|
"TestChangeSyncingStatus-Offline",
|
||||||
|
)
|
||||||
|
|
||||||
|
// Go online
|
||||||
|
out := tester.RunInteractiveShell(t, `hishtory syncing enable`)
|
||||||
|
require.Equal(t, "Enabled syncing successfully\n", out)
|
||||||
|
testutils.CompareGoldens(t,
|
||||||
|
tester.RunInteractiveShell(t, `hishtory status -v | grep -v User | grep -v Device | grep -v Secret`),
|
||||||
|
"TestChangeSyncingStatus-Online",
|
||||||
|
)
|
||||||
|
|
||||||
|
// Back up that device and set up another device to confirm syncing is working
|
||||||
|
restoreDev1 := testutils.BackupAndRestoreWithId(t, "dev1")
|
||||||
|
installHishtory(t, tester, userSecret)
|
||||||
|
out = tester.RunInteractiveShell(t, `hishtory export`)
|
||||||
|
require.Contains(t, out, "device1_whileOffline_1")
|
||||||
|
testutils.CompareGoldens(t,
|
||||||
|
tester.RunInteractiveShell(t, `hishtory status -v | grep -v User | grep -v Device | grep -v Secret`),
|
||||||
|
"TestChangeSyncingStatus-Online",
|
||||||
|
)
|
||||||
|
|
||||||
|
// Go back to the first device, disable syncing, and then record a command
|
||||||
|
restoreDev2 := testutils.BackupAndRestoreWithId(t, "dev2")
|
||||||
|
restoreDev1()
|
||||||
|
testutils.CompareGoldens(t,
|
||||||
|
tester.RunInteractiveShell(t, `hishtory status -v | grep -v User | grep -v Device | grep -v Secret`),
|
||||||
|
"TestChangeSyncingStatus-Online",
|
||||||
|
)
|
||||||
|
out = tester.RunInteractiveShell(t, `hishtory syncing disable`)
|
||||||
|
testutils.CompareGoldens(t,
|
||||||
|
tester.RunInteractiveShell(t, `hishtory status -v | grep -v User | grep -v Device | grep -v Secret`),
|
||||||
|
"TestChangeSyncingStatus-Offline",
|
||||||
|
)
|
||||||
|
require.Equal(t, "Disabled syncing successfully\n", out)
|
||||||
|
tester.RunInteractiveShell(t, `echo "device1_whileOffline_2"`)
|
||||||
|
out = tester.RunInteractiveShell(t, `hishtory export`)
|
||||||
|
require.Contains(t, out, "device1_whileOffline_1")
|
||||||
|
require.Contains(t, out, "device1_whileOffline_2")
|
||||||
|
|
||||||
|
// Then go back to the second device which won't see that command
|
||||||
|
testutils.BackupAndRestoreWithId(t, "dev1")
|
||||||
|
restoreDev2()
|
||||||
|
out = tester.RunInteractiveShell(t, `hishtory export`)
|
||||||
|
require.Contains(t, out, "device1_whileOffline_1")
|
||||||
|
require.NotContains(t, out, "device1_whileOffline_2")
|
||||||
|
testutils.CompareGoldens(t,
|
||||||
|
tester.RunInteractiveShell(t, `hishtory status -v | grep -v User | grep -v Device | grep -v Secret`),
|
||||||
|
"TestChangeSyncingStatus-Online",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: somehow test/confirm that hishtory works even if only bash/only zsh is installed
|
// TODO: somehow test/confirm that hishtory works even if only bash/only zsh is installed
|
||||||
|
@ -591,12 +591,15 @@ func setup(userSecret string, isOffline bool) error {
|
|||||||
if config.IsOffline {
|
if config.IsOffline {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
ctx := hctx.MakeContext()
|
return registerAndBootstrapDevice(hctx.MakeContext(), &config, db, userSecret)
|
||||||
|
}
|
||||||
|
|
||||||
|
func registerAndBootstrapDevice(ctx context.Context, config *hctx.ClientConfig, db *gorm.DB, userSecret string) error {
|
||||||
registerPath := "/api/v1/register?user_id=" + data.UserId(userSecret) + "&device_id=" + config.DeviceId
|
registerPath := "/api/v1/register?user_id=" + data.UserId(userSecret) + "&device_id=" + config.DeviceId
|
||||||
if isIntegrationTestDevice() {
|
if isIntegrationTestDevice() {
|
||||||
registerPath += "&is_integration_test_device=true"
|
registerPath += "&is_integration_test_device=true"
|
||||||
}
|
}
|
||||||
_, err = lib.ApiGet(ctx, registerPath)
|
_, err := lib.ApiGet(ctx, registerPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to register device with backend: %w", err)
|
return fmt.Errorf("failed to register device with backend: %w", err)
|
||||||
}
|
}
|
||||||
|
82
client/cmd/syncing.go
Normal file
82
client/cmd/syncing.go
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/ddworken/hishtory/client/data"
|
||||||
|
"github.com/ddworken/hishtory/client/hctx"
|
||||||
|
"github.com/ddworken/hishtory/client/lib"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var syncingCmd = &cobra.Command{
|
||||||
|
Use: "syncing",
|
||||||
|
Short: "Configure syncing to enable or disable syncing with the hishtory backend",
|
||||||
|
ValidArgs: []string{"disable", "enable"},
|
||||||
|
Args: cobra.MatchAll(cobra.OnlyValidArgs, cobra.ExactArgs(1)),
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
syncingStatus := false
|
||||||
|
if args[0] == "disable" {
|
||||||
|
syncingStatus = false
|
||||||
|
} else if args[0] == "enable" {
|
||||||
|
syncingStatus = true
|
||||||
|
} else {
|
||||||
|
lib.CheckFatalError(fmt.Errorf("unexpected syncing argument %q", args[0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := hctx.MakeContext()
|
||||||
|
conf := hctx.GetConf(ctx)
|
||||||
|
if syncingStatus {
|
||||||
|
if conf.IsOffline {
|
||||||
|
lib.CheckFatalError(switchToOnline(ctx))
|
||||||
|
fmt.Println("Enabled syncing successfully")
|
||||||
|
} else {
|
||||||
|
lib.CheckFatalError(fmt.Errorf("device is already online"))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if conf.IsOffline {
|
||||||
|
lib.CheckFatalError(fmt.Errorf("device is already offline"))
|
||||||
|
} else {
|
||||||
|
lib.CheckFatalError(switchToOffline(ctx))
|
||||||
|
fmt.Println("Disabled syncing successfully")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func switchToOnline(ctx context.Context) error {
|
||||||
|
config := hctx.GetConf(ctx)
|
||||||
|
config.IsOffline = false
|
||||||
|
err := hctx.SetConfig(config)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to switch device to online due to error while setting config: %w", err)
|
||||||
|
}
|
||||||
|
err = registerAndBootstrapDevice(ctx, config, hctx.GetDb(ctx), config.UserSecret)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to register device with backend: %w", err)
|
||||||
|
}
|
||||||
|
err = lib.Reupload(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to switch device to online due to error while uploading history entries: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func switchToOffline(ctx context.Context) error {
|
||||||
|
config := hctx.GetConf(ctx)
|
||||||
|
config.IsOffline = true
|
||||||
|
err := hctx.SetConfig(config)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to switch device to offline due to error while setting config: %w", err)
|
||||||
|
}
|
||||||
|
_, err = lib.ApiPost(ctx, "/api/v1/uninstall?user_id="+data.UserId(hctx.GetConf(ctx).UserSecret)+"&device_id="+hctx.GetConf(ctx).DeviceId, "application/json", []byte{})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to switch device to offline due to error while deleting sync state: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(syncingCmd)
|
||||||
|
}
|
4
client/testdata/TestChangeSyncingStatus-Offline
vendored
Normal file
4
client/testdata/TestChangeSyncingStatus-Offline
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
hiSHtory: v0.Unknown
|
||||||
|
Enabled: true
|
||||||
|
Sync Mode: Disabled
|
||||||
|
Commit Hash: Unknown
|
6
client/testdata/TestChangeSyncingStatus-Online
vendored
Normal file
6
client/testdata/TestChangeSyncingStatus-Online
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
hiSHtory: v0.Unknown
|
||||||
|
Enabled: true
|
||||||
|
Sync Mode: Enabled
|
||||||
|
Sync Server: http://localhost:8080
|
||||||
|
Sync Status: Synced
|
||||||
|
Commit Hash: Unknown
|
Loading…
Reference in New Issue
Block a user