From befd7fe63e5cbadfe9259b504ed65a49c0608226 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Wed, 2 Aug 2023 21:25:52 +1000 Subject: Support mp4 videos for demos For all videos but the first video in the readme we want to use mp4 because it's faster, better quality, smaller, and allows you to play/pause (don't quote me on the smaller part). HOWEVER: github won't let us reference mp4s stored in our repo from the readme, like it does for gifs (who knows why). This is annoying because it prevents us from easily re-recording things if the UI changes. So I've got the logic for recording to mp4 but I'm thinking of sticking to gifs for now --- README.md | 2 +- demo/record_demo.sh | 58 ++++++++++++++++++++++++++++++++++++++------- docs/dev/Demo_Recordings.md | 40 +++++++++++++++++++++++++++---- 3 files changed, 85 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index d5c3b99f4..ecd894c47 100644 --- a/README.md +++ b/README.md @@ -330,7 +330,7 @@ See the [docs](docs/Custom_Command_Keybindings.md) For when you really want to just get rid of anything that shows up when you run `git status` (and yes that includes dirty submodules) [kidpix style](https://www.youtube.com/watch?v=Ur7_A4JusMU) -![nuke_working_tree-compressed](https://github.com/jesseduffield/lazygit/assets/8456633/06facd9c-166c-4ff5-b011-12e584ff8163) +![Nuke working tree](../assets/demo/nuke_working_tree-compressed.gif) ### Amend old commit diff --git a/demo/record_demo.sh b/demo/record_demo.sh index 0ef379377..97d5c2f36 100755 --- a/demo/record_demo.sh +++ b/demo/record_demo.sh @@ -1,15 +1,44 @@ #!/bin/sh -TEST=$1 - set -e +TYPE=$1 +TEST=$2 + +usage() { + echo "Usage: $0 [gif|mp4] " + echo "e.g. using full path: $0 gif pkg/integration/tests/demo/nuke_working_tree.go" + exit 1 +} + +if [ "$#" -ne 2 ] +then + usage +fi + +if [ "$TYPE" != "gif" ] && [ "$TYPE" != "mp4" ] +then + usage + exit 1 +fi + if [ -z "$TEST" ] then - echo "Usage: $0 " + usage +fi + +WORKTREE_PATH=$(git worktree list | grep assets | awk '{print $1}') + +if [ -z "$WORKTREE_PATH" ] +then + echo "Could not find assets worktree. You'll need to create a worktree for the assets branch using the following command:" + echo "git worktree add .worktrees/assets assets" + echo "The assets branch has no shared history with the main branch: it exists to store assets which are too large to store in the main branch." exit 1 fi +OUTPUT_DIR="$WORKTREE_PATH/demo" + if ! command -v terminalizer &> /dev/null then echo "terminalizer could not be found" @@ -24,18 +53,29 @@ then exit 1 fi -# get last part of the test path and set that as the output name +# Get last part of the test path and set that as the output name # example test path: pkg/integration/tests/01_basic_test.go # For that we want: NAME=01_basic_test NAME=$(echo "$TEST" | sed -e 's/.*\///' | sed -e 's/\..*//') +# Add the demo to the tests list (if missing) so that it can be run go generate pkg/integration/tests/tests.go -mkdir -p demo/output +mkdir -p "$OUTPUT_DIR" + +# First we record the demo into a yaml representation +terminalizer -c demo/config.yml record --skip-sharing -d "go run cmd/integration_test/main.go cli --slow $TEST" "$OUTPUT_DIR/$NAME" +# Then we render it into a gif +terminalizer render "$OUTPUT_DIR/$NAME" -o "$OUTPUT_DIR/$NAME.gif" -terminalizer -c demo/config.yml record --skip-sharing -d "go run cmd/integration_test/main.go cli --slow $TEST" "demo/output/$NAME" -terminalizer render "demo/output/$NAME" -o "demo/output/$NAME.gif" -COMPRESSED_PATH="demo/output/$NAME-compressed.gif" -gifsicle --colors 256 --use-col=web -O3 < "demo/output/$NAME.gif" > "$COMPRESSED_PATH" +# Then we convert it to either an mp4 or gif based on the command line argument +if [ "$TYPE" = "mp4" ] +then + COMPRESSED_PATH="$OUTPUT_DIR/$NAME.mp4" + ffmpeg -y -i "$OUTPUT_DIR/$NAME.gif" -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" "$COMPRESSED_PATH" +else + COMPRESSED_PATH="$OUTPUT_DIR/$NAME-compressed.gif" + gifsicle --colors 256 --use-col=web -O3 < "$OUTPUT_DIR/$NAME.gif" > "$COMPRESSED_PATH" +fi echo "Demo recorded to $COMPRESSED_PATH" diff --git a/docs/dev/Demo_Recordings.md b/docs/dev/Demo_Recordings.md index 11924c199..1068e688f 100644 --- a/docs/dev/Demo_Recordings.md +++ b/docs/dev/Demo_Recordings.md @@ -12,6 +12,8 @@ Ideally we'd run this whole thing through docker but we haven't got that working npm i -g terminalizer # for gif compression npm i -g gifsicle +# for mp4 conversion +brew install ffmpeg # font with icons wget https://github.com/ryanoasis/nerd-fonts/releases/download/v3.0.2/DejaVuSansMono.tar.xz && \ @@ -37,16 +39,44 @@ You can use the same flow as we use with integration tests when you're writing a It's good to add captions explaining what task if being performed. Use the existing demos as a guide. +### Setting up the assets worktree + +We store assets (which includes demo recordings) in the `assets` branch, which is a branch that shares no history with the main branch and exists purely for storing assets. Storing them separately means we don't clog up the code branches with large binaries. + +The scripts and demo definitions live in the code branches but the output lives in the assets branch so to be able to create a video from a demo you'll need to create a linked worktree for the assets branch which you can do with: + +```sh +git worktree add .worktrees/assets assets +``` + +Outputs will be stored in `.worktrees/assets/demos/`. We'll store three separate things: +* the yaml of the recording +* the original gif +* either the compressed gif or the mp4 depending on the output you chose (see below) + ### Recording the demo Once you're happy with your demo you can record it using: ```sh -scripts/record_demo.sh +scripts/record_demo.sh [gif|mp4] # e.g. -scripts/record_demo.sh pkg/integration/tests/demo/interactive_rebase.go +scripts/record_demo.sh gif pkg/integration/tests/demo/interactive_rebase.go ``` -### Storing demos +~~The gif format is for use in the first video of the readme (it has a larger size but has auto-play and looping)~~ +~~The mp4 format is for everything else (no looping, requires clicking, but smaller size).~~ + +Turns out that you can't store mp4s in a repo and link them from a README so we're gonna just use gifs across the board for now. + +### Including demos in README/docs + +If you've followed the above steps you'll end up with your output in your assets worktree. + +Within that worktree, stage all three output files and raise a PR against the assets branch. + +Then back in the code branch, in the doc, you can embed the recording like so: +```md +![Nuke working tree](../assets/demo/interactive_rebase-compressed.gif) +``` -This part is subject to change. I'm thinking of storing all gifs in the `assets` branch. But yet to finalize on that. -For now, feel free to upload `demo/demo-compressed.gif` to GitHub by dragging and dropping it in a file in the browser (e.g. the README). +This means we can update assets without needing to update the docs that embed them. -- cgit v1.2.3 From 17db918cba68f6973621231f6346ba68706e1773 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Wed, 2 Aug 2023 22:00:56 +1000 Subject: Add demo for filtering branches --- pkg/integration/tests/demo/filter.go | 93 ++++++++++++++++++++++++++++++++++++ pkg/integration/tests/test_list.go | 1 + 2 files changed, 94 insertions(+) create mode 100644 pkg/integration/tests/demo/filter.go diff --git a/pkg/integration/tests/demo/filter.go b/pkg/integration/tests/demo/filter.go new file mode 100644 index 000000000..2e62ba444 --- /dev/null +++ b/pkg/integration/tests/demo/filter.go @@ -0,0 +1,93 @@ +package demo + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var Filter = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Filter branches", + ExtraCmdArgs: []string{}, + Skip: false, + IsDemo: true, + SetupConfig: func(config *config.AppConfig) { + // No idea why I had to use version 2: it should be using my own computer's + // font and the one iterm uses is version 3. + config.UserConfig.Gui.NerdFontsVersion = "2" + }, + SetupRepo: func(shell *Shell) { + shell.CreateNCommitsWithRandomMessages(30) + shell.NewBranch("feature/user-authentication") + shell.NewBranch("feature/payment-processing") + shell.NewBranch("feature/search-functionality") + shell.NewBranch("feature/mobile-responsive") + shell.NewBranch("bugfix/fix-login-issue") + shell.NewBranch("bugfix/fix-crash-bug") + shell.NewBranch("bugfix/fix-validation-error") + shell.NewBranch("refactor/improve-performance") + shell.NewBranch("refactor/code-cleanup") + shell.NewBranch("refactor/extract-method") + shell.NewBranch("docs/update-readme") + shell.NewBranch("docs/add-user-guide") + shell.NewBranch("docs/api-documentation") + shell.NewBranch("experiment/new-feature-idea") + shell.NewBranch("experiment/try-new-library") + shell.NewBranch("chore/update-dependencies") + shell.NewBranch("chore/add-test-cases") + shell.NewBranch("chore/migrate-database") + shell.NewBranch("hotfix/critical-bug") + shell.NewBranch("hotfix/security-patch") + shell.NewBranch("feature/social-media-integration") + shell.NewBranch("feature/email-notifications") + shell.NewBranch("feature/admin-panel") + shell.NewBranch("feature/analytics-dashboard") + shell.NewBranch("bugfix/fix-registration-flow") + shell.NewBranch("bugfix/fix-payment-bug") + shell.NewBranch("refactor/improve-error-handling") + shell.NewBranch("refactor/optimize-database-queries") + shell.NewBranch("docs/improve-tutorials") + shell.NewBranch("docs/add-faq-section") + shell.NewBranch("experiment/try-alternative-algorithm") + shell.NewBranch("experiment/implement-design-concept") + shell.NewBranch("chore/update-documentation") + shell.NewBranch("chore/improve-test-coverage") + shell.NewBranch("chore/cleanup-codebase") + shell.NewBranch("hotfix/critical-security-vulnerability") + shell.NewBranch("hotfix/fix-production-issue") + shell.NewBranch("feature/integrate-third-party-api") + shell.NewBranch("feature/image-upload-functionality") + shell.NewBranch("feature/localization-support") + shell.NewBranch("feature/chat-feature") + shell.NewBranch("bugfix/fix-broken-link") + shell.NewBranch("bugfix/fix-css-styling") + shell.NewBranch("refactor/improve-logging") + shell.NewBranch("refactor/extract-reusable-component") + shell.NewBranch("docs/add-changelog") + shell.NewBranch("docs/update-api-reference") + shell.NewBranch("experiment/implement-new-design") + shell.NewBranch("experiment/try-different-architecture") + shell.NewBranch("chore/clean-up-git-history") + shell.NewBranch("chore/update-environment-configuration") + shell.CreateFileAndAdd("env_config.rb", "EnvConfig.call(false)\n") + shell.Commit("Update env config") + shell.CreateFileAndAdd("env_config.rb", "# Turns out we need to pass true for this to work\nEnvConfig.call(true)\n") + shell.Commit("Fix env config issue") + shell.Checkout("docs/add-faq-section") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.SetCaptionPrefix("Fuzzy filter branches") + t.Wait(1000) + + t.Views().Branches(). + Focus(). + Wait(500). + Press(keys.Universal.StartSearch). + Tap(func() { + t.Wait(500) + + t.ExpectSearch().Type("environ").Confirm() + }). + Wait(500). + PressEnter() + }, +}) diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index 27cb3513e..e59fd56e2 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -92,6 +92,7 @@ var tests = []*components.IntegrationTest{ demo.Bisect, demo.CherryPick, demo.CommitAndPush, + demo.Filter, demo.InteractiveRebase, demo.NukeWorkingTree, diff.Diff, -- cgit v1.2.3 From c43195efb6c7459ea24180ef464bc6e19942654f Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Wed, 2 Aug 2023 00:06:48 +1000 Subject: Add demo for amending old commit --- pkg/integration/components/confirmation_driver.go | 6 +++ pkg/integration/tests/demo/amend_old_commit.go | 62 +++++++++++++++++++++++ pkg/integration/tests/test_list.go | 1 + 3 files changed, 69 insertions(+) create mode 100644 pkg/integration/tests/demo/amend_old_commit.go diff --git a/pkg/integration/components/confirmation_driver.go b/pkg/integration/components/confirmation_driver.go index aad5cc248..7934b351c 100644 --- a/pkg/integration/components/confirmation_driver.go +++ b/pkg/integration/components/confirmation_driver.go @@ -40,6 +40,12 @@ func (self *ConfirmationDriver) Cancel() { self.getViewDriver().PressEscape() } +func (self *ConfirmationDriver) Wait(milliseconds int) *ConfirmationDriver { + self.getViewDriver().Wait(milliseconds) + + return self +} + func (self *ConfirmationDriver) checkNecessaryChecksCompleted() { if !self.hasCheckedContent || !self.hasCheckedTitle { self.t.Fail("You must both check the content and title of a confirmation popup by calling Title()/Content() before calling Confirm()/Cancel().") diff --git a/pkg/integration/tests/demo/amend_old_commit.go b/pkg/integration/tests/demo/amend_old_commit.go new file mode 100644 index 000000000..b77a62bd1 --- /dev/null +++ b/pkg/integration/tests/demo/amend_old_commit.go @@ -0,0 +1,62 @@ +package demo + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var AmendOldCommit = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Amend old commit", + ExtraCmdArgs: []string{}, + Skip: false, + IsDemo: true, + SetupConfig: func(config *config.AppConfig) { + // No idea why I had to use version 2: it should be using my own computer's + // font and the one iterm uses is version 3. + config.UserConfig.Gui.NerdFontsVersion = "2" + config.UserConfig.Gui.ShowFileTree = false + }, + SetupRepo: func(shell *Shell) { + shell.CreateNCommitsWithRandomMessages(60) + shell.NewBranch("feature/demo") + + shell.CloneIntoRemote("origin") + + shell.SetBranchUpstream("feature/demo", "origin/feature/demo") + + shell.UpdateFile("navigation/site_navigation.go", "package navigation\n\nfunc Navigate() {\n\tpanic(\"unimplemented\")\n}") + shell.CreateFile("docs/README.md", "my readme content") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.SetCaptionPrefix("Amend an old commit") + t.Wait(1000) + + t.Views().Files(). + IsFocused(). + SelectedLine(Contains("site_navigation.go")). + PressPrimaryAction() + + t.Views().Commits(). + Focus(). + NavigateToLine(Contains("Improve accessibility of site navigation")). + Wait(500). + Press(keys.Commits.AmendToCommit). + Tap(func() { + t.ExpectPopup().Confirmation(). + Title(Equals("Amend commit")). + Wait(1000). + Content(AnyString()). + Confirm() + + t.Wait(1000) + }). + Press(keys.Universal.Push). + Tap(func() { + t.ExpectPopup().Confirmation(). + Title(Equals("Force push")). + Content(AnyString()). + Wait(1000). + Confirm() + }) + }, +}) diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index e59fd56e2..f5197f852 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -89,6 +89,7 @@ var tests = []*components.IntegrationTest{ custom_commands.OmitFromHistory, custom_commands.SuggestionsCommand, custom_commands.SuggestionsPreset, + demo.AmendOldCommit, demo.Bisect, demo.CherryPick, demo.CommitAndPush, -- cgit v1.2.3 From 0152639ef0a574b9df98c1e812580d1c54d4d76e Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Wed, 2 Aug 2023 22:32:57 +1000 Subject: Add demo for staging lines --- pkg/integration/tests/demo/stage_lines.go | 85 +++++++++++++++++++++++++++++++ pkg/integration/tests/test_list.go | 1 + 2 files changed, 86 insertions(+) create mode 100644 pkg/integration/tests/demo/stage_lines.go diff --git a/pkg/integration/tests/demo/stage_lines.go b/pkg/integration/tests/demo/stage_lines.go new file mode 100644 index 000000000..6bfa21a98 --- /dev/null +++ b/pkg/integration/tests/demo/stage_lines.go @@ -0,0 +1,85 @@ +package demo + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var originalFile = `# Lazygit + +Simple terminal UI for git commands + +![demo](https://user-images.gh.com/demo.gif) + +## Installation + +### Homebrew + +` + +var updatedFile = `# Lazygit + +Simple terminal UI for git +(Not too simple though) + +![demo](https://user-images.gh.com/demo.gif) + +## Installation + +### Homebrew + +Just do brew install lazygit and bada bing bada +boom you have begun on the path of laziness. + +` + +var StageLines = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Stage individual lines", + ExtraCmdArgs: []string{}, + Skip: false, + IsDemo: true, + SetupConfig: func(config *config.AppConfig) { + // No idea why I had to use version 2: it should be using my own computer's + // font and the one iterm uses is version 3. + config.UserConfig.Gui.NerdFontsVersion = "2" + config.UserConfig.Gui.ShowFileTree = false + config.UserConfig.Gui.ShowCommandLog = false + }, + SetupRepo: func(shell *Shell) { + shell.NewBranch("docs-fix") + shell.CreateNCommitsWithRandomMessages(30) + shell.CreateFileAndAdd("docs/README.md", originalFile) + shell.Commit("Update docs/README") + shell.UpdateFile("docs/README.md", updatedFile) + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.SetCaptionPrefix("Stage individual lines") + t.Wait(1000) + + t.Views().Files(). + IsFocused(). + PressEnter() + + t.Views().Staging(). + IsFocused(). + Press(keys.Main.ToggleDragSelect). + PressFast(keys.Universal.NextItem). + PressFast(keys.Universal.NextItem). + Wait(500). + PressPrimaryAction(). + Wait(500). + PressEscape() + + t.Views().Files(). + IsFocused(). + Press(keys.Files.CommitChanges). + Tap(func() { + t.ExpectPopup().CommitMessagePanel(). + Type("Update tagline"). + Confirm() + }) + + t.Views().Commits(). + Focus() + }, +}) diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index f5197f852..75508784e 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -96,6 +96,7 @@ var tests = []*components.IntegrationTest{ demo.Filter, demo.InteractiveRebase, demo.NukeWorkingTree, + demo.StageLines, diff.Diff, diff.DiffAndApplyPatch, diff.DiffCommits, -- cgit v1.2.3 From bbb2b32816302e7693e3410fa18cb7180e706326 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Thu, 3 Aug 2023 16:58:11 +1000 Subject: Point to new demos --- README.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ecd894c47..af6e15f1c 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,9 @@ A simple terminal UI for git commands
-[![GitHub Releases](https://img.shields.io/github/downloads/jesseduffield/lazygit/total)](https://github.com/jesseduffield/lazygit/releases) [![Go Report Card](https://goreportcard.com/badge/github.com/jesseduffield/lazygit)](https://goreportcard.com/report/github.com/jesseduffield/lazygit) [![GolangCI](https://golangci.com/badges/github.com/jesseduffield/lazygit.svg)](https://golangci.com) [![GitHub tag](https://img.shields.io/github/tag/jesseduffield/lazygit.svg)](https://github.com/jesseduffield/lazygit/releases/latest) [![homebrew](https://img.shields.io/homebrew/v/lazygit)](https://github.com/Homebrew/homebrew-core/blob/master/Formula/lazygit.rb) +[![GitHub Releases](https://img.shields.io/github/downloads/jesseduffield/lazygit/total)](https://github.com/jesseduffield/lazygit/releases) [![Go Report Card](https://goreportcard.com/badge/github.com/jesseduffield/lazygit)](https://goreportcard.com/report/github.com/jesseduffield/lazygit) [![GolangCI](https://golangci.com/badges/github.com/jesseduffield/lazygit.svg)](https://golangci.com) [![GitHub tag](https://img.shields.io/github/tag/jesseduffield/lazygit.svg)](https://github.com/jesseduffield/lazygit/releases/latest) [![homebrew](https://img.shields.io/homebrew/v/lazygit)](https://github.com/Homebrew/homebrew-core/blob/master/Formula/lazygit.rb) -![demo-compressed](https://github.com/jesseduffield/lazygit/assets/8456633/7e77d895-05a9-4571-a55b-240ac80f75eb) +![commit_and_push](../assets/demo/commit_and_push-compressed.gif) @@ -316,15 +316,15 @@ See the [docs](docs/Custom_Command_Keybindings.md) ### Git Bisect -![demo-compressed](https://github.com/jesseduffield/lazygit/assets/8456633/b2752a77-3bd0-4b65-8e36-e643ae70c396) +![bisect](../assets/demo/bisect-compressed.gif) ### Cherry-pick -![cherry_pick-compressed](https://github.com/jesseduffield/lazygit/assets/8456633/2d1205c8-9980-40b0-8b6a-221497099715) +![cherry_pick](../assets/demo/cherry_pick-compressed.gif) ### Interactive Rebase -![demo-compressed](https://github.com/jesseduffield/lazygit/assets/8456633/04d6dbe4-845a-41de-8072-0e475765ec63) +![interactive_rebase](../assets/demo/interactive_rebase-compressed.gif) ### Nuking the working tree @@ -334,7 +334,11 @@ For when you really want to just get rid of anything that shows up when you run ### Amend old commit -![amend_old_commit-compressed](https://github.com/jesseduffield/lazygit/assets/8456633/de7010c0-6902-4fad-8fe5-7197956ca40d) +![amend_old_commit](../assets/demo/amend_old_commit-compressed.gif) + +### Stage individual lines + +![stage_lines](../assets/demo/stage_lines-compressed.gif) ## Contributing -- cgit v1.2.3