mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-05-10 20:05:50 +02:00
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.
This commit is contained in:
parent
9fc7a5177b
commit
6afcc5bda8
3 changed files with 237 additions and 39 deletions
|
@ -305,7 +305,7 @@ SelectedWorktree
|
||||||
CheckedOutBranch
|
CheckedOutBranch
|
||||||
```
|
```
|
||||||
|
|
||||||
To see what fields are available on e.g. the `SelectedFile`, see [here](https://github.com/jesseduffield/lazygit/blob/master/pkg/commands/models/file.go) (all the modelling lives in the same directory). Note that the custom commands feature does not guarantee backwards compatibility (until we hit Lazygit version 1.0 of course) which means a field you're accessing on an object may no longer be available from one release to the next. Typically however, all you'll need is `{{.SelectedFile.Name}}`, `{{.SelectedLocalCommit.Hash}}` and `{{.SelectedLocalBranch.Name}}`. In the future we will likely introduce a tighter interface that exposes a limited set of fields for each model.
|
To see what fields are available on e.g. the `SelectedFile`, see [here](https://github.com/jesseduffield/lazygit/blob/master/pkg/gui/services/custom_commands/models.go) (all the modelling lives in the same file).
|
||||||
|
|
||||||
## Keybinding collisions
|
## Keybinding collisions
|
||||||
|
|
||||||
|
|
96
pkg/gui/services/custom_commands/models.go
Normal file
96
pkg/gui/services/custom_commands/models.go
Normal file
|
@ -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
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ package custom_commands
|
||||||
import (
|
import (
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
|
"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
|
// 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 {
|
func commitShimFromModelCommit(commit *models.Commit) *Commit {
|
||||||
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 {
|
|
||||||
if commit == nil {
|
if commit == nil {
|
||||||
return 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
|
// SessionState captures the current state of the application for use in custom commands
|
||||||
type SessionState struct {
|
type SessionState struct {
|
||||||
SelectedLocalCommit *Commit
|
SelectedLocalCommit *Commit
|
||||||
SelectedReflogCommit *Commit
|
SelectedReflogCommit *Commit
|
||||||
SelectedSubCommit *Commit
|
SelectedSubCommit *Commit
|
||||||
SelectedFile *models.File
|
SelectedFile *File
|
||||||
SelectedPath string
|
SelectedPath string
|
||||||
SelectedLocalBranch *models.Branch
|
SelectedLocalBranch *Branch
|
||||||
SelectedRemoteBranch *models.RemoteBranch
|
SelectedRemoteBranch *RemoteBranch
|
||||||
SelectedRemote *models.Remote
|
SelectedRemote *Remote
|
||||||
SelectedTag *models.Tag
|
SelectedTag *Tag
|
||||||
SelectedStashEntry *models.StashEntry
|
SelectedStashEntry *StashEntry
|
||||||
SelectedCommitFile *models.CommitFile
|
SelectedCommitFile *CommitFile
|
||||||
SelectedCommitFilePath string
|
SelectedCommitFilePath string
|
||||||
SelectedWorktree *models.Worktree
|
SelectedWorktree *Worktree
|
||||||
CheckedOutBranch *models.Branch
|
CheckedOutBranch *Branch
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *SessionStateLoader) call() *SessionState {
|
func (self *SessionStateLoader) call() *SessionState {
|
||||||
return &SessionState{
|
return &SessionState{
|
||||||
SelectedFile: self.c.Contexts().Files.GetSelectedFile(),
|
SelectedFile: fileShimFromModelFile(self.c.Contexts().Files.GetSelectedFile()),
|
||||||
SelectedPath: self.c.Contexts().Files.GetSelectedPath(),
|
SelectedPath: self.c.Contexts().Files.GetSelectedPath(),
|
||||||
SelectedLocalCommit: commitWrapperFromModelCommit(self.c.Contexts().LocalCommits.GetSelected()),
|
SelectedLocalCommit: commitShimFromModelCommit(self.c.Contexts().LocalCommits.GetSelected()),
|
||||||
SelectedReflogCommit: commitWrapperFromModelCommit(self.c.Contexts().ReflogCommits.GetSelected()),
|
SelectedReflogCommit: commitShimFromModelCommit(self.c.Contexts().ReflogCommits.GetSelected()),
|
||||||
SelectedLocalBranch: self.c.Contexts().Branches.GetSelected(),
|
SelectedLocalBranch: branchShimFromModelBranch(self.c.Contexts().Branches.GetSelected()),
|
||||||
SelectedRemoteBranch: self.c.Contexts().RemoteBranches.GetSelected(),
|
SelectedRemoteBranch: remoteBranchShimFromModelRemoteBranch(self.c.Contexts().RemoteBranches.GetSelected()),
|
||||||
SelectedRemote: self.c.Contexts().Remotes.GetSelected(),
|
SelectedRemote: remoteShimFromModelRemote(self.c.Contexts().Remotes.GetSelected()),
|
||||||
SelectedTag: self.c.Contexts().Tags.GetSelected(),
|
SelectedTag: tagShimFromModelRemote(self.c.Contexts().Tags.GetSelected()),
|
||||||
SelectedStashEntry: self.c.Contexts().Stash.GetSelected(),
|
SelectedStashEntry: stashEntryShimFromModelRemote(self.c.Contexts().Stash.GetSelected()),
|
||||||
SelectedCommitFile: self.c.Contexts().CommitFiles.GetSelectedFile(),
|
SelectedCommitFile: commitFileShimFromModelRemote(self.c.Contexts().CommitFiles.GetSelectedFile()),
|
||||||
SelectedCommitFilePath: self.c.Contexts().CommitFiles.GetSelectedPath(),
|
SelectedCommitFilePath: self.c.Contexts().CommitFiles.GetSelectedPath(),
|
||||||
SelectedSubCommit: commitWrapperFromModelCommit(self.c.Contexts().SubCommits.GetSelected()),
|
SelectedSubCommit: commitShimFromModelCommit(self.c.Contexts().SubCommits.GetSelected()),
|
||||||
SelectedWorktree: self.c.Contexts().Worktrees.GetSelected(),
|
SelectedWorktree: worktreeShimFromModelRemote(self.c.Contexts().Worktrees.GetSelected()),
|
||||||
CheckedOutBranch: self.refsHelper.GetCheckedOutRef(),
|
CheckedOutBranch: branchShimFromModelBranch(self.refsHelper.GetCheckedOutRef()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue