diff --git a/backend/web/landing/www/install.py b/backend/web/landing/www/install.py index a68de88..fdb781f 100644 --- a/backend/web/landing/www/install.py +++ b/backend/web/landing/www/install.py @@ -31,8 +31,20 @@ else: with urllib.request.urlopen(download_url) as response: hishtory_binary = response.read() -tmpdir = os.environ.get('TMPDIR', '') or '/tmp/' -tmpFilePath = tmpdir+'hishtory-client' +def get_executable_tmpdir(): + specified_dir = os.environ.get('TMPDIR', '') + if specified_dir: + return specified_dir + try: + if hasattr(os, 'ST_NOEXEC'): + if os.statvfs("/tmp").f_flag & os.ST_NOEXEC: + # /tmp/ is mounted as NOEXEC, so fall back to the current working directory + return os.getcwd() + except: + pass + return "/tmp/" + +tmpFilePath = os.path.join(get_executable_tmpdir(), 'hishtory-client') if os.path.exists(tmpFilePath): os.remove(tmpFilePath) with open(tmpFilePath, 'wb') as f: @@ -44,4 +56,5 @@ if os.environ.get('HISHTORY_OFFLINE'): exitCode = os.system(cmd) if exitCode != 0: raise Exception("failed to install downloaded hishtory client via `" + tmpFilePath +" install` (is that directory mounted noexec? Consider setting an alternate directory via the TMPDIR environment variable)!") +os.remove(tmpFilePath) print('Succesfully installed hishtory! Open a new terminal, try running a command, and then running `hishtory query`.') diff --git a/client/client_test.go b/client/client_test.go index 1daa008..7aec368 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -1107,6 +1107,42 @@ func testInstallViaPythonScriptChild(t *testing.T, tester shellTester) { } } +func TestInstallViaPythonScriptFromHead(t *testing.T) { + defer testutils.BackupAndRestore(t)() + tester := zshTester{} + + // Set up + defer testutils.BackupAndRestoreEnv("HISHTORY_TEST")() + + // Install via the python script + out := tester.RunInteractiveShell(t, `cat backend/web/landing/www/install.py | python3 -`) + require.Contains(t, out, "Succesfully installed hishtory") + r := regexp.MustCompile(`Setting secret hishtory key to (.*)`) + matches := r.FindStringSubmatch(out) + if len(matches) != 2 { + t.Fatalf("Failed to extract userSecret from output=%#v: matches=%#v", out, matches) + } + userSecret := matches[1] + + // Test the status subcommand + downloadData, err := cmd.GetDownloadData(makeTestOnlyContextWithFakeConfig()) + require.NoError(t, err) + out = tester.RunInteractiveShell(t, `hishtory status`) + expectedOut := fmt.Sprintf("hiSHtory: %s\nEnabled: true\nSecret Key: %s\nCommit Hash: ", downloadData.Version, userSecret) + require.Contains(t, out, expectedOut) + + // And test that it recorded that command + time.Sleep(time.Second) + out = tester.RunInteractiveShell(t, `hishtory export -pipefail`) + if out != "hishtory status\n" { + t.Fatalf("unexpected output from hishtory export=%#v", out) + } + + // And check that it installed in online mode + out = tester.RunInteractiveShell(t, `hishtory status -v`) + require.Contains(t, out, "\nSync Mode: Enabled\n") +} + func testExportWithQuery(t *testing.T, tester shellTester) { // Setup defer testutils.BackupAndRestore(t)()