summaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorStefan Haller <stefan@haller-berlin.de>2024-05-17 19:04:21 +0200
committerStefan Haller <stefan@haller-berlin.de>2024-05-19 09:44:38 +0200
commit6afcc5bda8bbe9d9976fd50740564fe201c3ea41 (patch)
tree20b3ebd4fbe0f1e03613af494ec5a9fd0c51c94c /pkg
parent9fc7a5177bf3a924527fb7172da8ce9407b65bd2 (diff)
Create shims for all model classes in SessionStateLoader
This guards against accidentally renaming a model field and thereby breaking user's custom commands. With this change we'll get a build failure when we do that.
Diffstat (limited to 'pkg')
-rw-r--r--pkg/gui/services/custom_commands/models.go96
-rw-r--r--pkg/gui/services/custom_commands/session_state_loader.go178
2 files changed, 236 insertions, 38 deletions
diff --git a/pkg/gui/services/custom_commands/models.go b/pkg/gui/services/custom_commands/models.go
new file mode 100644
index 000000000..a33a4daf8
--- /dev/null
+++ b/pkg/gui/services/custom_commands/models.go
@@ -0,0 +1,96 @@
+package custom_commands
+
+import (
+ "github.com/jesseduffield/lazygit/pkg/commands/models"
+ "github.com/stefanhaller/git-todo-parser/todo"
+)
+
+// We create shims for all the model classes in order to get a more stable API
+// for custom commands. At the moment these are almost identical to the model
+// classes, but this allows us to add "private" fields to the model classes that
+// we don't want to expose to custom commands, or rename a model field to a
+// better name without breaking people's custom commands. In such a case we add
+// the new, better name to the shim but keep the old one for backwards
+// compatibility. We already did this for Commit.Sha, which was renamed to Hash.
+
+type Commit struct {
+ Hash string // deprecated: use Sha
+ Sha string
+ Name string
+ Status models.CommitStatus
+ Action todo.TodoCommand
+ Tags []string
+ ExtraInfo string
+ AuthorName string
+ AuthorEmail string
+ UnixTimestamp int64
+ Divergence models.Divergence
+ Parents []string
+}
+
+type File struct {
+ Name string
+ PreviousName string
+ HasStagedChanges bool
+ HasUnstagedChanges bool
+ Tracked bool
+ Added bool
+ Deleted bool
+ HasMergeConflicts bool
+ HasInlineMergeConflicts bool
+ DisplayString string
+ ShortStatus string
+ IsWorktree bool
+}
+
+type Branch struct {
+ Name string
+ DisplayName string
+ Recency string
+ Pushables string
+ Pullables string
+ UpstreamGone bool
+ Head bool
+ DetachedHead bool
+ UpstreamRemote string
+ UpstreamBranch string
+ Subject string
+ CommitHash string
+}
+
+type RemoteBranch struct {
+ Name string
+ RemoteName string
+}
+
+type Remote struct {
+ Name string
+ Urls []string
+ Branches []*RemoteBranch
+}
+
+type Tag struct {
+ Name string
+ Message string
+}
+
+type StashEntry struct {
+ Index int
+ Recency string
+ Name string
+}
+
+type CommitFile struct {
+ Name string
+ ChangeStatus string
+}
+
+type Worktree struct {
+ IsMain bool
+ IsCurrent bool
+ Path string
+ IsPathMissing bool
+ GitDir string
+ Branch string
+ Name string
+}
diff --git a/pkg/gui/services/custom_commands/session_state_loader.go b/pkg/gui/services/custom_commands/session_state_loader.go
index 6a3068df8..23369cb0b 100644
--- a/pkg/gui/services/custom_commands/session_state_loader.go
+++ b/pkg/gui/services/custom_commands/session_state_loader.go
@@ -3,7 +3,7 @@ package custom_commands
import (
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
- "github.com/stefanhaller/git-todo-parser/todo"
+ "github.com/samber/lo"
)
// loads the session state at the time that a custom command is invoked, for use
@@ -20,22 +20,7 @@ func NewSessionStateLoader(c *helpers.HelperCommon, refsHelper *helpers.RefsHelp
}
}
-type Commit struct {
- Hash string
- Sha string
- Name string
- Status models.CommitStatus
- Action todo.TodoCommand
- Tags []string
- ExtraInfo string
- AuthorName string
- AuthorEmail string
- UnixTimestamp int64
- Divergence models.Divergence
- Parents []string
-}
-
-func commitWrapperFromModelCommit(commit *models.Commit) *Commit {
+func commitShimFromModelCommit(commit *models.Commit) *Commit {
if commit == nil {
return nil
}
@@ -56,39 +41,156 @@ func commitWrapperFromModelCommit(commit *models.Commit) *Commit {
}
}
+func fileShimFromModelFile(file *models.File) *File {
+ if file == nil {
+ return nil
+ }
+
+ return &File{
+ Name: file.Name,
+ PreviousName: file.PreviousName,
+ HasStagedChanges: file.HasStagedChanges,
+ HasUnstagedChanges: file.HasUnstagedChanges,
+ Tracked: file.Tracked,
+ Added: file.Added,
+ Deleted: file.Deleted,
+ HasMergeConflicts: file.HasMergeConflicts,
+ HasInlineMergeConflicts: file.HasInlineMergeConflicts,
+ DisplayString: file.DisplayString,
+ ShortStatus: file.ShortStatus,
+ IsWorktree: file.IsWorktree,
+ }
+}
+
+func branchShimFromModelBranch(branch *models.Branch) *Branch {
+ if branch == nil {
+ return nil
+ }
+
+ return &Branch{
+ Name: branch.Name,
+ DisplayName: branch.DisplayName,
+ Recency: branch.Recency,
+ Pushables: branch.Pushables,
+ Pullables: branch.Pullables,
+ UpstreamGone: branch.UpstreamGone,
+ Head: branch.Head,
+ DetachedHead: branch.DetachedHead,
+ UpstreamRemote: branch.UpstreamRemote,
+ UpstreamBranch: branch.UpstreamBranch,
+ Subject: branch.Subject,
+ CommitHash: branch.CommitHash,
+ }
+}
+
+func remoteBranchShimFromModelRemoteBranch(remoteBranch *models.RemoteBranch) *RemoteBranch {
+ if remoteBranch == nil {
+ return nil
+ }
+
+ return &RemoteBranch{
+ Name: remoteBranch.Name,
+ RemoteName: remoteBranch.RemoteName,
+ }
+}
+
+func remoteShimFromModelRemote(remote *models.Remote) *Remote {
+ if remote == nil {
+ return nil
+ }
+
+ return &Remote{
+ Name: remote.Name,
+ Urls: remote.Urls,
+ Branches: lo.Map(remote.Branches, func(branch *models.RemoteBranch, _ int) *RemoteBranch {
+ return remoteBranchShimFromModelRemoteBranch(branch)
+ }),
+ }
+}
+
+func tagShimFromModelRemote(tag *models.Tag) *Tag {
+ if tag == nil {
+ return nil
+ }
+
+ return &Tag{
+ Name: tag.Name,
+ Message: tag.Message,
+ }
+}
+
+func stashEntryShimFromModelRemote(stashEntry *models.StashEntry) *StashEntry {
+ if stashEntry == nil {
+ return nil
+ }
+
+ return &StashEntry{
+ Index: stashEntry.Index,
+ Recency: stashEntry.Recency,
+ Name: stashEntry.Name,
+ }
+}
+
+func commitFileShimFromModelRemote(commitFile *models.CommitFile) *CommitFile {
+ if commitFile == nil {
+ return nil
+ }
+
+ return &CommitFile{
+ Name: commitFile.Name,
+ ChangeStatus: commitFile.ChangeStatus,
+ }
+}
+
+func worktreeShimFromModelRemote(worktree *models.Worktree) *Worktree {
+ if worktree == nil {
+ return nil
+ }
+
+ return &Worktree{
+ IsMain: worktree.IsMain,
+ IsCurrent: worktree.IsCurrent,
+ Path: worktree.Path,
+ IsPathMissing: worktree.IsPathMissing,
+ GitDir: worktree.GitDir,
+ Branch: worktree.Branch,
+ Name: worktree.Name,
+ }
+}
+
// SessionState captures the current state of the application for use in custom commands
type SessionState struct {
SelectedLocalCommit *Commit
SelectedReflogCommit *Commit
SelectedSubCommit *Commit
- SelectedFile *models.File
+ SelectedFile *File
SelectedPath string
- SelectedLocalBranch *models.Branch
- SelectedRemoteBranch *models.RemoteBranch
- SelectedRemote *models.Remote
- SelectedTag *models.Tag
- SelectedStashEntry *models.StashEntry
- SelectedCommitFile *models.CommitFile
+ SelectedLocalBranch *Branch
+ SelectedRemoteBranch *RemoteBranch
+ SelectedRemote *Remote
+ SelectedTag *Tag
+ SelectedStashEntry *StashEntry
+ SelectedCommitFile *CommitFile
SelectedCommitFilePath string
- SelectedWorktree *models.Worktree
- CheckedOutBranch *models.Branch
+ SelectedWorktree *Worktree
+ CheckedOutBranch *Branch
}
func (self *SessionStateLoader) call() *SessionState {
return &SessionState{
- SelectedFile: self.c.Contexts().Files.GetSelectedFile(),
+ SelectedFile: fileShimFromModelFile(self.c.Contexts().Files.GetSelectedFile()),
SelectedPath: self.c.Contexts().Files.GetSelectedPath(),
- SelectedLocalCommit: commitWrapperFromModelCommit(self.c.Contexts().LocalCommits.GetSelected()),
- SelectedReflogCommit: commitWrapperFromModelCommit(self.c.Contexts().ReflogCommits.GetSelected()),
- SelectedLocalBranch: self.c.Contexts().Branches.GetSelected(),
- SelectedRemoteBranch: self.c.Contexts().RemoteBranches.GetSelected(),
- SelectedRemote: self.c.Contexts().Remotes.GetSelected(),
- SelectedTag: self.c.Contexts().Tags.GetSelected(),
- SelectedStashEntry: self.c.Contexts().Stash.GetSelected(),
- SelectedCommitFile: self.c.Contexts().CommitFiles.GetSelectedFile(),
+ SelectedLocalCommit: commitShimFromModelCommit(self.c.Contexts().LocalCommits.GetSelected()),
+ SelectedReflogCommit: commitShimFromModelCommit(self.c.Contexts().ReflogCommits.GetSelected()),
+ SelectedLocalBranch: branchShimFromModelBranch(self.c.Contexts().Branches.GetSelected()),
+ SelectedRemoteBranch: remoteBranchShimFromModelRemoteBranch(self.c.Contexts().RemoteBranches.GetSelected()),
+ SelectedRemote: remoteShimFromModelRemote(self.c.Contexts().Remotes.GetSelected()),
+ SelectedTag: tagShimFromModelRemote(self.c.Contexts().Tags.GetSelected()),
+ SelectedStashEntry: stashEntryShimFromModelRemote(self.c.Contexts().Stash.GetSelected()),
+ SelectedCommitFile: commitFileShimFromModelRemote(self.c.Contexts().CommitFiles.GetSelectedFile()),
SelectedCommitFilePath: self.c.Contexts().CommitFiles.GetSelectedPath(),
- SelectedSubCommit: commitWrapperFromModelCommit(self.c.Contexts().SubCommits.GetSelected()),
- SelectedWorktree: self.c.Contexts().Worktrees.GetSelected(),
- CheckedOutBranch: self.refsHelper.GetCheckedOutRef(),
+ SelectedSubCommit: commitShimFromModelCommit(self.c.Contexts().SubCommits.GetSelected()),
+ SelectedWorktree: worktreeShimFromModelRemote(self.c.Contexts().Worktrees.GetSelected()),
+ CheckedOutBranch: branchShimFromModelBranch(self.refsHelper.GetCheckedOutRef()),
}
}