From dcd5bcdfcd8ebc5b44e3e9b90cb0a9838a155512 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Sun, 30 Jun 2019 22:22:35 +1000 Subject: [PATCH 01/26] remove incorrect description from status click binding --- docs/keybindings/Keybindings_en.md | 1 - docs/keybindings/Keybindings_nl.md | 1 - docs/keybindings/Keybindings_pl.md | 1 - pkg/gui/keybindings.go | 9 ++++----- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/docs/keybindings/Keybindings_en.md b/docs/keybindings/Keybindings_en.md index b0dece3c..50d7a427 100644 --- a/docs/keybindings/Keybindings_en.md +++ b/docs/keybindings/Keybindings_en.md @@ -7,7 +7,6 @@ o: open lazydocker config [: previous tab ]: next tab - : next tab m: view logs enter: focus main panel diff --git a/docs/keybindings/Keybindings_nl.md b/docs/keybindings/Keybindings_nl.md index b0dece3c..50d7a427 100644 --- a/docs/keybindings/Keybindings_nl.md +++ b/docs/keybindings/Keybindings_nl.md @@ -7,7 +7,6 @@ o: open lazydocker config [: previous tab ]: next tab - : next tab m: view logs enter: focus main panel diff --git a/docs/keybindings/Keybindings_pl.md b/docs/keybindings/Keybindings_pl.md index b0dece3c..50d7a427 100644 --- a/docs/keybindings/Keybindings_pl.md +++ b/docs/keybindings/Keybindings_pl.md @@ -7,7 +7,6 @@ o: open lazydocker config [: previous tab ]: next tab - : next tab m: view logs enter: focus main panel diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index 4753582c..e3b44f77 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -154,11 +154,10 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { Description: gui.Tr.NextContext, }, { - ViewName: "status", - Key: gocui.MouseLeft, - Modifier: gocui.ModNone, - Handler: gui.handleStatusClick, - Description: gui.Tr.NextContext, + ViewName: "status", + Key: gocui.MouseLeft, + Modifier: gocui.ModNone, + Handler: gui.handleStatusClick, }, { ViewName: "status", From b7c548121c9cc0cf5e1bd05280259c62cd553372 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kr=C3=BCger?= Date: Sun, 30 Jun 2019 18:17:47 +0200 Subject: [PATCH 02/26] Translate german.go Added a new 'german.go' file and translated it using the English version as a base. --- pkg/i18n/german.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 pkg/i18n/german.go diff --git a/pkg/i18n/german.go b/pkg/i18n/german.go new file mode 100644 index 00000000..e69de29b From 08f94efbf78d06f027d0456e20e783b95e7a7020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kr=C3=BCger?= Date: Sun, 30 Jun 2019 18:25:13 +0200 Subject: [PATCH 03/26] Translate keybinding docs Translated the keybinding docs, added a new file for the German version, and it is based on the English version --- docs/keybindings/Keybindings_de..md | 68 +++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 docs/keybindings/Keybindings_de..md diff --git a/docs/keybindings/Keybindings_de..md b/docs/keybindings/Keybindings_de..md new file mode 100644 index 00000000..7fe3d684 --- /dev/null +++ b/docs/keybindings/Keybindings_de..md @@ -0,0 +1,68 @@ +# Lazydocker menu + +## Status + +
+  e: barbeite lazydocker Konfiguration
+  o: öffne lazydocker Konfiguration
+  [: vorheriges Tab
+  ]: nächstes tab
+  m: zeige Protokoll
+  enter: fokusieren aufs Hauptpanel
+
+ +## Containers + +
+  [: vorheriges Tab
+  ]: nächstes Tab
+  d: entfernen
+  s: anhalten
+  r: neustarten
+  a: anbinden
+  D: entferne verlassene Container
+  m: zeige Protokolle
+  c: führe vordefinierten benutzerdefinierten Befehl aus
+  enter: fokusieren aufs Hauptpanel
+
+ +## Services + +
+  d: entferne Container
+  s: anhalten
+  r: neustarten
+  a: anbinden
+  m: zeige Protokolle
+  [: vorheriges Tab
+  ]: nächstes Tab
+  R: zeige Neustartoptionen
+  c: führe vordefinierten benutzerdefinierten Befehl aus
+  enter: fokusieren aufs Hauptpanel
+
+ +## Images + +
+  [: vorheriges Tab
+  ]: nächstes Tab
+  d: entferne Image
+  D: entferne unbenutzte Images
+  enter: fokusieren aufs Hauptpanel
+
+ +## Volumes + +
+  [: vorheriges Tab
+  ]: nächstes Tab
+  d: entferne Volumen
+  D: entferne unbenutzte Volumen
+  enter: fokusieren aufs Hauptpanel
+
+ +## Main + +
+  esc: zurück
+
From 5c0b355ca77ddf9c2e6bdeb820434b6b748a281e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kr=C3=BCger?= Date: Sun, 30 Jun 2019 18:28:39 +0200 Subject: [PATCH 04/26] Adding 'german.go' Prior commit failed for unknown reason, but this is again the translated file based on the English version. --- pkg/i18n/german.go | 90 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/pkg/i18n/german.go b/pkg/i18n/german.go index e69de29b..b005b3e6 100644 --- a/pkg/i18n/german.go +++ b/pkg/i18n/german.go @@ -0,0 +1,90 @@ +package i18n + +func germanSet() TranslationSet { + return TranslationSet{ + PruningStatus: "zerstören", + RemovingStatus: "entfernen", + RestartingStatus: "neustarten", + StoppingStatus: "anhalten", + RunningCustomCommandStatus: "führt benutzerdefinierten Befehl aus", + + RunningSubprocess: "Unterprozess ausführen", + NoViewMachingNewLineFocusedSwitchStatement: "No view matching newLineFocused switch statement", + + ErrorOccurred: "Es ist ein Fehler aufgetreten! Bitte erstelle ein Issue hier: https://github.com/jesseduffield/lazydocker/issues", + ConnectionFailed: "Verbindung zum Docker Client fehlgeschlagen. Du musst ggf. den Docker Client neustarten.", + UnattachableContainerError: "Der Container bietet keine Unterstützung für das Anbinden. Du musst den Dienst entweder mit der '-it' Flagge benutzen oder `stdin_open: true, tty: true` in der docker-compose.yml Datei setzen.", + CannotAttachStoppedContainerError: "Du kannst keinen angehaltenen Container anbinden. Du musst ihn erst starten (was du tun kannst, indem du 'r' drückst), (ja, ich bin zu faul um das zu automatisieren) (aber ist schon cool, dass ich so eine Konversation durch eine Fehlermeldung mit dir führen kann)", + CannotAccessDockerSocketError: "Kann nicht auf den Socket zugreifen: unix:///var/run/docker.sock\nFühre lazydocker als root aus oder lese https://docs.docker.com/install/linux/linux-postinstall/", + + Donate: "Spenden", + Confirm: "Bestätigen", + + Return: "zurück", + FocusMain: "fokusieren aufs Hauptpanel", + Navigate: "navigieren", + Execute: "ausführen", + Close: "schließen", + Menu: "Menü", + Scroll: "scrolenl", + OpenConfig: "öffne lazydocker Konfiguration", + EditConfig: "bearbeite lazydocker Konfiguration", + Cancel: "abbrechen", + Remove: "entfernen", + ForceRemove: "Entfernen erzwingen", + RemoveWithVolumes: "entferne mit Volumen", + RemoveService: "entferne Container", + Stop: "stopp", + Restart: "neustarten", + Rebuild: "neubauen", + Recreate: "neuerstellen", + PreviousContext: "vorheriges Tab", + NextContext: "nächstes Tab", + Attach: "anbinden", + ViewLogs: "zeige Protokolle", + RemoveImage: "entferne Image", + RemoveVolume: "entferne Volumen", + RemoveWithoutPrune: "entfernen, ohne die unmarkierten Elntern zu entfernen", + PruneContainers: "entferne verlassene Container", + PruneVolumes: "entferne unbenutzte Volumen", + PruneImages: "entferne unbenutzte Images", + ViewRestartOptions: "zeige Neustartoptionen", + RunCustomCommand: "führe vordefinierten benutzerdefinierten Befehl aus", + + AnonymousReportingTitle: "Mache dabei mit layzdocker besser zu machen", + AnonymousReportingPrompt: "Would you like to enable anonymous reporting data to help improve lazydocker? (enter/esc)", + + GlobalTitle: "Global", + MainTitle: "Haupt", + StatusTitle: "Status", + ServicesTitle: "Dienste", + ContainersTitle: "Container", + StandaloneContainersTitle: "Alleinstehende Container", + ImagesTitle: "Images", + VolumesTitle: "Volumen", + CustomCommandTitle: "Benutzerdefinierter Befehl:", + ErrorTitle: "Fehler", + LogsTitle: "Protokoll", + ConfigTitle: "Konfiguration", + DockerComposeConfigTitle: "Docker-Compose Konfiguration", + TopTitle: "Top", + StatsTitle: "Statistiken", + CreditsTitle: "Über Uns", + ContainerConfigTitle: "Container Konfiguration", + + NoContainers: "Keine Container", + NoContainer: "Kein Container", + NoImages: "Keine Images", + NoVolumes: "Keine Volumen", + + ConfirmQuit: "Bist dD dir sicher, dass du verlassen möchtest?", + MustForceToRemoveContainer: "Du kannst keinen Container entfernen, der noch ausgeführt wird außer du erzwingst es. Möchtest du es erzwingen?", + NotEnoughSpace: "Nicht genug Platz um die Panele darzustellen", + ConfirmPruneImages: "Bist du dir sicher, dass du alle unbenutzten Images entfernen möchtest?", + ConfirmPruneContainers: "Bist du dir sicher, dass du alle angehaltenen Container entfernen möchtes?", + ConfirmPruneVolumes: "Bist du dir sicher, dass du alle unbenutzen Volumen entfernen möchtest?", + StopService: "Bist du dir sicher, dass du den Dienst dieses Containers anhalten möchtest? (enter/esc)", + StopContainer: "Bist du dir sicher, dass du den Container anhalten möchtest?", + PressEnterToReturn: "Drücke Eingabe um zu layzdocker zurück zu kehren. (Diese Nachfrage kann in Deiner Konfiguration deaktiviert werden, indem du folgenden Wert setzt: `gui.returnImmediately: true`)", + } +} From 70cffacddcd3cfe30795533825cfd5ac01664dc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kr=C3=BCger?= Date: Sun, 30 Jun 2019 18:35:01 +0200 Subject: [PATCH 05/26] fixed typos in 'german.go' --- pkg/i18n/german.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pkg/i18n/german.go b/pkg/i18n/german.go index b005b3e6..8b610cd5 100644 --- a/pkg/i18n/german.go +++ b/pkg/i18n/german.go @@ -26,7 +26,7 @@ func germanSet() TranslationSet { Execute: "ausführen", Close: "schließen", Menu: "Menü", - Scroll: "scrolenl", + Scroll: "scrollen", OpenConfig: "öffne lazydocker Konfiguration", EditConfig: "bearbeite lazydocker Konfiguration", Cancel: "abbrechen", @@ -34,7 +34,7 @@ func germanSet() TranslationSet { ForceRemove: "Entfernen erzwingen", RemoveWithVolumes: "entferne mit Volumen", RemoveService: "entferne Container", - Stop: "stopp", + Stop: "anhalten", Restart: "neustarten", Rebuild: "neubauen", Recreate: "neuerstellen", @@ -44,15 +44,15 @@ func germanSet() TranslationSet { ViewLogs: "zeige Protokolle", RemoveImage: "entferne Image", RemoveVolume: "entferne Volumen", - RemoveWithoutPrune: "entfernen, ohne die unmarkierten Elntern zu entfernen", + RemoveWithoutPrune: "entfernen, ohne die unmarkierten Eltern zu entfernen", PruneContainers: "entferne verlassene Container", PruneVolumes: "entferne unbenutzte Volumen", PruneImages: "entferne unbenutzte Images", ViewRestartOptions: "zeige Neustartoptionen", RunCustomCommand: "führe vordefinierten benutzerdefinierten Befehl aus", - AnonymousReportingTitle: "Mache dabei mit layzdocker besser zu machen", - AnonymousReportingPrompt: "Would you like to enable anonymous reporting data to help improve lazydocker? (enter/esc)", + AnonymousReportingTitle: "Mache dabei mit lazydocker besser zu machen", + AnonymousReportingPrompt: "Möchtest du anonymiserte Datensammlung erlauben, um zu helfen lazydocker zu erbessern? (enter/esc)", GlobalTitle: "Global", MainTitle: "Haupt", @@ -62,7 +62,7 @@ func germanSet() TranslationSet { StandaloneContainersTitle: "Alleinstehende Container", ImagesTitle: "Images", VolumesTitle: "Volumen", - CustomCommandTitle: "Benutzerdefinierter Befehl:", + CustomCommandTitle: "Benutzerdefinierter Befehl", ErrorTitle: "Fehler", LogsTitle: "Protokoll", ConfigTitle: "Konfiguration", @@ -77,7 +77,7 @@ func germanSet() TranslationSet { NoImages: "Keine Images", NoVolumes: "Keine Volumen", - ConfirmQuit: "Bist dD dir sicher, dass du verlassen möchtest?", + ConfirmQuit: "Bist du dir sicher, dass du verlassen möchtest?", MustForceToRemoveContainer: "Du kannst keinen Container entfernen, der noch ausgeführt wird außer du erzwingst es. Möchtest du es erzwingen?", NotEnoughSpace: "Nicht genug Platz um die Panele darzustellen", ConfirmPruneImages: "Bist du dir sicher, dass du alle unbenutzten Images entfernen möchtest?", @@ -85,6 +85,6 @@ func germanSet() TranslationSet { ConfirmPruneVolumes: "Bist du dir sicher, dass du alle unbenutzen Volumen entfernen möchtest?", StopService: "Bist du dir sicher, dass du den Dienst dieses Containers anhalten möchtest? (enter/esc)", StopContainer: "Bist du dir sicher, dass du den Container anhalten möchtest?", - PressEnterToReturn: "Drücke Eingabe um zu layzdocker zurück zu kehren. (Diese Nachfrage kann in Deiner Konfiguration deaktiviert werden, indem du folgenden Wert setzt: `gui.returnImmediately: true`)", + PressEnterToReturn: "Drücke Eingabe um zu lazydocker zurück zu kehren. (Diese Nachfrage kann in Deiner Konfiguration deaktiviert werden, indem du folgenden Wert setzt: `gui.returnImmediately: true`)", } } From 56626b9af6b0e049088f8b99af1277fe4d19ec69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kr=C3=BCger?= Date: Sun, 30 Jun 2019 18:38:36 +0200 Subject: [PATCH 06/26] Fixed typo in Keybindings_de filename It had one too many dots 'Keybindings_de..md' is now 'Keybindings_de.md' --- docs/keybindings/{Keybindings_de..md => Keybindings_de.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename docs/keybindings/{Keybindings_de..md => Keybindings_de.md} (96%) diff --git a/docs/keybindings/Keybindings_de..md b/docs/keybindings/Keybindings_de.md similarity index 96% rename from docs/keybindings/Keybindings_de..md rename to docs/keybindings/Keybindings_de.md index 7fe3d684..68b42395 100644 --- a/docs/keybindings/Keybindings_de..md +++ b/docs/keybindings/Keybindings_de.md @@ -3,7 +3,7 @@ ## Status
-  e: barbeite lazydocker Konfiguration
+  e: bearbeite lazydocker Konfiguration
   o: öffne lazydocker Konfiguration
   [: vorheriges Tab
   ]: nächstes tab

From f4f56055e51c0319a66853fa03e13a603a064b56 Mon Sep 17 00:00:00 2001
From: Jesse Duffield 
Date: Mon, 1 Jul 2019 09:24:41 +1000
Subject: [PATCH 07/26] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 3dff58cb..57b35619 100644
--- a/README.md
+++ b/README.md
@@ -80,7 +80,7 @@ everything is one keypress away (or one click away! Mouse support FTW):
 There is still a lot of work to go! Please check out the [contributing guide](CONTRIBUTING.md).
 For contributor discussion about things not better discussed here in the repo, join the slack channel
 
-[![Slack](/docs/resources/slack_rgb.png)](https://join.slack.com/t/lazydocker/shared_invite/enQtNDE3MjIwNTYyMDA0LTM3Yjk3NzdiYzhhNTA1YjM4Y2M4MWNmNDBkOTI0YTE4YjQ1ZmI2YWRhZTgwNjg2YzhhYjg3NDBlMmQyMTI5N2M)
+[![Slack](/docs/resources/slack_rgb.png)](https://join.slack.com/t/lazydocker/shared_invite/enQtNjgwMjc0Njk3MzgwLTM0NThlMTZiZmNkNWJkY2VlYWYwZmY1NWYyYWViZmE0ZTcxMWZjMTFjNTU1ZTEwMDBiNWIxZTIxYzkwNDgyY2M)
 
 ## Donate
 

From 541bf0310ad379e8261a37a7882aa23480995b10 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Kr=C3=BCger?= 
Date: Mon, 1 Jul 2019 02:04:39 +0200
Subject: [PATCH 08/26] Add check for German in 'i18n.go'

---
 pkg/i18n/i18n.go | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/pkg/i18n/i18n.go b/pkg/i18n/i18n.go
index 3b9a36e4..4f6a93fc 100644
--- a/pkg/i18n/i18n.go
+++ b/pkg/i18n/i18n.go
@@ -34,6 +34,10 @@ func NewTranslationSet(log *logrus.Entry) *TranslationSet {
 		mergo.Merge(&set, polishSet(), mergo.WithOverride)
 	}
 
+	if strings.HasPrefix(userLang, "de") {
+		mergo.Merge(&set, germanSet(), mergo.WithOverride)
+	}
+
 	return &set
 }
 

From 0fe35ba5c534e863aeef03d55b788598e4bd51a2 Mon Sep 17 00:00:00 2001
From: haoyun 
Date: Mon, 1 Jul 2019 14:18:11 +0800
Subject: [PATCH 09/26] fix strings.ReplaceAll() does't exist error while go
 version bellow 1.12

---
 pkg/commands/image.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pkg/commands/image.go b/pkg/commands/image.go
index 51bc94d9..41f9b99f 100644
--- a/pkg/commands/image.go
+++ b/pkg/commands/image.go
@@ -68,7 +68,7 @@ func (l *Layer) GetDisplayStrings(isFocused bool) []string {
 		createdBy = utils.ColoredString(split[0], color.FgYellow) + " " + strings.Join(split[1:], " ")
 	}
 
-	createdBy = strings.ReplaceAll(createdBy, "\t", " ")
+	createdBy = strings.Replace(createdBy, "\t", " ", -1)
 
 	size := utils.FormatBinaryBytes(int(l.Size))
 	sizeColor := color.FgWhite

From e3f6f5989064c3759515c4613f7535d7ed23d224 Mon Sep 17 00:00:00 2001
From: mjarkk 
Date: Mon, 1 Jul 2019 09:50:00 +0200
Subject: [PATCH 10/26] Removed some dead code

---
 coverage.txt                      | 1086 ++++++++++++-----------------
 pkg/app/app.go                    |   11 -
 pkg/commands/exec_live_default.go |  100 ---
 pkg/commands/exec_live_win.go     |    9 -
 pkg/commands/os.go                |   31 -
 pkg/gui/confirmation_panel.go     |    8 -
 pkg/gui/gui.go                    |    4 -
 pkg/gui/view_helpers.go           |   32 -
 pkg/test/utils.go                 |   45 --
 pkg/utils/utils.go                |   54 --
 pkg/utils/utils_test.go           |  193 -----
 11 files changed, 438 insertions(+), 1135 deletions(-)
 delete mode 100644 pkg/commands/exec_live_default.go
 delete mode 100644 pkg/commands/exec_live_win.go
 delete mode 100644 pkg/test/utils.go

diff --git a/coverage.txt b/coverage.txt
index 56f9d38a..4766f8c4 100644
--- a/coverage.txt
+++ b/coverage.txt
@@ -1,657 +1,447 @@
 
 mode: atomic
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:247.64,249.2 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:252.47,254.35 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:258.2,258.49 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:254.35,256.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:262.48,265.25 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:269.2,270.16 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:275.2,276.21 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:284.2,284.48 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:265.25,267.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:270.16,273.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:276.21,278.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:278.8,278.28 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:278.28,280.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:280.8,282.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:288.42,290.2 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:293.48,294.27 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:295.16,296.36 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:299.3,299.21 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:300.17,301.22 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:302.17,303.23 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:304.16,305.24 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:306.14,307.21 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:308.20,309.22 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:310.18,311.25 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:312.10,313.23 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:296.36,298.4 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:318.72,319.86 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:330.2,330.12 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:319.86,320.100 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:327.3,327.13 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:320.100,326.4 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:334.34,336.2 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:339.37,341.2 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:344.49,346.33 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:350.2,350.35 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:354.2,355.17 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:346.33,348.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:350.35,352.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:359.63,361.2 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:364.39,365.48 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:369.2,369.37 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:365.48,367.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:369.37,370.74 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:370.74,373.4 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:378.51,389.2 5 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:392.49,395.2 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:398.60,400.2 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:403.49,405.16 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:409.2,409.82 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:405.16,407.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container.go:413.42,415.2 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:28.60,31.2 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:34.64,35.85 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:39.2,39.12 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:35.85,37.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:48.60,50.21 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:54.2,55.18 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:58.2,59.23 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:63.2,65.60 3 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:71.2,75.18 4 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:79.2,84.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:50.21,52.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:55.18,57.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:59.23,61.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:65.60,69.3 3 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:75.18,77.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:88.49,91.16 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:95.2,96.32 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:100.2,100.93 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:91.16,93.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:96.32,98.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:104.59,106.16 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:110.2,112.31 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:139.2,139.23 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:106.16,108.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:112.31,117.20 3 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:121.3,123.25 3 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:127.3,136.4 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:117.20,119.4 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:123.25,125.4 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/image.go:143.45,146.2 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/os_default_platform.go:9.30,19.2 1 17
+github.com/jesseduffield/lazydocker/pkg/commands/service.go:23.62,25.24 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/service.go:29.2,30.76 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/service.go:25.24,27.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/service.go:34.70,36.2 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/service.go:39.32,46.2 3 0
+github.com/jesseduffield/lazydocker/pkg/commands/service.go:49.35,56.2 3 0
+github.com/jesseduffield/lazydocker/pkg/commands/service.go:59.47,61.2 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/service.go:64.61,66.2 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/service.go:69.49,80.2 5 0
+github.com/jesseduffield/lazydocker/pkg/commands/service.go:83.47,91.2 3 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:150.68,156.23 5 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:159.2,159.14 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:156.23,158.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:163.66,166.23 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:169.2,169.14 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:166.23,168.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:173.64,175.23 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:178.2,182.34 4 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:190.2,195.16 5 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:199.2,207.22 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:175.23,177.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:182.34,184.17 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:187.3,187.78 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:184.17,186.4 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:195.16,197.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:211.83,216.38 4 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:248.2,249.21 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:253.2,260.8 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:216.38,218.17 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:221.3,222.17 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:225.3,225.25 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:235.3,235.25 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:245.3,245.23 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:218.17,220.4 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:222.17,224.4 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:225.25,226.14 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:226.14,228.5 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:228.10,229.25 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:229.25,231.6 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:235.25,236.14 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:236.14,238.5 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:238.10,239.25 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:239.25,241.6 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:249.21,251.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:264.49,268.25 3 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:269.15,270.16 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:271.15,272.25 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:273.13,274.25 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:275.13,276.25 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:277.11,278.25 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:279.14,280.25 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:281.14,282.25 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:283.12,284.25 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:285.14,286.35 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:287.10,290.40 3 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:290.40,293.4 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:293.9,293.48 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:293.48,297.4 3 0
+github.com/jesseduffield/lazydocker/pkg/commands/container_stats.go:297.9,299.4 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:56.75,60.2 3 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:63.161,65.16 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:69.2,92.16 5 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:97.2,97.27 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:65.16,67.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:92.16,95.3 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:101.49,104.2 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:107.52,112.16 4 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:117.2,121.21 4 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:138.2,140.8 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:112.16,115.3 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:121.21,125.69 3 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:129.3,130.42 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:135.3,135.28 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:125.69,128.4 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:130.42,131.32 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:131.32,133.5 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:144.55,147.35 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:147.35,148.42 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:148.42,149.34 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:149.34,151.5 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:156.71,159.16 3 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:164.2,167.21 3 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:187.2,188.8 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:159.16,162.3 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:167.21,185.3 8 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:192.62,199.16 5 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:203.2,205.28 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:214.2,217.47 3 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:224.2,224.43 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:236.2,240.12 4 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:199.16,201.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:205.28,207.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:207.8,209.17 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:209.17,211.4 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:217.47,219.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:219.8,221.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:224.43,225.67 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:229.3,229.67 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:233.3,233.45 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:225.67,227.4 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:229.67,231.4 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:243.98,245.35 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:245.35,246.40 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:252.3,252.26 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:246.40,247.66 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:247.66,249.15 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:257.111,260.39 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:269.2,269.29 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:260.39,261.36 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:266.3,266.65 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:261.36,262.97 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:262.97,263.15 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:273.63,280.16 5 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:284.2,286.39 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:325.2,325.27 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:280.16,282.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:286.39,290.56 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:298.3,298.26 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:310.3,312.47 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:317.3,322.34 5 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:290.56,291.44 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:291.44,293.10 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:298.26,308.4 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:312.47,314.4 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:314.9,316.4 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:329.59,330.31 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:334.2,336.16 3 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:344.2,346.28 3 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:357.2,357.22 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:330.31,332.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:336.16,338.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:346.28,355.3 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:362.56,369.39 5 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:373.2,375.16 3 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:379.2,380.57 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:384.2,384.39 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:388.2,388.12 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:369.39,371.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:375.16,377.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:380.57,382.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:384.39,386.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:392.58,403.2 3 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:406.54,414.16 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:417.2,417.15 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/docker.go:414.16,416.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/dummies.go:14.37,16.2 1 17
+github.com/jesseduffield/lazydocker/pkg/commands/dummies.go:19.44,29.2 2 17
+github.com/jesseduffield/lazydocker/pkg/commands/dummies.go:32.34,36.2 3 17
+github.com/jesseduffield/lazydocker/pkg/commands/dummies.go:39.45,41.2 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/dummies.go:44.78,51.2 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/errors.go:18.33,19.16 1 1
+github.com/jesseduffield/lazydocker/pkg/commands/errors.go:23.2,23.28 1 1
+github.com/jesseduffield/lazydocker/pkg/commands/errors.go:19.16,21.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/errors.go:35.61,39.2 3 0
+github.com/jesseduffield/lazydocker/pkg/commands/errors.go:42.52,44.2 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/errors.go:46.39,48.2 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/errors.go:51.45,53.35 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/errors.go:56.2,56.14 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/errors.go:53.35,55.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:45.75,54.2 1 17
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:58.71,60.2 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:63.74,69.2 5 5
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:72.76,74.2 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:77.56,80.2 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:83.71,87.2 2 5
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:90.54,93.2 2 3
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:96.50,98.16 2 4
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:101.2,101.22 1 3
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:104.2,104.15 1 2
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:98.16,100.3 1 1
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:101.22,103.3 1 1
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:108.70,115.2 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:117.71,119.16 2 5
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:127.2,127.26 1 2
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:119.16,122.25 1 3
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:125.3,125.48 1 2
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:122.25,124.4 1 1
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:131.53,140.2 5 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:143.49,152.2 5 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:156.66,159.18 2 5
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:162.2,162.18 1 5
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:165.2,165.18 1 5
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:170.2,170.18 1 5
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:174.2,174.51 1 4
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:159.18,161.3 1 4
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:162.18,164.3 1 3
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:165.18,166.50 1 2
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:166.50,168.4 1 1
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:170.18,172.3 1 1
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:178.88,180.2 1 4
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:183.50,186.56 3 3
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:189.2,189.46 1 3
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:186.56,188.3 1 1
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:194.52,196.2 1 1
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:199.67,201.16 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:204.2,207.16 3 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:210.2,210.12 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:201.16,203.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:207.16,209.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:214.78,216.16 2 1
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:221.2,221.56 1 1
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:225.2,225.40 1 1
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:230.2,230.28 1 1
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:216.16,219.3 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:221.56,224.3 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:225.40,228.3 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:234.51,237.2 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:240.59,241.41 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:247.2,247.18 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:241.41,242.25 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:245.3,245.20 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:242.25,244.4 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:253.61,257.16 4 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:263.2,263.12 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:257.16,258.26 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:261.3,261.31 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:258.26,260.4 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:267.48,269.16 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:272.2,272.29 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:269.16,271.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:276.64,278.2 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:281.66,285.37 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:289.2,289.35 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:301.2,306.27 4 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:332.2,334.26 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:337.2,337.12 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:285.37,287.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:289.35,291.17 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:295.3,295.27 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:291.17,293.4 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:306.27,308.13 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:308.13,310.18 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:314.4,314.45 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:318.4,318.52 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:324.4,324.44 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:328.4,328.13 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:310.18,312.5 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:314.45,316.5 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:318.52,319.19 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:319.19,321.6 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:324.44,326.5 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:334.26,336.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:341.47,342.24 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:346.2,346.63 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:351.2,351.27 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:342.24,345.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:346.63,349.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/os.go:355.55,359.2 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/volume.go:24.61,26.2 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/volume.go:29.48,31.16 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/volume.go:35.2,39.42 3 0
+github.com/jesseduffield/lazydocker/pkg/commands/volume.go:43.2,43.33 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/volume.go:54.2,56.12 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/volume.go:31.16,33.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/volume.go:39.42,41.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/volume.go:43.33,52.3 1 0
+github.com/jesseduffield/lazydocker/pkg/commands/volume.go:60.46,63.2 2 0
+github.com/jesseduffield/lazydocker/pkg/commands/volume.go:66.43,68.2 1 0
+mode: atomic
+mode: atomic
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:23.50,25.54 2 3
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:28.2,29.31 2 1
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:32.2,32.14 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:25.54,27.3 1 2
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:29.31,31.3 1 1
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:36.50,38.33 2 11
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:41.2,41.61 1 10
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:38.33,40.3 1 1
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:46.71,48.37 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:51.2,52.41 2 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:48.37,50.3 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:57.66,59.2 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:62.44,66.2 3 4
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:69.22,75.2 5 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:78.79,79.36 1 7
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:82.2,82.12 1 7
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:79.36,81.3 1 5
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:86.24,87.11 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:90.2,90.10 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:87.11,89.3 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:102.58,103.35 1 1
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:103.35,105.3 1 1
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:108.60,109.35 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:109.35,111.3 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:117.88,119.33 2 4
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:123.2,124.31 2 4
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:128.2,130.31 2 3
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:138.2,138.53 1 2
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:119.33,121.3 1 1
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:124.31,126.3 1 1
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:130.31,132.10 2 4
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:135.3,135.26 1 3
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:132.10,134.4 1 1
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:145.90,146.21 1 6
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:150.2,151.28 2 6
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:155.2,155.34 1 6
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:146.21,148.3 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:151.28,153.3 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:159.59,160.41 1 6
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:164.2,167.54 3 5
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:160.41,162.3 1 1
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:171.36,174.2 2 22
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:176.50,177.31 1 8
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:180.2,181.27 2 5
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:189.2,189.18 1 5
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:177.31,179.3 1 3
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:181.27,182.40 1 6
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:182.40,184.43 2 11
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:184.43,186.5 1 6
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:192.81,194.43 2 6
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:203.2,203.29 1 6
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:194.43,195.28 1 11
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:198.3,198.38 1 9
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:201.3,201.57 1 9
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:195.28,196.12 1 2
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:198.38,200.4 1 9
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:208.57,209.39 1 8
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:214.2,214.13 1 6
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:209.39,210.43 1 15
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:210.43,212.4 1 2
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:217.84,219.36 2 8
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:222.2,222.21 1 8
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:219.36,221.3 1 15
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:225.38,228.29 3 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:239.2,239.16 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:228.29,229.26 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:229.26,231.4 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:231.9,233.22 2 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:236.4,236.14 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:233.22,235.5 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:242.39,245.29 3 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:256.2,256.16 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:245.29,246.26 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:246.26,248.4 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:248.9,250.22 2 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:253.4,253.14 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:250.22,252.5 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:259.59,263.2 3 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:266.52,282.13 3 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:285.2,285.25 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:282.13,284.3 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:289.52,304.13 3 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:307.2,307.22 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:304.13,306.3 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:311.38,313.29 2 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:319.2,319.33 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:313.29,315.22 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:315.22,317.4 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:323.65,325.2 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:328.57,329.17 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:333.2,336.21 3 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:339.2,340.27 2 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:344.2,344.15 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:329.17,331.3 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:336.21,338.3 1 0
+github.com/jesseduffield/lazydocker/pkg/utils/utils.go:340.27,342.3 1 0
 mode: atomic
 mode: atomic
 mode: atomic
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:22.50,24.54 2 3
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:27.2,28.31 2 1
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:31.2,31.14 1 0
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:24.54,26.3 1 2
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:28.31,30.3 1 1
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:35.50,36.26 1 11
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:39.2,39.52 1 10
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:36.26,38.3 1 1
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:44.71,47.2 2 0
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:51.66,53.2 1 0
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:56.34,58.16 2 0
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:61.2,61.27 1 0
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:58.16,60.3 1 0
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:66.45,67.34 1 2
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:70.2,70.12 1 1
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:67.34,69.3 1 1
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:74.44,78.2 3 4
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:83.30,85.16 2 0
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:88.2,88.53 1 0
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:85.16,86.13 1 0
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:92.22,98.2 5 0
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:101.79,102.36 1 7
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:105.2,105.12 1 7
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:102.36,104.3 1 5
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:109.24,110.11 1 3
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:113.2,113.10 1 2
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:110.11,112.3 1 1
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:123.68,125.31 2 4
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:129.2,131.31 2 3
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:139.2,139.55 1 2
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:125.31,127.3 1 1
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:131.31,133.10 2 4
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:136.3,136.26 1 3
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:133.10,135.4 1 1
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:146.81,147.21 1 6
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:151.2,153.41 2 6
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:157.2,160.54 3 5
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:147.21,149.3 1 0
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:153.41,155.3 1 1
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:164.36,167.2 2 11
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:169.50,170.31 1 8
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:173.2,174.27 2 5
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:182.2,182.18 1 5
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:170.31,172.3 1 3
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:174.27,175.40 1 6
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:175.40,177.43 2 11
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:177.43,179.5 1 6
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:185.81,187.43 2 6
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:196.2,196.29 1 6
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:187.43,188.28 1 11
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:191.3,191.38 1 9
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:194.3,194.57 1 9
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:188.28,189.12 1 2
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:191.38,193.4 1 9
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:201.57,202.39 1 8
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:207.2,207.13 1 6
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:202.39,203.43 1 15
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:203.43,205.4 1 2
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:210.84,212.36 2 8
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:215.2,215.21 1 8
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:212.36,214.3 1 15
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:219.51,220.25 1 4
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:225.2,225.14 1 2
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:220.25,221.13 1 6
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:221.13,223.4 1 2
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:229.54,230.37 1 5
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:235.2,235.10 1 3
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:230.37,231.29 1 8
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:231.29,233.4 1 2
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:239.54,241.31 2 4
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:246.2,246.12 1 3
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:241.31,242.33 1 6
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:242.33,244.4 1 1
-github.com/jesseduffield/lazydocker/pkg/utils/utils.go:249.35,252.2 2 1
 mode: atomic
 mode: atomic
 mode: atomic
-github.com/jesseduffield/lazydocker/pkg/commands/branch.go:22.61,24.71 2 0
-github.com/jesseduffield/lazydocker/pkg/commands/branch.go:28.2,28.41 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/branch.go:24.71,26.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/branch.go:32.45,33.21 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/branch.go:34.17,35.23 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/branch.go:36.16,37.24 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/branch.go:38.16,39.21 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/branch.go:40.10,41.23 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/branch.go:46.35,48.2 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/commit_file.go:11.65,13.2 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/dummies.go:16.37,18.2 1 99
-github.com/jesseduffield/lazydocker/pkg/commands/dummies.go:21.44,33.2 3 178
-github.com/jesseduffield/lazydocker/pkg/commands/dummies.go:36.34,40.2 3 257
-github.com/jesseduffield/lazydocker/pkg/commands/dummies.go:43.39,45.2 1 77
-github.com/jesseduffield/lazydocker/pkg/commands/dummies.go:48.72,54.52 1 77
-github.com/jesseduffield/lazydocker/pkg/commands/dummies.go:54.52,54.70 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/dummies.go:55.52,55.70 1 6
-github.com/jesseduffield/lazydocker/pkg/commands/dummies.go:56.42,56.56 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/os_default_platform.go:9.30,19.2 1 99
-github.com/jesseduffield/lazydocker/pkg/commands/pull_request.go:29.31,44.2 1 5
-github.com/jesseduffield/lazydocker/pkg/commands/pull_request.go:47.58,52.2 1 5
-github.com/jesseduffield/lazydocker/pkg/commands/pull_request.go:55.53,58.27 2 5
-github.com/jesseduffield/lazydocker/pkg/commands/pull_request.go:62.2,65.41 3 5
-github.com/jesseduffield/lazydocker/pkg/commands/pull_request.go:72.2,72.23 1 5
-github.com/jesseduffield/lazydocker/pkg/commands/pull_request.go:76.2,80.4 2 4
-github.com/jesseduffield/lazydocker/pkg/commands/pull_request.go:58.27,60.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/pull_request.go:65.41,66.46 1 11
-github.com/jesseduffield/lazydocker/pkg/commands/pull_request.go:66.46,68.9 2 4
-github.com/jesseduffield/lazydocker/pkg/commands/pull_request.go:72.23,74.3 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/pull_request.go:83.54,86.12 2 6
-github.com/jesseduffield/lazydocker/pkg/commands/pull_request.go:97.2,105.3 5 4
-github.com/jesseduffield/lazydocker/pkg/commands/pull_request.go:86.12,95.3 4 2
-github.com/jesseduffield/lazydocker/pkg/commands/commit.go:19.61,34.18 10 0
-github.com/jesseduffield/lazydocker/pkg/commands/commit.go:49.2,49.14 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/commit.go:53.2,54.20 2 0
-github.com/jesseduffield/lazydocker/pkg/commands/commit.go:58.2,58.78 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/commit.go:35.18,36.17 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/commit.go:37.16,38.20 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/commit.go:39.16,40.19 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/commit.go:41.18,42.18 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/commit.go:43.18,44.21 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/commit.go:45.10,46.19 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/commit.go:49.14,51.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/commit.go:54.20,56.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/errors.go:8.33,9.16 1 18
-github.com/jesseduffield/lazydocker/pkg/commands/errors.go:13.2,13.28 1 16
-github.com/jesseduffield/lazydocker/pkg/commands/errors.go:9.16,11.3 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:22.102,34.16 8 3
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:38.2,38.12 1 3
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:47.2,49.16 3 3
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:53.2,53.12 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:34.16,36.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:38.12,41.22 3 3
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:41.22,44.4 2 2
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:49.16,51.3 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:58.92,60.52 2 7
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:67.2,67.54 1 7
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:74.2,74.32 1 7
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:77.2,77.24 1 5
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:60.52,63.18 3 4
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:63.18,64.9 1 4
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:67.54,70.17 3 8
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:70.17,72.4 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:74.32,76.3 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:82.27,83.19 1 12
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:92.2,92.36 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:95.2,95.11 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:99.2,99.14 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:83.19,84.12 1 12
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:90.3,90.15 1 12
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:85.30,86.15 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:87.27,88.15 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:92.36,94.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/exec_live_default.go:96.66,97.14 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/file.go:20.59,25.39 3 0
-github.com/jesseduffield/lazydocker/pkg/commands/file.go:29.2,31.26 3 0
-github.com/jesseduffield/lazydocker/pkg/commands/file.go:36.2,36.25 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/file.go:25.39,27.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/file.go:31.26,33.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/file.go:33.8,35.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:22.55,24.2 1 4
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:26.106,27.6 1 4
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:27.6,30.30 2 4
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:34.3,34.26 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:38.3,38.36 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:30.30,32.4 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:34.26,36.4 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:38.36,40.4 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:44.191,47.16 2 5
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:55.2,57.16 2 3
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:61.2,61.8 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:47.16,48.81 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:52.3,52.9 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:48.81,50.4 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:57.16,59.3 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:78.131,83.16 3 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:96.2,96.23 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:102.2,112.8 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:83.16,85.4 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:86.16,88.4 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:89.16,93.4 3 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:96.23,97.29 1 4
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:97.29,99.4 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:116.54,119.51 3 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:122.2,122.21 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:119.51,121.3 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:125.61,131.2 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:134.67,136.2 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:139.47,144.45 4 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:165.2,165.14 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:144.45,164.3 8 4
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:169.62,171.2 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:175.54,177.2 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:180.75,181.24 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:185.2,189.35 3 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:200.2,200.39 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:206.2,206.15 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:181.24,183.3 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:189.35,190.43 1 3
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:190.43,191.36 1 9
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:191.36,194.10 3 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:200.39,201.43 1 3
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:201.43,203.4 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:209.42,210.25 1 3
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:215.2,215.14 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:210.25,211.13 1 3
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:211.13,213.4 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:219.44,220.42 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:224.2,224.33 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:220.42,222.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:227.81,229.2 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:231.91,234.2 2 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:238.77,241.16 3 3
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:244.2,245.16 2 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:248.2,248.75 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:241.16,243.3 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:245.16,247.3 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:252.54,254.2 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:257.60,259.16 2 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:263.2,263.44 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:259.16,261.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:267.100,268.79 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:268.79,269.27 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:272.3,272.14 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:269.27,271.4 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:277.54,279.2 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:282.51,284.2 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:287.58,289.16 2 3
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:295.2,295.51 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:289.16,291.17 2 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:291.17,293.4 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:299.68,302.11 2 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:306.2,306.70 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:302.11,304.3 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:310.50,312.2 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:315.53,317.2 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:320.41,322.2 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:326.38,328.19 2 15
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:331.2,333.75 2 15
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:328.19,330.3 1 10
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:337.64,339.18 2 3
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:343.2,343.45 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:339.18,341.3 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:347.53,349.18 2 4
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:353.2,353.45 1 3
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:349.18,351.3 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:357.58,359.2 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:362.89,364.11 2 3
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:368.2,369.46 2 3
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:364.11,366.3 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:373.63,375.2 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:378.55,380.2 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:383.39,385.2 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:388.41,390.2 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:393.71,395.13 2 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:400.2,401.33 2 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:406.2,406.12 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:395.13,397.3 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:401.33,402.95 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:402.95,404.4 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:410.50,412.2 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:415.53,417.16 2 4
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:420.2,420.102 1 3
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:417.16,419.3 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:425.51,427.16 2 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:430.2,430.12 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:433.2,434.12 2 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:427.16,429.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:430.12,432.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:434.12,436.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:436.8,438.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:442.62,445.27 2 7
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:450.2,450.19 1 6
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:453.2,453.43 1 3
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:445.27,446.96 1 3
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:446.96,448.4 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:450.19,452.3 1 3
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:457.67,460.2 2 4
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:463.64,465.11 2 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:468.2,468.84 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:465.11,467.3 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:473.58,475.2 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:478.58,480.2 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:483.63,485.2 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:490.72,492.2 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:495.52,497.2 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:500.55,502.16 2 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:507.2,508.16 2 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:512.2,512.23 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:519.2,520.20 2 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:524.2,525.30 2 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:529.2,530.16 2 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:533.2,533.30 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:502.16,504.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:508.16,511.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:512.23,514.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:520.20,522.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:525.30,527.3 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:530.16,532.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:537.44,540.2 2 5
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:543.67,550.2 2 5
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:553.58,559.55 6 4
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:562.2,562.45 1 4
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:565.2,565.11 1 4
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:569.2,573.10 3 4
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:559.55,561.3 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:562.45,564.3 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:565.11,567.3 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:576.63,578.16 2 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:583.2,583.15 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:585.2,585.108 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:578.16,581.3 2 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:583.15,583.51 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:588.59,591.2 2 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:593.65,601.2 3 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:605.77,613.2 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:615.84,617.16 2 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:621.2,621.77 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:617.16,619.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:624.73,626.29 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:631.2,633.40 3 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:637.2,638.16 2 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:642.2,642.44 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:626.29,629.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:633.40,635.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:638.16,640.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:645.91,647.16 2 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:651.2,652.16 2 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:656.2,656.44 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:647.16,649.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:652.16,654.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:662.123,666.43 3 3
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:670.2,675.16 4 3
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:679.2,690.20 3 3
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:694.2,694.17 1 3
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:666.43,668.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:675.16,677.3 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:690.20,692.3 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:697.54,699.2 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:701.54,703.2 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:705.109,706.29 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:711.2,712.46 2 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:719.2,719.18 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:706.29,709.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:712.46,714.17 2 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:717.3,717.64 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:714.17,716.4 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:723.48,724.49 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:728.2,728.42 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:724.49,726.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:732.69,735.16 3 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:739.2,749.57 7 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:735.16,737.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:752.63,755.31 2 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:760.2,760.20 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:755.31,756.50 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:756.50,758.4 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:764.52,767.16 3 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:771.2,779.57 7 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:767.16,769.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:783.47,785.2 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:788.65,790.33 2 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:794.2,795.16 2 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:799.2,799.44 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:790.33,792.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:795.16,797.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:803.78,806.16 3 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:810.2,812.75 2 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:820.2,820.25 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:806.16,808.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:812.75,818.3 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:824.81,827.2 2 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:830.69,833.2 2 3
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:836.103,837.34 1 3
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:844.2,844.18 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:848.2,851.16 3 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:855.2,856.16 2 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:860.2,860.60 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:865.2,865.98 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:879.2,880.16 2 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:883.2,883.16 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:888.2,888.45 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:837.34,839.3 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:844.18,846.3 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:851.16,853.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:856.16,858.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:860.60,862.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:865.98,866.54 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:869.3,869.47 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:866.54,868.4 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:869.47,871.4 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:872.8,873.59 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:873.59,875.4 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:880.16,882.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:883.16,885.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:892.60,894.2 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:897.51,899.2 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:902.44,904.2 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:907.44,909.2 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:912.69,915.2 2 0
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:918.58,921.2 2 1
-github.com/jesseduffield/lazydocker/pkg/commands/git.go:924.67,931.2 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:42.78,51.2 1 99
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:55.71,57.2 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:60.74,64.2 3 91
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:67.76,69.2 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:72.56,75.2 2 1
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:78.71,82.2 3 92
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:85.96,87.2 1 3
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:92.84,94.77 2 3
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:111.2,111.19 1 3
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:94.77,102.40 3 2
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:109.3,109.12 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:102.40,103.63 1 4
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:103.63,106.5 2 0
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:115.54,118.2 2 45
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:121.50,123.16 2 8
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:126.2,126.22 1 3
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:129.2,129.15 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:123.16,125.3 1 5
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:126.22,128.3 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:133.70,140.2 2 0
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:142.71,144.16 2 92
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:152.2,152.26 1 75
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:144.16,147.25 1 17
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:150.3,150.48 1 3
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:147.25,149.4 1 14
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:156.53,165.2 5 3
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:168.49,177.2 5 4
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:181.66,184.18 2 5
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:187.2,187.18 1 5
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:190.2,190.18 1 5
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:195.2,195.18 1 5
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:199.2,199.51 1 4
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:184.18,186.3 1 4
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:187.18,189.3 1 3
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:190.18,191.50 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:191.50,193.4 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:195.18,197.3 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:203.88,205.2 1 7
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:208.50,211.56 3 36
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:214.2,214.46 1 36
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:211.56,213.3 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:219.52,221.2 1 5
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:224.67,226.16 2 0
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:229.2,232.16 3 0
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:235.2,235.12 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:226.16,228.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:232.16,234.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:239.78,241.16 2 3
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:246.2,246.56 1 3
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:250.2,250.40 1 3
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:255.2,255.28 1 3
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:241.16,244.3 2 0
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:246.56,249.3 2 0
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:250.40,253.3 2 0
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:259.51,262.2 2 2
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:265.59,266.41 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:272.2,272.18 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:266.41,267.25 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:270.3,270.20 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:267.25,269.4 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:278.61,282.16 4 3
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:288.2,288.12 1 2
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:282.16,283.26 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:286.3,286.31 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:283.26,285.4 1 1
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:292.45,294.16 2 4
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:297.2,297.29 1 4
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:294.16,296.3 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/os.go:301.64,303.2 1 0
-github.com/jesseduffield/lazydocker/pkg/commands/stash_entry.go:11.65,13.2 1 0
 mode: atomic
-github.com/jesseduffield/lazydocker/pkg/i18n/dutch.go:9.46,729.2 1 3
-github.com/jesseduffield/lazydocker/pkg/i18n/english.go:18.48,752.2 1 3
-github.com/jesseduffield/lazydocker/pkg/i18n/i18n.go:21.49,27.2 3 1
-github.com/jesseduffield/lazydocker/pkg/i18n/i18n.go:32.66,34.2 1 6
-github.com/jesseduffield/lazydocker/pkg/i18n/i18n.go:39.49,45.2 1 2
-github.com/jesseduffield/lazydocker/pkg/i18n/i18n.go:48.93,55.2 1 2
-github.com/jesseduffield/lazydocker/pkg/i18n/i18n.go:58.42,60.2 1 2
-github.com/jesseduffield/lazydocker/pkg/i18n/i18n.go:63.61,70.23 2 3
-github.com/jesseduffield/lazydocker/pkg/i18n/i18n.go:70.23,71.39 1 9
-github.com/jesseduffield/lazydocker/pkg/i18n/i18n.go:71.39,74.4 1 0
-github.com/jesseduffield/lazydocker/pkg/i18n/i18n.go:79.65,80.49 1 3
-github.com/jesseduffield/lazydocker/pkg/i18n/i18n.go:84.2,84.12 1 1
-github.com/jesseduffield/lazydocker/pkg/i18n/i18n.go:80.49,82.3 1 2
-github.com/jesseduffield/lazydocker/pkg/i18n/i18n.go:88.68,102.2 4 3
-github.com/jesseduffield/lazydocker/pkg/i18n/polish.go:8.47,712.2 1 3
-mode: atomic
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:38.230,47.2 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:50.70,54.16 4 3
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:57.2,57.22 1 3
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:68.2,72.45 3 3
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:84.2,84.22 1 3
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:91.2,92.16 2 3
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:96.2,97.16 2 2
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:101.2,101.33 1 2
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:109.2,109.21 1 2
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:54.16,56.3 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:57.22,60.17 2 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:63.3,63.31 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:60.17,62.4 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:63.31,65.4 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:72.45,83.3 5 4
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:84.22,89.3 4 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:92.16,94.3 1 1
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:97.16,99.3 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:101.33,102.39 1 2
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:102.39,103.31 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:103.31,105.5 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:113.95,114.20 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:115.16,116.38 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:117.21,118.43 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:119.10,120.18 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:124.84,127.16 3 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:133.2,134.93 2 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:158.2,158.16 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:162.2,162.21 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:127.16,130.3 2 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:134.93,135.25 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:139.3,139.17 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:142.3,143.32 2 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:146.3,147.17 2 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:150.3,152.17 3 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:155.3,156.13 2 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:135.25,138.4 2 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:139.17,141.4 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:143.32,145.4 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:147.17,149.4 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:152.17,154.4 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:158.16,160.3 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:177.89,179.16 2 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:185.2,187.29 3 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:200.2,200.17 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:179.16,183.3 2 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:187.29,188.35 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:191.3,197.18 2 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:188.35,190.4 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:208.87,217.2 4 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:219.109,221.16 2 3
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:224.2,224.20 1 2
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:227.2,228.33 2 1
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:239.2,239.21 1 1
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:221.16,223.3 1 1
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:224.20,226.3 1 1
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:228.33,229.46 1 2
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:232.3,232.32 1 2
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:235.3,235.21 1 1
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:229.46,231.4 1 1
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:232.32,233.12 1 1
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:235.21,237.4 1 1
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:242.113,243.33 1 2
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:250.2,250.21 1 2
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:243.33,244.60 1 2
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:244.60,245.44 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:245.44,247.5 1 0
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:253.60,255.16 2 7
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:259.2,260.50 2 5
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:264.2,265.16 2 5
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:268.2,268.20 1 5
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:255.16,257.3 1 2
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:260.50,262.3 1 1
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:265.17,267.3 0 2
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:273.66,276.16 3 5
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:279.2,279.40 1 4
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:283.2,283.18 1 4
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:276.16,278.3 1 1
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:279.40,281.3 1 4
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:288.45,292.16 2 5
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:297.2,297.15 1 4
-github.com/jesseduffield/lazydocker/pkg/git/commit_list_builder.go:292.16,295.3 1 1
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:21.66,25.2 1 0
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:29.109,36.29 6 0
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:42.2,43.16 2 0
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:47.2,50.20 3 0
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:36.29,38.3 1 0
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:38.8,40.3 1 0
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:43.16,45.3 1 0
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:53.75,54.38 1 5
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:59.2,59.55 1 0
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:54.38,55.36 1 26
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:55.36,57.4 1 5
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:64.90,67.16 3 5
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:70.2,73.16 3 5
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:77.2,78.16 2 5
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:82.2,84.20 2 5
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:67.16,69.3 1 0
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:73.16,75.3 1 0
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:78.16,80.3 1 0
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:89.88,92.38 2 5
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:101.2,101.54 1 0
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:92.38,93.36 1 102
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:96.3,96.26 1 102
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:93.36,95.4 1 6
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:96.26,98.4 1 5
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:104.111,108.58 3 5
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:130.2,132.16 3 5
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:136.2,136.21 1 5
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:108.58,110.36 2 77
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:114.3,114.26 1 76
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:127.3,127.34 1 43
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:110.36,112.9 2 1
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:114.26,116.36 1 71
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:122.4,122.36 1 59
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:116.36,119.13 3 12
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:122.36,124.13 2 21
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:132.16,134.3 1 0
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:145.94,151.16 4 5
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:154.2,156.65 3 5
-github.com/jesseduffield/lazydocker/pkg/git/patch_modifier.go:151.16,153.3 1 0
-github.com/jesseduffield/lazydocker/pkg/git/patch_parser.go:14.62,18.2 1 0
-github.com/jesseduffield/lazydocker/pkg/git/patch_parser.go:20.70,25.33 5 3
-github.com/jesseduffield/lazydocker/pkg/git/patch_parser.go:34.2,35.40 2 3
-github.com/jesseduffield/lazydocker/pkg/git/patch_parser.go:25.33,26.36 1 82
-github.com/jesseduffield/lazydocker/pkg/git/patch_parser.go:30.3,30.83 1 82
-github.com/jesseduffield/lazydocker/pkg/git/patch_parser.go:26.36,29.4 2 4
-github.com/jesseduffield/lazydocker/pkg/git/patch_parser.go:30.83,32.4 1 34
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:33.107,38.2 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:40.68,42.16 2 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:46.2,46.62 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:42.16,43.21 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:49.71,52.16 3 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:56.2,57.35 2 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:63.2,63.31 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:52.16,54.3 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:57.35,62.3 4 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:66.69,70.16 3 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:73.2,73.56 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:79.2,79.17 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:70.16,71.13 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:73.56,77.3 3 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:82.146,83.40 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:88.2,88.22 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:83.40,84.67 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:84.67,86.4 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:91.97,92.42 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:97.2,97.26 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:92.42,93.77 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:93.77,95.4 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:101.56,107.46 5 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:111.2,114.57 3 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:118.2,120.17 2 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:107.46,109.3 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:114.57,116.3 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:123.74,124.42 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:129.2,129.14 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:124.42,125.74 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:125.74,127.4 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:132.67,134.34 2 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:140.2,140.22 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:134.34,135.49 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:138.3,138.48 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:135.49,136.12 1 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:145.63,150.2 4 0
-github.com/jesseduffield/lazydocker/pkg/git/branch_list_builder.go:152.50,165.2 4 0
diff --git a/pkg/app/app.go b/pkg/app/app.go
index 57015918..5edc6488 100644
--- a/pkg/app/app.go
+++ b/pkg/app/app.go
@@ -56,17 +56,6 @@ func (app *App) Run() error {
 	return err
 }
 
-// Close closes any resources
-func (app *App) Close() error {
-	for _, closer := range app.closers {
-		err := closer.Close()
-		if err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
 type errorMapping struct {
 	originalError string
 	newError      string
diff --git a/pkg/commands/exec_live_default.go b/pkg/commands/exec_live_default.go
deleted file mode 100644
index 34608bd1..00000000
--- a/pkg/commands/exec_live_default.go
+++ /dev/null
@@ -1,100 +0,0 @@
-// +build !windows
-
-package commands
-
-import (
-	"bufio"
-	"bytes"
-	"os"
-	"strings"
-	"unicode/utf8"
-
-	"github.com/go-errors/errors"
-
-	"github.com/jesseduffield/pty"
-	"github.com/mgutz/str"
-)
-
-// RunCommandWithOutputLiveWrapper runs a command and return every word that gets written in stdout
-// Output is a function that executes by every word that gets read by bufio
-// As return of output you need to give a string that will be written to stdin
-// NOTE: If the return data is empty it won't written anything to stdin
-func RunCommandWithOutputLiveWrapper(c *OSCommand, command string, output func(string) string) error {
-	splitCmd := str.ToArgv(command)
-	cmd := c.command(splitCmd[0], splitCmd[1:]...)
-
-	cmd.Env = os.Environ()
-	cmd.Env = append(cmd.Env, "LANG=en_US.UTF-8", "LC_ALL=en_US.UTF-8")
-
-	var stderr bytes.Buffer
-	cmd.Stderr = &stderr
-
-	ptmx, err := pty.Start(cmd)
-
-	if err != nil {
-		return err
-	}
-
-	go func() {
-		scanner := bufio.NewScanner(ptmx)
-		scanner.Split(scanWordsWithNewLines)
-		for scanner.Scan() {
-			toOutput := strings.Trim(scanner.Text(), " ")
-			_, _ = ptmx.WriteString(output(toOutput))
-		}
-	}()
-
-	err = cmd.Wait()
-	ptmx.Close()
-	if err != nil {
-		return errors.New(stderr.String())
-	}
-
-	return nil
-}
-
-// scanWordsWithNewLines is a copy of bufio.ScanWords but this also captures new lines
-// For specific comments about this function take a look at: bufio.ScanWords
-func scanWordsWithNewLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
-	start := 0
-	for width := 0; start < len(data); start += width {
-		var r rune
-		r, width = utf8.DecodeRune(data[start:])
-		if !isSpace(r) {
-			break
-		}
-	}
-	for width, i := 0, start; i < len(data); i += width {
-		var r rune
-		r, width = utf8.DecodeRune(data[i:])
-		if isSpace(r) {
-			return i + width, data[start:i], nil
-		}
-	}
-	if atEOF && len(data) > start {
-		return len(data), data[start:], nil
-	}
-	return start, nil, nil
-}
-
-// isSpace is also copied from the bufio package and has been modified to also captures new lines
-// For specific comments about this function take a look at: bufio.isSpace
-func isSpace(r rune) bool {
-	if r <= '\u00FF' {
-		switch r {
-		case ' ', '\t', '\v', '\f':
-			return true
-		case '\u0085', '\u00A0':
-			return true
-		}
-		return false
-	}
-	if '\u2000' <= r && r <= '\u200a' {
-		return true
-	}
-	switch r {
-	case '\u1680', '\u2028', '\u2029', '\u202f', '\u205f', '\u3000':
-		return true
-	}
-	return false
-}
diff --git a/pkg/commands/exec_live_win.go b/pkg/commands/exec_live_win.go
deleted file mode 100644
index d06cb920..00000000
--- a/pkg/commands/exec_live_win.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// +build windows
-
-package commands
-
-// RunCommandWithOutputLiveWrapper runs a command live but because of windows compatibility this command can't be ran there
-// TODO: Remove this hack and replace it with a proper way to run commands live on windows
-func RunCommandWithOutputLiveWrapper(c *OSCommand, command string, output func(string) string) error {
-	return c.RunCommand(command)
-}
diff --git a/pkg/commands/os.go b/pkg/commands/os.go
index 3c420fdd..9ce2d363 100644
--- a/pkg/commands/os.go
+++ b/pkg/commands/os.go
@@ -6,7 +6,6 @@ import (
 	"os"
 	"os/exec"
 	"path/filepath"
-	"regexp"
 	"strings"
 	"sync"
 	"syscall"
@@ -87,36 +86,6 @@ func (c *OSCommand) ExecutableFromString(commandStr string) *exec.Cmd {
 	return c.command(splitCmd[0], splitCmd[1:]...)
 }
 
-// RunCommandWithOutputLive runs RunCommandWithOutputLiveWrapper
-func (c *OSCommand) RunCommandWithOutputLive(command string, output func(string) string) error {
-	return RunCommandWithOutputLiveWrapper(c, command, output)
-}
-
-// DetectUnamePass detect a username / password question in a command
-// ask is a function that gets executen when this function detect you need to fillin a password
-// The ask argument will be "username" or "password" and expects the user's password or username back
-func (c *OSCommand) DetectUnamePass(command string, ask func(string) string) error {
-	ttyText := ""
-	errMessage := c.RunCommandWithOutputLive(command, func(word string) string {
-		ttyText = ttyText + " " + word
-
-		prompts := map[string]string{
-			"password": `Password\s*for\s*'.+':`,
-			"username": `Username\s*for\s*'.+':`,
-		}
-
-		for askFor, pattern := range prompts {
-			if match, _ := regexp.MatchString(pattern, ttyText); match {
-				ttyText = ""
-				return ask(askFor)
-			}
-		}
-
-		return ""
-	})
-	return errMessage
-}
-
 // RunCommand runs a command and just returns the error
 func (c *OSCommand) RunCommand(command string) error {
 	_, err := c.RunCommandWithOutput(command)
diff --git a/pkg/gui/confirmation_panel.go b/pkg/gui/confirmation_panel.go
index d5142508..fc3605d5 100644
--- a/pkg/gui/confirmation_panel.go
+++ b/pkg/gui/confirmation_panel.go
@@ -98,10 +98,6 @@ func (gui *Gui) onNewPopupPanel() {
 	}
 }
 
-func (gui *Gui) createLoaderPanel(g *gocui.Gui, currentView *gocui.View, prompt string) error {
-	return gui.createPopupPanel(g, currentView, "", prompt, true, nil, nil)
-}
-
 // it is very important that within this function we never include the original prompt in any error messages, because it may contain e.g. a user password
 func (gui *Gui) createConfirmationPanel(g *gocui.Gui, currentView *gocui.View, title, prompt string, handleConfirm, handleClose func(*gocui.Gui, *gocui.View) error) error {
 	return gui.createPopupPanel(g, currentView, title, prompt, false, handleConfirm, handleClose)
@@ -148,10 +144,6 @@ func (gui *Gui) setKeyBindings(g *gocui.Gui, handleConfirm, handleClose func(*go
 	return nil
 }
 
-func (gui *Gui) createMessagePanel(g *gocui.Gui, currentView *gocui.View, title, prompt string) error {
-	return gui.createPopupPanel(g, currentView, title, prompt, false, nil, nil)
-}
-
 // createSpecificErrorPanel allows you to create an error popup, specifying the
 //  view to be focused when the user closes the popup, and a boolean specifying
 // whether we will log the error. If the message may include a user password,
diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go
index c567a952..bb2c5a59 100644
--- a/pkg/gui/gui.go
+++ b/pkg/gui/gui.go
@@ -177,10 +177,6 @@ func NewGui(log *logrus.Entry, dockerCommand *commands.DockerCommand, oSCommand
 	return gui, nil
 }
 
-func (gui *Gui) handleRefresh(g *gocui.Gui, v *gocui.View) error {
-	return gui.refreshSidePanels(g)
-}
-
 func max(a, b int) int {
 	if a > b {
 		return a
diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go
index e3c51312..ba5d0441 100644
--- a/pkg/gui/view_helpers.go
+++ b/pkg/gui/view_helpers.go
@@ -144,11 +144,6 @@ func (gui *Gui) switchFocus(g *gocui.Gui, oldView, newView *gocui.View) error {
 	return gui.newLineFocused(newView)
 }
 
-func (gui *Gui) resetOrigin(v *gocui.View) error {
-	_ = v.SetCursor(0, 0)
-	return v.SetOrigin(0, 0)
-}
-
 // if the cursor down past the last item, move it to the last line
 func (gui *Gui) focusPoint(selectedX int, selectedY int, lineCount int, v *gocui.View) error {
 	if selectedY < 0 || selectedY > lineCount {
@@ -317,28 +312,6 @@ func (gui *Gui) changeSelectedLine(line *int, total int, up bool) {
 	}
 }
 
-func (gui *Gui) refreshSelectedLine(line *int, total int) {
-	if *line == -1 && total > 0 {
-		*line = 0
-	} else if total-1 < *line {
-		*line = total - 1
-	}
-}
-
-func (gui *Gui) renderListPanel(v *gocui.View, items interface{}) error {
-	gui.g.Update(func(g *gocui.Gui) error {
-		isFocused := gui.g.CurrentView().Name() == v.Name()
-		list, err := utils.RenderList(items, utils.IsFocused(isFocused))
-		if err != nil {
-			return gui.createErrorPanel(gui.g, err.Error())
-		}
-		v.Clear()
-		fmt.Fprint(v, list)
-		return nil
-	})
-	return nil
-}
-
 func (gui *Gui) renderPanelOptions() error {
 	currentView := gui.g.CurrentView()
 	switch currentView.Name() {
@@ -348,11 +321,6 @@ func (gui *Gui) renderPanelOptions() error {
 	return gui.renderGlobalOptions()
 }
 
-func (gui *Gui) handleFocusView(g *gocui.Gui, v *gocui.View) error {
-	_, err := gui.g.SetCurrentView(v.Name())
-	return err
-}
-
 func (gui *Gui) isPopupPanel(viewName string) bool {
 	return viewName == "confirmation" || viewName == "menu"
 }
diff --git a/pkg/test/utils.go b/pkg/test/utils.go
deleted file mode 100644
index e106a043..00000000
--- a/pkg/test/utils.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package test
-
-import (
-	"fmt"
-	"os/exec"
-	"strings"
-	"testing"
-
-	"github.com/mgutz/str"
-	"github.com/stretchr/testify/assert"
-)
-
-// CommandSwapper takes a command, verifies that it is what it's expected to be
-// and then returns a replacement command that will actually be called by the os
-type CommandSwapper struct {
-	Expect  string
-	Replace string
-}
-
-// SwapCommand verifies the command is what we expected, and swaps it out for a different command
-func (i *CommandSwapper) SwapCommand(t *testing.T, cmd string, args []string) *exec.Cmd {
-	splitCmd := str.ToArgv(i.Expect)
-	assert.EqualValues(t, splitCmd[0], cmd, fmt.Sprintf("received command: %s %s", cmd, strings.Join(args, " ")))
-	if len(splitCmd) > 1 {
-		assert.EqualValues(t, splitCmd[1:], args, fmt.Sprintf("received command: %s %s", cmd, strings.Join(args, " ")))
-	}
-
-	splitCmd = str.ToArgv(i.Replace)
-	return exec.Command(splitCmd[0], splitCmd[1:]...)
-}
-
-// CreateMockCommand creates a command function that will verify its receiving the right sequence of commands from lazydocker
-func CreateMockCommand(t *testing.T, swappers []*CommandSwapper) func(cmd string, args ...string) *exec.Cmd {
-	commandIndex := 0
-
-	return func(cmd string, args ...string) *exec.Cmd {
-		var command *exec.Cmd
-		if commandIndex > len(swappers)-1 {
-			assert.Fail(t, fmt.Sprintf("too many commands run. This command was (%s %s)", cmd, strings.Join(args, " ")))
-		}
-		command = swappers[commandIndex].SwapCommand(t, cmd, args)
-		commandIndex++
-		return command
-	}
-}
diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go
index f84bd1ea..264227aa 100644
--- a/pkg/utils/utils.go
+++ b/pkg/utils/utils.go
@@ -2,7 +2,6 @@ package utils
 
 import (
 	"bytes"
-	"encoding/json"
 	"fmt"
 	"html/template"
 	"math"
@@ -59,15 +58,6 @@ func ColoredStringDirect(str string, colour *color.Color) string {
 	return colour.SprintFunc()(fmt.Sprint(str))
 }
 
-// TrimTrailingNewline - Trims the trailing newline
-// TODO: replace with `chomp` after refactor
-func TrimTrailingNewline(str string) string {
-	if strings.HasSuffix(str, "\n") {
-		return str[:len(str)-1]
-	}
-	return str
-}
-
 // NormalizeLinefeeds - Removes all Windows and Mac style line feeds
 func NormalizeLinefeeds(str string) string {
 	str = strings.Replace(str, "\r\n", "\n", -1)
@@ -92,14 +82,6 @@ func ResolvePlaceholderString(str string, arguments map[string]string) string {
 	return str
 }
 
-// Min returns the minimum of two integers
-func Min(x, y int) int {
-	if x < y {
-		return x
-	}
-	return y
-}
-
 // Max returns the maximum of two integers
 func Max(x, y int) int {
 	if x > y {
@@ -240,42 +222,6 @@ func getDisplayStringArrays(displayables []Displayable, isFocused bool) [][]stri
 	return stringArrays
 }
 
-// IncludesString if the list contains the string
-func IncludesString(list []string, a string) bool {
-	for _, b := range list {
-		if b == a {
-			return true
-		}
-	}
-	return false
-}
-
-// NextIndex returns the index of the element that comes after the given number
-func NextIndex(numbers []int, currentNumber int) int {
-	for index, number := range numbers {
-		if number > currentNumber {
-			return index
-		}
-	}
-	return 0
-}
-
-// PrevIndex returns the index that comes before the given number, cycling if we reach the end
-func PrevIndex(numbers []int, currentNumber int) int {
-	end := len(numbers) - 1
-	for i := end; i >= 0; i -= 1 {
-		if numbers[i] < currentNumber {
-			return i
-		}
-	}
-	return end
-}
-
-func AsJson(i interface{}) string {
-	bytes, _ := json.MarshalIndent(i, "", "    ")
-	return string(bytes)
-}
-
 func FormatBinaryBytes(b int) string {
 	n := float64(b)
 	units := []string{"B", "kiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"}
diff --git a/pkg/utils/utils_test.go b/pkg/utils/utils_test.go
index 6b76a084..0b01ee42 100644
--- a/pkg/utils/utils_test.go
+++ b/pkg/utils/utils_test.go
@@ -62,29 +62,6 @@ func TestWithPadding(t *testing.T) {
 	}
 }
 
-// TestTrimTrailingNewline is a function.
-func TestTrimTrailingNewline(t *testing.T) {
-	type scenario struct {
-		str      string
-		expected string
-	}
-
-	scenarios := []scenario{
-		{
-			"hello world !\n",
-			"hello world !",
-		},
-		{
-			"hello world !",
-			"hello world !",
-		},
-	}
-
-	for _, s := range scenarios {
-		assert.EqualValues(t, s.expected, TrimTrailingNewline(s.str))
-	}
-}
-
 // TestNormalizeLinefeeds is a function.
 func TestNormalizeLinefeeds(t *testing.T) {
 	type scenario struct {
@@ -403,173 +380,3 @@ func TestGetPadWidths(t *testing.T) {
 		assert.EqualValues(t, s.expected, getPadWidths(s.stringArrays))
 	}
 }
-
-// TestMin is a function.
-func TestMin(t *testing.T) {
-	type scenario struct {
-		a        int
-		b        int
-		expected int
-	}
-
-	scenarios := []scenario{
-		{
-			1,
-			1,
-			1,
-		},
-		{
-			1,
-			2,
-			1,
-		},
-		{
-			2,
-			1,
-			1,
-		},
-	}
-
-	for _, s := range scenarios {
-		assert.EqualValues(t, s.expected, Min(s.a, s.b))
-	}
-}
-
-// TestIncludesString is a function.
-func TestIncludesString(t *testing.T) {
-	type scenario struct {
-		list     []string
-		element  string
-		expected bool
-	}
-
-	scenarios := []scenario{
-		{
-			[]string{"a", "b"},
-			"a",
-			true,
-		},
-		{
-			[]string{"a", "b"},
-			"c",
-			false,
-		},
-		{
-			[]string{"a", "b"},
-			"",
-			false,
-		},
-		{
-			[]string{""},
-			"",
-			true,
-		},
-	}
-
-	for _, s := range scenarios {
-		assert.EqualValues(t, s.expected, IncludesString(s.list, s.element))
-	}
-}
-
-func TestNextIndex(t *testing.T) {
-	type scenario struct {
-		testName string
-		list     []int
-		element  int
-		expected int
-	}
-
-	scenarios := []scenario{
-		{
-			// I'm not really fussed about how it behaves here
-			"no elements",
-			[]int{},
-			1,
-			0,
-		},
-		{
-			"one element",
-			[]int{1},
-			1,
-			0,
-		},
-		{
-			"two elements",
-			[]int{1, 2},
-			1,
-			1,
-		},
-		{
-			"two elements, giving second one",
-			[]int{1, 2},
-			2,
-			0,
-		},
-		{
-			"three elements, giving second one",
-			[]int{1, 2, 3},
-			2,
-			2,
-		},
-	}
-
-	for _, s := range scenarios {
-		t.Run(s.testName, func(t *testing.T) {
-			assert.EqualValues(t, s.expected, NextIndex(s.list, s.element))
-		})
-	}
-}
-
-func TestPrevIndex(t *testing.T) {
-	type scenario struct {
-		testName string
-		list     []int
-		element  int
-		expected int
-	}
-
-	scenarios := []scenario{
-		{
-			// I'm not really fussed about how it behaves here
-			"no elements",
-			[]int{},
-			1,
-			-1,
-		},
-		{
-			"one element",
-			[]int{1},
-			1,
-			0,
-		},
-		{
-			"two elements",
-			[]int{1, 2},
-			1,
-			1,
-		},
-		{
-			"three elements, giving second one",
-			[]int{1, 2, 3},
-			2,
-			0,
-		},
-	}
-
-	for _, s := range scenarios {
-		t.Run(s.testName, func(t *testing.T) {
-			assert.EqualValues(t, s.expected, PrevIndex(s.list, s.element))
-		})
-	}
-}
-
-func TestAsJson(t *testing.T) {
-	type myStruct struct {
-		a string
-	}
-
-	output := AsJson(&myStruct{a: "foo"})
-
-	// no idea why this is returning empty hashes but it's works in the app ¯\_(ツ)_/¯
-	assert.EqualValues(t, "{}", output)
-}

From be681bb8e03c821590bb79ccc08a88e12ca64c6b Mon Sep 17 00:00:00 2001
From: mjarkk 
Date: Mon, 1 Jul 2019 10:23:39 +0200
Subject: [PATCH 11/26] Updated git gitignore

---
 .gitignore | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/.gitignore b/.gitignore
index 0839d745..82995009 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
-
+lazydocker*
 TODO.md
-Lazydocker.code-workspace
\ No newline at end of file
+Lazydocker.code-workspace
+.vscode

From 9a41c773ea63ee750fa885f952bb6cf4b00bc5c7 Mon Sep 17 00:00:00 2001
From: Callum McIntyre 
Date: Mon, 1 Jul 2019 08:58:02 +0100
Subject: [PATCH 12/26] Migrate from flag to flaggy

- Prerequisite for supporting multiple -f flags
- Migrate the existing flag use to flaggy, no new flags introduced yet
- Add name/description/repo to flaggy help output
- Use flaggy for version flag
---
 main.go | 28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/main.go b/main.go
index 7dbadb95..1e80bd11 100644
--- a/main.go
+++ b/main.go
@@ -2,7 +2,6 @@ package main
 
 import (
 	"bytes"
-	"flag"
 	"fmt"
 	"log"
 	"os"
@@ -10,6 +9,7 @@ import (
 
 	"github.com/docker/docker/client"
 	"github.com/go-errors/errors"
+	"github.com/integrii/flaggy"
 	"github.com/jesseduffield/lazydocker/pkg/app"
 	"github.com/jesseduffield/lazydocker/pkg/config"
 	"github.com/jesseduffield/yaml"
@@ -21,19 +21,23 @@ var (
 	date        string
 	buildSource = "unknown"
 
-	configFlag    = flag.Bool("config", false, "Print the current default config")
-	debuggingFlag = flag.Bool("debug", false, "a boolean")
-	versionFlag   = flag.Bool("v", false, "Print the current version")
+	configFlag    = false
+	debuggingFlag = false
 )
 
 func main() {
-	flag.Parse()
-	if *versionFlag {
-		fmt.Printf("commit=%s, build date=%s, build source=%s, version=%s, os=%s, arch=%s\n", commit, date, buildSource, version, runtime.GOOS, runtime.GOARCH)
-		os.Exit(0)
-	}
 
-	if *configFlag {
+	flaggy.SetName("lazydocker")
+	flaggy.SetDescription("The lazier way to manage everything docker")
+	flaggy.DefaultParser.AdditionalHelpPrepend = "https://github.com/jesseduffield/lazydocker"
+
+	flaggy.Bool(&configFlag, "c", "config", "Print the current default config")
+	flaggy.Bool(&debuggingFlag, "d", "debug", "a boolean")
+	flaggy.SetVersion(fmt.Sprintf("commit=%s, build date=%s, build source=%s, version=%s, os=%s, arch=%s\n", commit, date, buildSource, version, runtime.GOOS, runtime.GOARCH))
+
+	flaggy.Parse()
+
+	if configFlag {
 		var buf bytes.Buffer
 		yaml.NewEncoder(&buf).Encode(config.GetDefaultConfig())
 		fmt.Printf("%v\n", buf.String())
@@ -41,9 +45,9 @@ func main() {
 	}
 
 	// for now we're always in debug mode so we're not passing *debuggingFlag
-	*debuggingFlag = true
+	debuggingFlag = true
 
-	appConfig, err := config.NewAppConfig("lazydocker", version, commit, date, buildSource, *debuggingFlag)
+	appConfig, err := config.NewAppConfig("lazydocker", version, commit, date, buildSource, debuggingFlag)
 	if err != nil {
 		log.Fatal(err.Error())
 	}

From 73ec29849f1f86197204f57f8657ce1daf182d4d Mon Sep 17 00:00:00 2001
From: Jesse Duffield 
Date: Mon, 1 Jul 2019 20:02:47 +1000
Subject: [PATCH 13/26] fix format

---
 pkg/i18n/german.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pkg/i18n/german.go b/pkg/i18n/german.go
index 8b610cd5..eb9f605d 100644
--- a/pkg/i18n/german.go
+++ b/pkg/i18n/german.go
@@ -77,7 +77,7 @@ func germanSet() TranslationSet {
 		NoImages:     "Keine Images",
 		NoVolumes:    "Keine Volumen",
 
-		ConfirmQuit:                "Bist du dir sicher, dass du verlassen möchtest?", 
+		ConfirmQuit:                "Bist du dir sicher, dass du verlassen möchtest?",
 		MustForceToRemoveContainer: "Du kannst keinen Container entfernen, der noch ausgeführt wird außer du erzwingst es. Möchtest du es erzwingen?",
 		NotEnoughSpace:             "Nicht genug Platz um die Panele darzustellen",
 		ConfirmPruneImages:         "Bist du dir sicher, dass du alle unbenutzten Images entfernen möchtest?",

From ec7624c3a3824823c0cbbba323de6036863eee24 Mon Sep 17 00:00:00 2001
From: Jesse Duffield 
Date: Mon, 1 Jul 2019 21:17:55 +1000
Subject: [PATCH 14/26] fix menu overlap bug

---
 pkg/gui/main_panel.go | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/pkg/gui/main_panel.go b/pkg/gui/main_panel.go
index 5dc15763..38127d25 100644
--- a/pkg/gui/main_panel.go
+++ b/pkg/gui/main_panel.go
@@ -91,6 +91,10 @@ func (gui *Gui) handleExitMain(g *gocui.Gui, v *gocui.View) error {
 }
 
 func (gui *Gui) handleMainClick(g *gocui.Gui, v *gocui.View) error {
+	if gui.popupPanelFocused() {
+		return nil
+	}
+
 	currentView := gui.g.CurrentView()
 
 	v.ParentView = currentView

From 16b700c945df980f8ff3186449b0392813807bf0 Mon Sep 17 00:00:00 2001
From: Jesse Duffield 
Date: Mon, 1 Jul 2019 21:28:46 +1000
Subject: [PATCH 15/26] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 57b35619..0182b011 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
   
 

-A simple terminal UI for docker and docker-compose, written in Go with the [gocui](https://github.com/jroimartin/gocui 'gocui') library. +A simple terminal UI for both docker and docker-compose, written in Go with the [gocui](https://github.com/jroimartin/gocui 'gocui') library. [![CircleCI](https://circleci.com/gh/jesseduffield/lazydocker.svg?style=svg)](https://circleci.com/gh/jesseduffield/lazydocker) [![Go Report Card](https://goreportcard.com/badge/github.com/jesseduffield/lazydocker)](https://goreportcard.com/report/github.com/jesseduffield/lazydocker) [![GolangCI](https://golangci.com/badges/github.com/jesseduffield/lazydocker.svg)](https://golangci.com) [![GoDoc](https://godoc.org/github.com/jesseduffield/lazydocker?status.svg)](http://godoc.org/github.com/jesseduffield/lazydocker) [![GitHub tag](https://img.shields.io/github/tag/jesseduffield/lazydocker.svg)]() From fdb4ad124e69958079430ca02a0f8c9e90f6466b Mon Sep 17 00:00:00 2001 From: Callum McIntyre Date: Mon, 1 Jul 2019 13:10:30 +0100 Subject: [PATCH 16/26] Remove hardcoded debug=true flag --- main.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/main.go b/main.go index 1e80bd11..be1e3dd7 100644 --- a/main.go +++ b/main.go @@ -44,9 +44,6 @@ func main() { os.Exit(0) } - // for now we're always in debug mode so we're not passing *debuggingFlag - debuggingFlag = true - appConfig, err := config.NewAppConfig("lazydocker", version, commit, date, buildSource, debuggingFlag) if err != nil { log.Fatal(err.Error()) From d72808f4fc7d2513be13c30a0e3c4b4b8c9cf463 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Mon, 1 Jul 2019 22:53:38 +1000 Subject: [PATCH 17/26] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 32 ++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..20d28336 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,32 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: bug +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behaviour** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. Windows] + - Lazydocker Version [e.g. v0.1.45] + - The last commit id if you built project from sources (run : ```git-rev parse HEAD```) + +**Additional context** +Add any other context about the problem here. From 3784c3e54e66b5d06fdde217f9cf1dce4580aea2 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Mon, 1 Jul 2019 22:54:24 +1000 Subject: [PATCH 18/26] Update issue templates --- .github/ISSUE_TEMPLATE/feature_request.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..11fc491e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: enhancement +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. From 750437d5720171f44a0b457a8f2c559536e23440 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Mon, 1 Jul 2019 23:01:26 +1000 Subject: [PATCH 19/26] bump jesseduffield/rollrus --- Gopkg.lock | 11 +-- vendor/github.com/jesseduffield/pty/License | 23 ------ vendor/github.com/jesseduffield/pty/doc.go | 16 ---- vendor/github.com/jesseduffield/pty/ioctl.go | 13 --- .../github.com/jesseduffield/pty/ioctl_bsd.go | 39 --------- .../jesseduffield/pty/pty_darwin.go | 65 --------------- .../jesseduffield/pty/pty_dragonfly.go | 80 ------------------- .../jesseduffield/pty/pty_freebsd.go | 78 ------------------ .../github.com/jesseduffield/pty/pty_linux.go | 51 ------------ .../jesseduffield/pty/pty_openbsd.go | 33 -------- .../jesseduffield/pty/pty_unsupported.go | 11 --- vendor/github.com/jesseduffield/pty/run.go | 54 ------------- vendor/github.com/jesseduffield/pty/types.go | 10 --- .../jesseduffield/pty/types_dragonfly.go | 17 ---- .../jesseduffield/pty/types_freebsd.go | 15 ---- .../jesseduffield/pty/types_openbsd.go | 14 ---- vendor/github.com/jesseduffield/pty/util.go | 64 --------------- .../jesseduffield/pty/ztypes_386.go | 9 --- .../jesseduffield/pty/ztypes_amd64.go | 9 --- .../jesseduffield/pty/ztypes_arm.go | 9 --- .../jesseduffield/pty/ztypes_arm64.go | 11 --- .../pty/ztypes_dragonfly_amd64.go | 14 ---- .../jesseduffield/pty/ztypes_freebsd_386.go | 13 --- .../jesseduffield/pty/ztypes_freebsd_amd64.go | 14 ---- .../jesseduffield/pty/ztypes_freebsd_arm.go | 13 --- .../jesseduffield/pty/ztypes_mipsx.go | 12 --- .../jesseduffield/pty/ztypes_openbsd_386.go | 13 --- .../jesseduffield/pty/ztypes_openbsd_amd64.go | 13 --- .../jesseduffield/pty/ztypes_ppc64.go | 11 --- .../jesseduffield/pty/ztypes_ppc64le.go | 11 --- .../jesseduffield/pty/ztypes_s390x.go | 11 --- 31 files changed, 1 insertion(+), 756 deletions(-) delete mode 100644 vendor/github.com/jesseduffield/pty/License delete mode 100644 vendor/github.com/jesseduffield/pty/doc.go delete mode 100644 vendor/github.com/jesseduffield/pty/ioctl.go delete mode 100644 vendor/github.com/jesseduffield/pty/ioctl_bsd.go delete mode 100644 vendor/github.com/jesseduffield/pty/pty_darwin.go delete mode 100644 vendor/github.com/jesseduffield/pty/pty_dragonfly.go delete mode 100644 vendor/github.com/jesseduffield/pty/pty_freebsd.go delete mode 100644 vendor/github.com/jesseduffield/pty/pty_linux.go delete mode 100644 vendor/github.com/jesseduffield/pty/pty_openbsd.go delete mode 100644 vendor/github.com/jesseduffield/pty/pty_unsupported.go delete mode 100644 vendor/github.com/jesseduffield/pty/run.go delete mode 100644 vendor/github.com/jesseduffield/pty/types.go delete mode 100644 vendor/github.com/jesseduffield/pty/types_dragonfly.go delete mode 100644 vendor/github.com/jesseduffield/pty/types_freebsd.go delete mode 100644 vendor/github.com/jesseduffield/pty/types_openbsd.go delete mode 100644 vendor/github.com/jesseduffield/pty/util.go delete mode 100644 vendor/github.com/jesseduffield/pty/ztypes_386.go delete mode 100644 vendor/github.com/jesseduffield/pty/ztypes_amd64.go delete mode 100644 vendor/github.com/jesseduffield/pty/ztypes_arm.go delete mode 100644 vendor/github.com/jesseduffield/pty/ztypes_arm64.go delete mode 100644 vendor/github.com/jesseduffield/pty/ztypes_dragonfly_amd64.go delete mode 100644 vendor/github.com/jesseduffield/pty/ztypes_freebsd_386.go delete mode 100644 vendor/github.com/jesseduffield/pty/ztypes_freebsd_amd64.go delete mode 100644 vendor/github.com/jesseduffield/pty/ztypes_freebsd_arm.go delete mode 100644 vendor/github.com/jesseduffield/pty/ztypes_mipsx.go delete mode 100644 vendor/github.com/jesseduffield/pty/ztypes_openbsd_386.go delete mode 100644 vendor/github.com/jesseduffield/pty/ztypes_openbsd_amd64.go delete mode 100644 vendor/github.com/jesseduffield/pty/ztypes_ppc64.go delete mode 100644 vendor/github.com/jesseduffield/pty/ztypes_ppc64le.go delete mode 100644 vendor/github.com/jesseduffield/pty/ztypes_s390x.go diff --git a/Gopkg.lock b/Gopkg.lock index 5acb6e3d..e43444ec 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -129,14 +129,6 @@ pruneopts = "NUT" revision = "117e4fb79d29e3908cb7a7bed5e991a321fde7fd" -[[projects]] - branch = "master" - digest = "1:a46c2f4863e5284ddb255c28750298e04bc8c0fc896bed6056e947673168b7be" - name = "github.com/jesseduffield/pty" - packages = ["."] - pruneopts = "NUT" - revision = "02db52c7e406c7abec44c717a173c7715e4c1b62" - [[projects]] branch = "master" digest = "1:7429d1589cc1454e9e97ba48cb7c5025a085b32eae4d3163c517e3e5d6c7a7a0" @@ -151,7 +143,7 @@ name = "github.com/jesseduffield/rollrus" packages = ["."] pruneopts = "NUT" - revision = "7086c0b1b1bd21ef1f502e914ff2505a68c7d638" + revision = "dd028cb0bfd75da456151b389d1a32b68cc57360" [[projects]] branch = "master" @@ -329,7 +321,6 @@ "github.com/imdario/mergo", "github.com/jesseduffield/asciigraph", "github.com/jesseduffield/gocui", - "github.com/jesseduffield/pty", "github.com/jesseduffield/rollrus", "github.com/jesseduffield/yaml", "github.com/mcuadros/go-lookup", diff --git a/vendor/github.com/jesseduffield/pty/License b/vendor/github.com/jesseduffield/pty/License deleted file mode 100644 index 6b7558b6..00000000 --- a/vendor/github.com/jesseduffield/pty/License +++ /dev/null @@ -1,23 +0,0 @@ -Copyright (c) 2011 Keith Rarick - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall -be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/jesseduffield/pty/doc.go b/vendor/github.com/jesseduffield/pty/doc.go deleted file mode 100644 index 190cfbea..00000000 --- a/vendor/github.com/jesseduffield/pty/doc.go +++ /dev/null @@ -1,16 +0,0 @@ -// Package pty provides functions for working with Unix terminals. -package pty - -import ( - "errors" - "os" -) - -// ErrUnsupported is returned if a function is not -// available on the current platform. -var ErrUnsupported = errors.New("unsupported") - -// Opens a pty and its corresponding tty. -func Open() (pty, tty *os.File, err error) { - return open() -} diff --git a/vendor/github.com/jesseduffield/pty/ioctl.go b/vendor/github.com/jesseduffield/pty/ioctl.go deleted file mode 100644 index c57c19e7..00000000 --- a/vendor/github.com/jesseduffield/pty/ioctl.go +++ /dev/null @@ -1,13 +0,0 @@ -// +build !windows - -package pty - -import "syscall" - -func ioctl(fd, cmd, ptr uintptr) error { - _, _, e := syscall.Syscall(syscall.SYS_IOCTL, fd, cmd, ptr) - if e != 0 { - return e - } - return nil -} diff --git a/vendor/github.com/jesseduffield/pty/ioctl_bsd.go b/vendor/github.com/jesseduffield/pty/ioctl_bsd.go deleted file mode 100644 index 73b12c53..00000000 --- a/vendor/github.com/jesseduffield/pty/ioctl_bsd.go +++ /dev/null @@ -1,39 +0,0 @@ -// +build darwin dragonfly freebsd netbsd openbsd - -package pty - -// from -const ( - _IOC_VOID uintptr = 0x20000000 - _IOC_OUT uintptr = 0x40000000 - _IOC_IN uintptr = 0x80000000 - _IOC_IN_OUT uintptr = _IOC_OUT | _IOC_IN - _IOC_DIRMASK = _IOC_VOID | _IOC_OUT | _IOC_IN - - _IOC_PARAM_SHIFT = 13 - _IOC_PARAM_MASK = (1 << _IOC_PARAM_SHIFT) - 1 -) - -func _IOC_PARM_LEN(ioctl uintptr) uintptr { - return (ioctl >> 16) & _IOC_PARAM_MASK -} - -func _IOC(inout uintptr, group byte, ioctl_num uintptr, param_len uintptr) uintptr { - return inout | (param_len&_IOC_PARAM_MASK)<<16 | uintptr(group)<<8 | ioctl_num -} - -func _IO(group byte, ioctl_num uintptr) uintptr { - return _IOC(_IOC_VOID, group, ioctl_num, 0) -} - -func _IOR(group byte, ioctl_num uintptr, param_len uintptr) uintptr { - return _IOC(_IOC_OUT, group, ioctl_num, param_len) -} - -func _IOW(group byte, ioctl_num uintptr, param_len uintptr) uintptr { - return _IOC(_IOC_IN, group, ioctl_num, param_len) -} - -func _IOWR(group byte, ioctl_num uintptr, param_len uintptr) uintptr { - return _IOC(_IOC_IN_OUT, group, ioctl_num, param_len) -} diff --git a/vendor/github.com/jesseduffield/pty/pty_darwin.go b/vendor/github.com/jesseduffield/pty/pty_darwin.go deleted file mode 100644 index 6344b6b0..00000000 --- a/vendor/github.com/jesseduffield/pty/pty_darwin.go +++ /dev/null @@ -1,65 +0,0 @@ -package pty - -import ( - "errors" - "os" - "syscall" - "unsafe" -) - -func open() (pty, tty *os.File, err error) { - pFD, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|syscall.O_CLOEXEC, 0) - if err != nil { - return nil, nil, err - } - p := os.NewFile(uintptr(pFD), "/dev/ptmx") - // In case of error after this point, make sure we close the ptmx fd. - defer func() { - if err != nil { - _ = p.Close() // Best effort. - } - }() - - sname, err := ptsname(p) - if err != nil { - return nil, nil, err - } - - if err := grantpt(p); err != nil { - return nil, nil, err - } - - if err := unlockpt(p); err != nil { - return nil, nil, err - } - - t, err := os.OpenFile(sname, os.O_RDWR, 0) - if err != nil { - return nil, nil, err - } - return p, t, nil -} - -func ptsname(f *os.File) (string, error) { - n := make([]byte, _IOC_PARM_LEN(syscall.TIOCPTYGNAME)) - - err := ioctl(f.Fd(), syscall.TIOCPTYGNAME, uintptr(unsafe.Pointer(&n[0]))) - if err != nil { - return "", err - } - - for i, c := range n { - if c == 0 { - return string(n[:i]), nil - } - } - return "", errors.New("TIOCPTYGNAME string not NUL-terminated") -} - -func grantpt(f *os.File) error { - return ioctl(f.Fd(), syscall.TIOCPTYGRANT, 0) -} - -func unlockpt(f *os.File) error { - return ioctl(f.Fd(), syscall.TIOCPTYUNLK, 0) -} diff --git a/vendor/github.com/jesseduffield/pty/pty_dragonfly.go b/vendor/github.com/jesseduffield/pty/pty_dragonfly.go deleted file mode 100644 index b7d1f20f..00000000 --- a/vendor/github.com/jesseduffield/pty/pty_dragonfly.go +++ /dev/null @@ -1,80 +0,0 @@ -package pty - -import ( - "errors" - "os" - "strings" - "syscall" - "unsafe" -) - -// same code as pty_darwin.go -func open() (pty, tty *os.File, err error) { - p, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0) - if err != nil { - return nil, nil, err - } - // In case of error after this point, make sure we close the ptmx fd. - defer func() { - if err != nil { - _ = p.Close() // Best effort. - } - }() - - sname, err := ptsname(p) - if err != nil { - return nil, nil, err - } - - if err := grantpt(p); err != nil { - return nil, nil, err - } - - if err := unlockpt(p); err != nil { - return nil, nil, err - } - - t, err := os.OpenFile(sname, os.O_RDWR, 0) - if err != nil { - return nil, nil, err - } - return p, t, nil -} - -func grantpt(f *os.File) error { - _, err := isptmaster(f.Fd()) - return err -} - -func unlockpt(f *os.File) error { - _, err := isptmaster(f.Fd()) - return err -} - -func isptmaster(fd uintptr) (bool, error) { - err := ioctl(fd, syscall.TIOCISPTMASTER, 0) - return err == nil, err -} - -var ( - emptyFiodgnameArg fiodgnameArg - ioctl_FIODNAME = _IOW('f', 120, unsafe.Sizeof(emptyFiodgnameArg)) -) - -func ptsname(f *os.File) (string, error) { - name := make([]byte, _C_SPECNAMELEN) - fa := fiodgnameArg{Name: (*byte)(unsafe.Pointer(&name[0])), Len: _C_SPECNAMELEN, Pad_cgo_0: [4]byte{0, 0, 0, 0}} - - err := ioctl(f.Fd(), ioctl_FIODNAME, uintptr(unsafe.Pointer(&fa))) - if err != nil { - return "", err - } - - for i, c := range name { - if c == 0 { - s := "/dev/" + string(name[:i]) - return strings.Replace(s, "ptm", "pts", -1), nil - } - } - return "", errors.New("TIOCPTYGNAME string not NUL-terminated") -} diff --git a/vendor/github.com/jesseduffield/pty/pty_freebsd.go b/vendor/github.com/jesseduffield/pty/pty_freebsd.go deleted file mode 100644 index 63b6d913..00000000 --- a/vendor/github.com/jesseduffield/pty/pty_freebsd.go +++ /dev/null @@ -1,78 +0,0 @@ -package pty - -import ( - "errors" - "os" - "syscall" - "unsafe" -) - -func posixOpenpt(oflag int) (fd int, err error) { - r0, _, e1 := syscall.Syscall(syscall.SYS_POSIX_OPENPT, uintptr(oflag), 0, 0) - fd = int(r0) - if e1 != 0 { - err = e1 - } - return fd, err -} - -func open() (pty, tty *os.File, err error) { - fd, err := posixOpenpt(syscall.O_RDWR | syscall.O_CLOEXEC) - if err != nil { - return nil, nil, err - } - p := os.NewFile(uintptr(fd), "/dev/pts") - // In case of error after this point, make sure we close the pts fd. - defer func() { - if err != nil { - _ = p.Close() // Best effort. - } - }() - - sname, err := ptsname(p) - if err != nil { - return nil, nil, err - } - - t, err := os.OpenFile("/dev/"+sname, os.O_RDWR, 0) - if err != nil { - return nil, nil, err - } - return p, t, nil -} - -func isptmaster(fd uintptr) (bool, error) { - err := ioctl(fd, syscall.TIOCPTMASTER, 0) - return err == nil, err -} - -var ( - emptyFiodgnameArg fiodgnameArg - ioctlFIODGNAME = _IOW('f', 120, unsafe.Sizeof(emptyFiodgnameArg)) -) - -func ptsname(f *os.File) (string, error) { - master, err := isptmaster(f.Fd()) - if err != nil { - return "", err - } - if !master { - return "", syscall.EINVAL - } - - const n = _C_SPECNAMELEN + 1 - var ( - buf = make([]byte, n) - arg = fiodgnameArg{Len: n, Buf: (*byte)(unsafe.Pointer(&buf[0]))} - ) - if err := ioctl(f.Fd(), ioctlFIODGNAME, uintptr(unsafe.Pointer(&arg))); err != nil { - return "", err - } - - for i, c := range buf { - if c == 0 { - return string(buf[:i]), nil - } - } - return "", errors.New("FIODGNAME string not NUL-terminated") -} diff --git a/vendor/github.com/jesseduffield/pty/pty_linux.go b/vendor/github.com/jesseduffield/pty/pty_linux.go deleted file mode 100644 index 296dd212..00000000 --- a/vendor/github.com/jesseduffield/pty/pty_linux.go +++ /dev/null @@ -1,51 +0,0 @@ -package pty - -import ( - "os" - "strconv" - "syscall" - "unsafe" -) - -func open() (pty, tty *os.File, err error) { - p, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0) - if err != nil { - return nil, nil, err - } - // In case of error after this point, make sure we close the ptmx fd. - defer func() { - if err != nil { - _ = p.Close() // Best effort. - } - }() - - sname, err := ptsname(p) - if err != nil { - return nil, nil, err - } - - if err := unlockpt(p); err != nil { - return nil, nil, err - } - - t, err := os.OpenFile(sname, os.O_RDWR|syscall.O_NOCTTY, 0) - if err != nil { - return nil, nil, err - } - return p, t, nil -} - -func ptsname(f *os.File) (string, error) { - var n _C_uint - err := ioctl(f.Fd(), syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n))) - if err != nil { - return "", err - } - return "/dev/pts/" + strconv.Itoa(int(n)), nil -} - -func unlockpt(f *os.File) error { - var u _C_int - // use TIOCSPTLCK with a zero valued arg to clear the slave pty lock - return ioctl(f.Fd(), syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&u))) -} diff --git a/vendor/github.com/jesseduffield/pty/pty_openbsd.go b/vendor/github.com/jesseduffield/pty/pty_openbsd.go deleted file mode 100644 index 6e7aeae7..00000000 --- a/vendor/github.com/jesseduffield/pty/pty_openbsd.go +++ /dev/null @@ -1,33 +0,0 @@ -package pty - -import ( - "os" - "syscall" - "unsafe" -) - -func open() (pty, tty *os.File, err error) { - /* - * from ptm(4): - * The PTMGET command allocates a free pseudo terminal, changes its - * ownership to the caller, revokes the access privileges for all previous - * users, opens the file descriptors for the master and slave devices and - * returns them to the caller in struct ptmget. - */ - - p, err := os.OpenFile("/dev/ptm", os.O_RDWR|syscall.O_CLOEXEC, 0) - if err != nil { - return nil, nil, err - } - defer p.Close() - - var ptm ptmget - if err := ioctl(p.Fd(), uintptr(ioctl_PTMGET), uintptr(unsafe.Pointer(&ptm))); err != nil { - return nil, nil, err - } - - pty = os.NewFile(uintptr(ptm.Cfd), "/dev/ptm") - tty = os.NewFile(uintptr(ptm.Sfd), "/dev/ptm") - - return pty, tty, nil -} diff --git a/vendor/github.com/jesseduffield/pty/pty_unsupported.go b/vendor/github.com/jesseduffield/pty/pty_unsupported.go deleted file mode 100644 index 9a3e721b..00000000 --- a/vendor/github.com/jesseduffield/pty/pty_unsupported.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build !linux,!darwin,!freebsd,!dragonfly,!openbsd - -package pty - -import ( - "os" -) - -func open() (pty, tty *os.File, err error) { - return nil, nil, ErrUnsupported -} diff --git a/vendor/github.com/jesseduffield/pty/run.go b/vendor/github.com/jesseduffield/pty/run.go deleted file mode 100644 index dda19b76..00000000 --- a/vendor/github.com/jesseduffield/pty/run.go +++ /dev/null @@ -1,54 +0,0 @@ -// +build !windows - -package pty - -import ( - "os" - "os/exec" - "syscall" -) - -// Start assigns a pseudo-terminal tty os.File to c.Stdin, c.Stdout, -// and c.Stderr, calls c.Start, and returns the File of the tty's -// corresponding pty. -func Start(c *exec.Cmd) (pty *os.File, err error) { - return StartWithSize(c, nil) -} - -// StartWithSize assigns a pseudo-terminal tty os.File to c.Stdin, c.Stdout, -// and c.Stderr, calls c.Start, and returns the File of the tty's -// corresponding pty. -// -// This will resize the pty to the specified size before starting the command -func StartWithSize(c *exec.Cmd, sz *Winsize) (pty *os.File, err error) { - pty, tty, err := Open() - if err != nil { - return nil, err - } - defer tty.Close() - if sz != nil { - err = Setsize(pty, sz) - if err != nil { - pty.Close() - return nil, err - } - } - if c.Stdout == nil { - c.Stdout = tty - } - if c.Stderr == nil { - c.Stderr = tty - } - c.Stdin = tty - if c.SysProcAttr == nil { - c.SysProcAttr = &syscall.SysProcAttr{} - } - c.SysProcAttr.Setctty = true - c.SysProcAttr.Setsid = true - err = c.Start() - if err != nil { - pty.Close() - return nil, err - } - return pty, err -} diff --git a/vendor/github.com/jesseduffield/pty/types.go b/vendor/github.com/jesseduffield/pty/types.go deleted file mode 100644 index 5aecb6bc..00000000 --- a/vendor/github.com/jesseduffield/pty/types.go +++ /dev/null @@ -1,10 +0,0 @@ -// +build ignore - -package pty - -import "C" - -type ( - _C_int C.int - _C_uint C.uint -) diff --git a/vendor/github.com/jesseduffield/pty/types_dragonfly.go b/vendor/github.com/jesseduffield/pty/types_dragonfly.go deleted file mode 100644 index 5c0493b8..00000000 --- a/vendor/github.com/jesseduffield/pty/types_dragonfly.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build ignore - -package pty - -/* -#define _KERNEL -#include -#include -#include -*/ -import "C" - -const ( - _C_SPECNAMELEN = C.SPECNAMELEN /* max length of devicename */ -) - -type fiodgnameArg C.struct_fiodname_args diff --git a/vendor/github.com/jesseduffield/pty/types_freebsd.go b/vendor/github.com/jesseduffield/pty/types_freebsd.go deleted file mode 100644 index ce3eb951..00000000 --- a/vendor/github.com/jesseduffield/pty/types_freebsd.go +++ /dev/null @@ -1,15 +0,0 @@ -// +build ignore - -package pty - -/* -#include -#include -*/ -import "C" - -const ( - _C_SPECNAMELEN = C.SPECNAMELEN /* max length of devicename */ -) - -type fiodgnameArg C.struct_fiodgname_arg diff --git a/vendor/github.com/jesseduffield/pty/types_openbsd.go b/vendor/github.com/jesseduffield/pty/types_openbsd.go deleted file mode 100644 index 47701b5f..00000000 --- a/vendor/github.com/jesseduffield/pty/types_openbsd.go +++ /dev/null @@ -1,14 +0,0 @@ -// +build ignore - -package pty - -/* -#include -#include -#include -*/ -import "C" - -type ptmget C.struct_ptmget - -var ioctl_PTMGET = C.PTMGET diff --git a/vendor/github.com/jesseduffield/pty/util.go b/vendor/github.com/jesseduffield/pty/util.go deleted file mode 100644 index 68a8584c..00000000 --- a/vendor/github.com/jesseduffield/pty/util.go +++ /dev/null @@ -1,64 +0,0 @@ -// +build !windows - -package pty - -import ( - "os" - "syscall" - "unsafe" -) - -// InheritSize applies the terminal size of master to slave. This should be run -// in a signal handler for syscall.SIGWINCH to automatically resize the slave when -// the master receives a window size change notification. -func InheritSize(master, slave *os.File) error { - size, err := GetsizeFull(master) - if err != nil { - return err - } - err = Setsize(slave, size) - if err != nil { - return err - } - return nil -} - -// Setsize resizes t to s. -func Setsize(t *os.File, ws *Winsize) error { - return windowRectCall(ws, t.Fd(), syscall.TIOCSWINSZ) -} - -// GetsizeFull returns the full terminal size description. -func GetsizeFull(t *os.File) (size *Winsize, err error) { - var ws Winsize - err = windowRectCall(&ws, t.Fd(), syscall.TIOCGWINSZ) - return &ws, err -} - -// Getsize returns the number of rows (lines) and cols (positions -// in each line) in terminal t. -func Getsize(t *os.File) (rows, cols int, err error) { - ws, err := GetsizeFull(t) - return int(ws.Rows), int(ws.Cols), err -} - -// Winsize describes the terminal size. -type Winsize struct { - Rows uint16 // ws_row: Number of rows (in cells) - Cols uint16 // ws_col: Number of columns (in cells) - X uint16 // ws_xpixel: Width in pixels - Y uint16 // ws_ypixel: Height in pixels -} - -func windowRectCall(ws *Winsize, fd, a2 uintptr) error { - _, _, errno := syscall.Syscall( - syscall.SYS_IOCTL, - fd, - a2, - uintptr(unsafe.Pointer(ws)), - ) - if errno != 0 { - return syscall.Errno(errno) - } - return nil -} diff --git a/vendor/github.com/jesseduffield/pty/ztypes_386.go b/vendor/github.com/jesseduffield/pty/ztypes_386.go deleted file mode 100644 index ff0b8fd8..00000000 --- a/vendor/github.com/jesseduffield/pty/ztypes_386.go +++ /dev/null @@ -1,9 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types.go - -package pty - -type ( - _C_int int32 - _C_uint uint32 -) diff --git a/vendor/github.com/jesseduffield/pty/ztypes_amd64.go b/vendor/github.com/jesseduffield/pty/ztypes_amd64.go deleted file mode 100644 index ff0b8fd8..00000000 --- a/vendor/github.com/jesseduffield/pty/ztypes_amd64.go +++ /dev/null @@ -1,9 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types.go - -package pty - -type ( - _C_int int32 - _C_uint uint32 -) diff --git a/vendor/github.com/jesseduffield/pty/ztypes_arm.go b/vendor/github.com/jesseduffield/pty/ztypes_arm.go deleted file mode 100644 index ff0b8fd8..00000000 --- a/vendor/github.com/jesseduffield/pty/ztypes_arm.go +++ /dev/null @@ -1,9 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types.go - -package pty - -type ( - _C_int int32 - _C_uint uint32 -) diff --git a/vendor/github.com/jesseduffield/pty/ztypes_arm64.go b/vendor/github.com/jesseduffield/pty/ztypes_arm64.go deleted file mode 100644 index 6c29a4b9..00000000 --- a/vendor/github.com/jesseduffield/pty/ztypes_arm64.go +++ /dev/null @@ -1,11 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types.go - -// +build arm64 - -package pty - -type ( - _C_int int32 - _C_uint uint32 -) diff --git a/vendor/github.com/jesseduffield/pty/ztypes_dragonfly_amd64.go b/vendor/github.com/jesseduffield/pty/ztypes_dragonfly_amd64.go deleted file mode 100644 index 6b0ba037..00000000 --- a/vendor/github.com/jesseduffield/pty/ztypes_dragonfly_amd64.go +++ /dev/null @@ -1,14 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_dragonfly.go - -package pty - -const ( - _C_SPECNAMELEN = 0x3f -) - -type fiodgnameArg struct { - Name *byte - Len uint32 - Pad_cgo_0 [4]byte -} diff --git a/vendor/github.com/jesseduffield/pty/ztypes_freebsd_386.go b/vendor/github.com/jesseduffield/pty/ztypes_freebsd_386.go deleted file mode 100644 index d9975374..00000000 --- a/vendor/github.com/jesseduffield/pty/ztypes_freebsd_386.go +++ /dev/null @@ -1,13 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_freebsd.go - -package pty - -const ( - _C_SPECNAMELEN = 0x3f -) - -type fiodgnameArg struct { - Len int32 - Buf *byte -} diff --git a/vendor/github.com/jesseduffield/pty/ztypes_freebsd_amd64.go b/vendor/github.com/jesseduffield/pty/ztypes_freebsd_amd64.go deleted file mode 100644 index 5fa102fc..00000000 --- a/vendor/github.com/jesseduffield/pty/ztypes_freebsd_amd64.go +++ /dev/null @@ -1,14 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_freebsd.go - -package pty - -const ( - _C_SPECNAMELEN = 0x3f -) - -type fiodgnameArg struct { - Len int32 - Pad_cgo_0 [4]byte - Buf *byte -} diff --git a/vendor/github.com/jesseduffield/pty/ztypes_freebsd_arm.go b/vendor/github.com/jesseduffield/pty/ztypes_freebsd_arm.go deleted file mode 100644 index d9975374..00000000 --- a/vendor/github.com/jesseduffield/pty/ztypes_freebsd_arm.go +++ /dev/null @@ -1,13 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_freebsd.go - -package pty - -const ( - _C_SPECNAMELEN = 0x3f -) - -type fiodgnameArg struct { - Len int32 - Buf *byte -} diff --git a/vendor/github.com/jesseduffield/pty/ztypes_mipsx.go b/vendor/github.com/jesseduffield/pty/ztypes_mipsx.go deleted file mode 100644 index f0ce7408..00000000 --- a/vendor/github.com/jesseduffield/pty/ztypes_mipsx.go +++ /dev/null @@ -1,12 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types.go - -// +build linux -// +build mips mipsle mips64 mips64le - -package pty - -type ( - _C_int int32 - _C_uint uint32 -) diff --git a/vendor/github.com/jesseduffield/pty/ztypes_openbsd_386.go b/vendor/github.com/jesseduffield/pty/ztypes_openbsd_386.go deleted file mode 100644 index ccb3aab9..00000000 --- a/vendor/github.com/jesseduffield/pty/ztypes_openbsd_386.go +++ /dev/null @@ -1,13 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_openbsd.go - -package pty - -type ptmget struct { - Cfd int32 - Sfd int32 - Cn [16]int8 - Sn [16]int8 -} - -var ioctl_PTMGET = 0x40287401 diff --git a/vendor/github.com/jesseduffield/pty/ztypes_openbsd_amd64.go b/vendor/github.com/jesseduffield/pty/ztypes_openbsd_amd64.go deleted file mode 100644 index e6705168..00000000 --- a/vendor/github.com/jesseduffield/pty/ztypes_openbsd_amd64.go +++ /dev/null @@ -1,13 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_openbsd.go - -package pty - -type ptmget struct { - Cfd int32 - Sfd int32 - Cn [16]int8 - Sn [16]int8 -} - -var ioctl_PTMGET = 0x40287401 diff --git a/vendor/github.com/jesseduffield/pty/ztypes_ppc64.go b/vendor/github.com/jesseduffield/pty/ztypes_ppc64.go deleted file mode 100644 index 4e1af843..00000000 --- a/vendor/github.com/jesseduffield/pty/ztypes_ppc64.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build ppc64 - -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types.go - -package pty - -type ( - _C_int int32 - _C_uint uint32 -) diff --git a/vendor/github.com/jesseduffield/pty/ztypes_ppc64le.go b/vendor/github.com/jesseduffield/pty/ztypes_ppc64le.go deleted file mode 100644 index e6780f4e..00000000 --- a/vendor/github.com/jesseduffield/pty/ztypes_ppc64le.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build ppc64le - -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types.go - -package pty - -type ( - _C_int int32 - _C_uint uint32 -) diff --git a/vendor/github.com/jesseduffield/pty/ztypes_s390x.go b/vendor/github.com/jesseduffield/pty/ztypes_s390x.go deleted file mode 100644 index a7452b61..00000000 --- a/vendor/github.com/jesseduffield/pty/ztypes_s390x.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build s390x - -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types.go - -package pty - -type ( - _C_int int32 - _C_uint uint32 -) From 344e5ecda558c1e95128010bdc250cbbff25ceaa Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Mon, 1 Jul 2019 23:30:51 +1000 Subject: [PATCH 20/26] default to container view when not in docker-compose context --- pkg/gui/gui.go | 15 ++++++++------- pkg/gui/layout.go | 6 +++++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index bb2c5a59..a5eb08b1 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -131,14 +131,8 @@ type guiState struct { // NewGui builds a new gui handler func NewGui(log *logrus.Entry, dockerCommand *commands.DockerCommand, oSCommand *commands.OSCommand, tr *i18n.TranslationSet, config *config.AppConfig, errorChan chan error) (*Gui, error) { - previousView := "containers" - if dockerCommand.InDockerComposeProject { - previousView = "services" - } - initialState := guiState{ - PreviousView: previousView, - Platform: *oSCommand.Platform, + Platform: *oSCommand.Platform, Panels: &panelStates{ Services: &servicePanelState{SelectedLine: -1, ContextIndex: 0}, Containers: &containerPanelState{SelectedLine: -1, ContextIndex: 0}, @@ -390,3 +384,10 @@ func (gui *Gui) shouldRefresh(key string) bool { gui.State.Panels.Main.ObjectKey = key return true } + +func (gui *Gui) initiallyFocusedViewName() string { + if gui.DockerCommand.InDockerComposeProject { + return "services" + } + return "containers" +} diff --git a/pkg/gui/layout.go b/pkg/gui/layout.go index a18ed005..71fb7e6a 100644 --- a/pkg/gui/layout.go +++ b/pkg/gui/layout.go @@ -275,7 +275,11 @@ func (gui *Gui) layout(g *gocui.Gui) error { if gui.g.CurrentView() == nil { v, err := gui.g.View(gui.State.PreviousView) if err != nil { - v = gui.getServicesView() + viewName := gui.initiallyFocusedViewName() + v, err = gui.g.View(viewName) + if err != nil { + return err + } } if err := gui.switchFocus(gui.g, nil, v); err != nil { From 86589c35170760a6250e2952b20a3d347e5b91f9 Mon Sep 17 00:00:00 2001 From: Mark Kopenga Date: Mon, 1 Jul 2019 15:46:18 +0200 Subject: [PATCH 21/26] Added dutch translations (#18) * Translated the keybindings * Translated the dutch.go file * Squased the commits * Added the sugestion from @YannickMeeus * Fixed a minor bug in the i18n file * Removed the .vscode settings * Squased the commits --- docs/keybindings/Keybindings_nl.md | 70 ++++++++++++------------ pkg/i18n/dutch.go | 87 +++++++++++++++++++++++++++++- pkg/i18n/i18n.go | 2 +- 3 files changed, 122 insertions(+), 37 deletions(-) diff --git a/docs/keybindings/Keybindings_nl.md b/docs/keybindings/Keybindings_nl.md index 50d7a427..8de2dfd5 100644 --- a/docs/keybindings/Keybindings_nl.md +++ b/docs/keybindings/Keybindings_nl.md @@ -3,66 +3,66 @@ ## Status
-  e: edit lazydocker config
-  o: open lazydocker config
-  [: previous tab
-  ]: next tab
-  m: view logs
-  enter: focus main panel
+  e: verander lazydocker configuratie
+  o: open lazydocker configuratie
+  [: vorige tab
+  ]: volgende tab
+  m: bekijk logs
+  enter: focus hooft panneel
 
## Containers
-  [: previous tab
-  ]: next tab
-  d: remove
+  [: vorige tab
+  ]: volgende tab
+  d: verwijder
   s: stop
-  r: restart
-  a: attach
-  D: prune exited containers
-  m: view logs
-  c: run predefined custom command
-  enter: focus main panel
+  r: herstart
+  a: vastmaken
+  D: verwijder verlaten containers
+  m: bekijk logs
+  c: draai een vooraf bedacht aangepaste opdracht
+  enter: focus hooft panneel
 
## Services
-  d: remove containers
+  d: verwijder containers
   s: stop
-  r: restart
-  a: attach
-  m: view logs
-  [: previous tab
-  ]: next tab
-  R: view restart options
-  c: run predefined custom command
-  enter: focus main panel
+  r: herstart
+  a: vermaken
+  m: bekijk logs
+  [: vorige tab
+  ]: volgende tab
+  R: bekijk herstart opties
+  c: draai een vooraf bedacht aangepaste opdracht
+  enter: focus hooft panneel
 
## Images
-  [: previous tab
-  ]: next tab
-  d: remove image
-  D: prune unused images
-  enter: focus main panel
+  [: vorige tab
+  ]: volgende tab
+  d: verwijder image
+  D: verwijder nietgebruikte images
+  enter: focus hooft panneel
 
## Volumes
-  [: previous tab
-  ]: next tab
-  d: remove volume
-  D: prune unused volumes
-  enter: focus main panel
+  [: vorige tab
+  ]: volgende tab
+  d: verwijder volume
+  D: verwijder nietgebruikte images
+  enter: focus hooft panneel
 
## Main
-  esc: return
+  esc: terug
 
diff --git a/pkg/i18n/dutch.go b/pkg/i18n/dutch.go index 681710f0..c416413e 100644 --- a/pkg/i18n/dutch.go +++ b/pkg/i18n/dutch.go @@ -1,5 +1,90 @@ package i18n func dutchSet() TranslationSet { - return TranslationSet{} + return TranslationSet{ + PruningStatus: "vernietigen", + RemovingStatus: "verwijderen", + RestartingStatus: "herstarten", + StoppingStatus: "stoppen", + RunningCustomCommandStatus: "Aangepast commando draaien", + + RunningSubprocess: "subprocess draaien", + NoViewMachingNewLineFocusedSwitchStatement: "No view matching newLineFocused switch statement", + + ErrorOccurred: "Er is iets fout gegaan! Zou je hier een issue aan willen maken: https://github.com/jesseduffield/lazydocker/issues", + ConnectionFailed: "connectie naar de docker client mislukt. Het zou kunnen dat je de docker client moet herstarten", + UnattachableContainerError: "Container heeft geen ondersteuning voor vastmaken. Je zou de service met het '-it' argument kunnen draaien of stop dit in je `stdin_open: true, tty: true` docker-compose.yml", + CannotAttachStoppedContainerError: "Je kan niet een vastgemaakte container stoppen, je moet het eerst starten (dit kan je doen met de 'r' toets) (ja ik ben te leu om dat voor je te doen automatisch)", + CannotAccessDockerSocketError: "Kan de docker socket niet bereiken: unix:///var/run/docker.sock\nDraai lazydocker als root of lees https://docs.docker.com/install/linux/linux-postinstall/", + + Donate: "Doneer", + Confirm: "Bevestigen", + + Return: "terug", + FocusMain: "focus hooft panneel", + Navigate: "navigeer", + Execute: "voer uit", + Close: "sluit", + Menu: "menu", + Scroll: "scroll", + OpenConfig: "open de lazydocker configuratie", + EditConfig: "verander de lazydocker configuratie", + Cancel: "annuleren", + Remove: "verwijder", + ForceRemove: "geforceerd verwijderen", + RemoveWithVolumes: "verwijder met volumes", + RemoveService: "verwijder containers", + Stop: "stop", + Restart: "herstart", + Rebuild: "herbouw", + Recreate: "hercreëer", + PreviousContext: "vorige tab", + NextContext: "volgende tab", + Attach: "verbinden", + ViewLogs: "bekijk logs", + RemoveImage: "verwijder image", + RemoveVolume: "verwijder volume", + RemoveWithoutPrune: "verwijder zonder de ongelabeld ouders te verwijderen", + PruneContainers: "vernietig bestaande containers", + PruneVolumes: "vernietig ongebruikte volumes", + PruneImages: "vernietig ongebruikte images", + ViewRestartOptions: "beijk herstart opties", + RunCustomCommand: "draai een vooraf bedacht aangepaste opdracht", + + AnonymousReportingTitle: "Help mee met lazydocker beter maken", + AnonymousReportingPrompt: "Zou je anonieme data rapportage willen aanzetten om lazygit beter te kunnen maken? (enter/esc)", + + GlobalTitle: "Globaal", + MainTitle: "Hooft", + StatusTitle: "Staat", + ServicesTitle: "Diensten", + ContainersTitle: "Containers", + StandaloneContainersTitle: "Alleenstaande Containers", + ImagesTitle: "Images", + VolumesTitle: "Volumes", + CustomCommandTitle: "Aangepast commando:", + ErrorTitle: "Fout", + LogsTitle: "Logs", + ConfigTitle: "Config", + DockerComposeConfigTitle: "Docker-Compose Configuratie", + TopTitle: "Top", + StatsTitle: "Stats", + CreditsTitle: "Over", + ContainerConfigTitle: "Container Configuratie", + + NoContainers: "Geen containers", + NoContainer: "Geen container", + NoImages: "Geen images", + NoVolumes: "Geen volumes", + + ConfirmQuit: "Weet je zeker dat je weg wil gaan?", + MustForceToRemoveContainer: "Je kan geen draaiende container verwijderen tenzij je het forceert, Wil je het forceren?", + NotEnoughSpace: "Niet genoeg ruimte om de panelen te renderen", + ConfirmPruneImages: "Weet je zeker dat je alle niet gebruikte images wil vernietigen?", + ConfirmPruneContainers: "Weet je zeker dat je alle niet gestopte containers wil vernietigen?", + ConfirmPruneVolumes: "Weet je zeker dat je alle niet gebruikte volumes wil vernietigen?", + StopService: "Weet je zeker dat je deze service zijn containers wil stoppen (enter/esc)?", + StopContainer: "Weet je zeker dat je deze container wil stoppen?", + PressEnterToReturn: "Druk op enter om terug te gaan naar lazydocker (Deze popup kan uit gezet worden door in de config dit neer te zetten `gui.returnImmediately: true`)", + } } diff --git a/pkg/i18n/i18n.go b/pkg/i18n/i18n.go index 4f6a93fc..8d2d21cb 100644 --- a/pkg/i18n/i18n.go +++ b/pkg/i18n/i18n.go @@ -31,7 +31,7 @@ func NewTranslationSet(log *logrus.Entry) *TranslationSet { } if strings.HasPrefix(userLang, "nl") { - mergo.Merge(&set, polishSet(), mergo.WithOverride) + mergo.Merge(&set, dutchSet(), mergo.WithOverride) } if strings.HasPrefix(userLang, "de") { From 389981af9cd3c0c39beee9dec107eb950d697260 Mon Sep 17 00:00:00 2001 From: Mikhail Swift Date: Mon, 1 Jul 2019 11:27:15 -0400 Subject: [PATCH 22/26] Add arch aur installation instructions --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 0182b011..a199facb 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,18 @@ required go version: 1.12 go get github.com/jesseduffield/lazydocker ``` +### Arch Linux AUR + +You can install lazydocker using your AUR package manager of choice or by running: + +```sh +git clone https://aur.archlinux.org/lazydocker.git ~/lazydocker +cd ~/lazydocker +makepkg --install +``` + +A development version of the AUR package is also [available](https://aur.archlinux.org/lazydocker-git.git) + ## Usage Call `lazydocker` in your terminal. I personally use this a lot so I've made an alias for it like so: From 24264b35e6e402780bb40996ebf387fc1670e782 Mon Sep 17 00:00:00 2001 From: Callum McIntyre Date: Mon, 1 Jul 2019 18:48:28 +0100 Subject: [PATCH 23/26] Add flaggy to vendor --- Gopkg.lock | 9 + vendor/github.com/integrii/flaggy/LICENSE | 24 + .../integrii/flaggy/argumentParser.go | 29 + vendor/github.com/integrii/flaggy/flag.go | 622 ++++++++++++++++ vendor/github.com/integrii/flaggy/help.go | 23 + .../github.com/integrii/flaggy/helpValues.go | 215 ++++++ vendor/github.com/integrii/flaggy/main.go | 341 +++++++++ vendor/github.com/integrii/flaggy/parser.go | 111 +++ .../integrii/flaggy/positionalValue.go | 14 + .../github.com/integrii/flaggy/subCommand.go | 691 ++++++++++++++++++ 10 files changed, 2079 insertions(+) create mode 100644 vendor/github.com/integrii/flaggy/LICENSE create mode 100644 vendor/github.com/integrii/flaggy/argumentParser.go create mode 100644 vendor/github.com/integrii/flaggy/flag.go create mode 100644 vendor/github.com/integrii/flaggy/help.go create mode 100644 vendor/github.com/integrii/flaggy/helpValues.go create mode 100644 vendor/github.com/integrii/flaggy/main.go create mode 100644 vendor/github.com/integrii/flaggy/parser.go create mode 100644 vendor/github.com/integrii/flaggy/positionalValue.go create mode 100644 vendor/github.com/integrii/flaggy/subCommand.go diff --git a/Gopkg.lock b/Gopkg.lock index 5acb6e3d..80ac9127 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -113,6 +113,14 @@ revision = "7c29201646fa3de8506f701213473dd407f19646" version = "v0.3.7" +[[projects]] + digest = "1:9cf73012dbe62f96cd8cdd210a1123a360401967a4530284dcd2990888747e3d" + name = "github.com/integrii/flaggy" + packages = ["."] + pruneopts = "NUT" + revision = "07ea7eb774047dab1bdcc7cad0f825fa419df47d" + version = "1.2.1" + [[projects]] branch = "master" digest = "1:7b2ab5c6de135d57d3a594b53068e2712da4d376b2f78097dec7b46d18deaa78" @@ -327,6 +335,7 @@ "github.com/fatih/color", "github.com/go-errors/errors", "github.com/imdario/mergo", + "github.com/integrii/flaggy", "github.com/jesseduffield/asciigraph", "github.com/jesseduffield/gocui", "github.com/jesseduffield/pty", diff --git a/vendor/github.com/integrii/flaggy/LICENSE b/vendor/github.com/integrii/flaggy/LICENSE new file mode 100644 index 00000000..cf1ab25d --- /dev/null +++ b/vendor/github.com/integrii/flaggy/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/vendor/github.com/integrii/flaggy/argumentParser.go b/vendor/github.com/integrii/flaggy/argumentParser.go new file mode 100644 index 00000000..089f2c5c --- /dev/null +++ b/vendor/github.com/integrii/flaggy/argumentParser.go @@ -0,0 +1,29 @@ +package flaggy + +// setValueForParsers sets the value for a specified key in the +// specified parsers (which normally include a Parser and Subcommand). +// The return values represent the key being set, and any errors +// returned when setting the key, such as failures to convert the string +// into the appropriate flag value. We stop assigning values as soon +// as we find a parser that accepts it. +func setValueForParsers(key string, value string, parsers ...ArgumentParser) (bool, error) { + + var valueWasSet bool + + for _, p := range parsers { + valueWasSet, err := p.SetValueForKey(key, value) + if err != nil { + return valueWasSet, err + } + if valueWasSet { + break + } + } + + return valueWasSet, nil +} + +// ArgumentParser represents a parser or subcommand +type ArgumentParser interface { + SetValueForKey(key string, value string) (bool, error) +} diff --git a/vendor/github.com/integrii/flaggy/flag.go b/vendor/github.com/integrii/flaggy/flag.go new file mode 100644 index 00000000..409ddf94 --- /dev/null +++ b/vendor/github.com/integrii/flaggy/flag.go @@ -0,0 +1,622 @@ +package flaggy + +import ( + "errors" + "fmt" + "net" + "reflect" + "strconv" + "strings" + "time" +) + +// Flag holds the base methods for all flag types +type Flag struct { + ShortName string + LongName string + Description string + rawValue string // the value as a string before being parsed + Hidden bool // indicates this flag should be hidden from help and suggestions + AssignmentVar interface{} + defaultValue string // the value (as a string), that was set by default before any parsing and assignment + parsed bool // indicates that this flag has already been parsed +} + +// HasName indicates that this flag's short or long name matches the +// supplied name string +func (f *Flag) HasName(name string) bool { + name = strings.TrimSpace(name) + if f.ShortName == name || f.LongName == name { + return true + } + return false +} + +// identifyAndAssignValue identifies the type of the incoming value +// and assigns it to the AssignmentVar pointer's target value. If +// the value is a type that needs parsing, that is performed as well. +func (f *Flag) identifyAndAssignValue(value string) error { + + var err error + + // Only parse this flag default value once. This keeps us from + // overwriting the default value in help output + if !f.parsed { + f.parsed = true + // parse the default value as a string and remember it for help output + f.defaultValue, err = f.returnAssignmentVarValueAsString() + if err != nil { + return err + } + } + + debugPrint("attempting to assign value", value, "to flag", f.LongName) + f.rawValue = value // remember the raw value + + // depending on the type of the assignment variable, we convert the + // incoming string and assign it. We only use pointers to variables + // in flagy. No returning vars by value. + switch f.AssignmentVar.(type) { + case *string: + v, _ := (f.AssignmentVar).(*string) + *v = value + case *[]string: + v := f.AssignmentVar.(*[]string) + splitString := strings.Split(value, ",") + new := append(*v, splitString...) + *v = new + case *bool: + v, err := strconv.ParseBool(value) + if err != nil { + return err + } + a, _ := (f.AssignmentVar).(*bool) + *a = v + case *[]bool: + // parse the incoming bool + b, err := strconv.ParseBool(value) + if err != nil { + return err + } + // cast the assignment var + existing := f.AssignmentVar.(*[]bool) + // deref the assignment var and append to it + v := append(*existing, b) + // pointer the new value and assign it + a, _ := (f.AssignmentVar).(*[]bool) + *a = v + case *time.Duration: + v, err := time.ParseDuration(value) + if err != nil { + return err + } + a, _ := (f.AssignmentVar).(*time.Duration) + *a = v + case *[]time.Duration: + t, err := time.ParseDuration(value) + if err != nil { + return err + } + existing := f.AssignmentVar.(*[]time.Duration) + // deref the assignment var and append to it + v := append(*existing, t) + // pointer the new value and assign it + a, _ := (f.AssignmentVar).(*[]time.Duration) + *a = v + case *float32: + v, err := strconv.ParseFloat(value, 32) + if err != nil { + return err + } + float := float32(v) + a, _ := (f.AssignmentVar).(*float32) + *a = float + case *[]float32: + v, err := strconv.ParseFloat(value, 32) + if err != nil { + return err + } + float := float32(v) + existing := f.AssignmentVar.(*[]float32) + new := append(*existing, float) + *existing = new + case *float64: + v, err := strconv.ParseFloat(value, 64) + if err != nil { + return err + } + a, _ := (f.AssignmentVar).(*float64) + *a = v + case *[]float64: + v, err := strconv.ParseFloat(value, 64) + if err != nil { + return err + } + existing := f.AssignmentVar.(*[]float64) + new := append(*existing, v) + + *existing = new + case *int: + v, err := strconv.Atoi(value) + if err != nil { + return err + } + e := f.AssignmentVar.(*int) + *e = v + case *[]int: + v, err := strconv.Atoi(value) + if err != nil { + return err + } + existing := f.AssignmentVar.(*[]int) + new := append(*existing, v) + *existing = new + case *uint: + v, err := strconv.ParseUint(value, 10, 64) + if err != nil { + return err + } + existing := f.AssignmentVar.(*uint) + *existing = uint(v) + case *[]uint: + v, err := strconv.ParseUint(value, 10, 64) + if err != nil { + return err + } + existing := f.AssignmentVar.(*[]uint) + new := append(*existing, uint(v)) + *existing = new + case *uint64: + v, err := strconv.ParseUint(value, 10, 64) + if err != nil { + return err + } + existing := f.AssignmentVar.(*uint64) + *existing = v + case *[]uint64: + v, err := strconv.ParseUint(value, 10, 64) + if err != nil { + return err + } + existing := f.AssignmentVar.(*[]uint64) + new := append(*existing, v) + *existing = new + case *uint32: + v, err := strconv.ParseUint(value, 10, 32) + if err != nil { + return err + } + existing := f.AssignmentVar.(*uint32) + *existing = uint32(v) + case *[]uint32: + v, err := strconv.ParseUint(value, 10, 32) + if err != nil { + return err + } + existing := f.AssignmentVar.(*[]uint32) + new := append(*existing, uint32(v)) + *existing = new + case *uint16: + v, err := strconv.ParseUint(value, 10, 16) + if err != nil { + return err + } + val := uint16(v) + existing := f.AssignmentVar.(*uint16) + *existing = val + case *[]uint16: + v, err := strconv.ParseUint(value, 10, 16) + if err != nil { + return err + } + existing := f.AssignmentVar.(*[]uint16) + new := append(*existing, uint16(v)) + *existing = new + case *uint8: + v, err := strconv.ParseUint(value, 10, 8) + if err != nil { + return err + } + val := uint8(v) + existing := f.AssignmentVar.(*uint8) + *existing = val + case *[]uint8: + var newSlice []uint8 + + v, err := strconv.ParseUint(value, 10, 8) + if err != nil { + return err + } + newV := uint8(v) + existing := f.AssignmentVar.(*[]uint8) + newSlice = append(*existing, newV) + *existing = newSlice + case *int64: + v, err := strconv.ParseInt(value, 10, 64) + if err != nil { + return err + } + existing := f.AssignmentVar.(*int64) + *existing = v + case *[]int64: + v, err := strconv.ParseInt(value, 10, 64) + if err != nil { + return err + } + existingSlice := f.AssignmentVar.(*[]int64) + newSlice := append(*existingSlice, v) + *existingSlice = newSlice + case *int32: + v, err := strconv.ParseInt(value, 10, 32) + if err != nil { + return err + } + converted := int32(v) + existing := f.AssignmentVar.(*int32) + *existing = converted + case *[]int32: + v, err := strconv.ParseInt(value, 10, 32) + if err != nil { + return err + } + existingSlice := f.AssignmentVar.(*[]int32) + newSlice := append(*existingSlice, int32(v)) + *existingSlice = newSlice + case *int16: + v, err := strconv.ParseInt(value, 10, 16) + if err != nil { + return err + } + converted := int16(v) + existing := f.AssignmentVar.(*int16) + *existing = converted + case *[]int16: + v, err := strconv.ParseInt(value, 10, 16) + if err != nil { + return err + } + existingSlice := f.AssignmentVar.(*[]int16) + newSlice := append(*existingSlice, int16(v)) + *existingSlice = newSlice + case *int8: + v, err := strconv.ParseInt(value, 10, 8) + if err != nil { + return err + } + converted := int8(v) + existing := f.AssignmentVar.(*int8) + *existing = converted + case *[]int8: + v, err := strconv.ParseInt(value, 10, 8) + if err != nil { + return err + } + existingSlice := f.AssignmentVar.(*[]int8) + newSlice := append(*existingSlice, int8(v)) + *existingSlice = newSlice + case *net.IP: + v := net.ParseIP(value) + existing := f.AssignmentVar.(*net.IP) + *existing = v + case *[]net.IP: + v := net.ParseIP(value) + existing := f.AssignmentVar.(*[]net.IP) + new := append(*existing, v) + *existing = new + case *net.HardwareAddr: + v, err := net.ParseMAC(value) + if err != nil { + return err + } + existing := f.AssignmentVar.(*net.HardwareAddr) + *existing = v + case *[]net.HardwareAddr: + v, err := net.ParseMAC(value) + if err != nil { + return err + } + existing := f.AssignmentVar.(*[]net.HardwareAddr) + new := append(*existing, v) + *existing = new + case *net.IPMask: + v := net.IPMask(net.ParseIP(value).To4()) + existing := f.AssignmentVar.(*net.IPMask) + *existing = v + case *[]net.IPMask: + v := net.IPMask(net.ParseIP(value).To4()) + existing := f.AssignmentVar.(*[]net.IPMask) + new := append(*existing, v) + *existing = new + default: + return errors.New("Unknown flag assignmentVar supplied in flag " + f.LongName + " " + f.ShortName) + } + + return err +} + +const argIsPositional = "positional" // subcommand or positional value +const argIsFlagWithSpace = "flagWithSpace" // -f path or --file path +const argIsFlagWithValue = "flagWithValue" // -f=path or --file=path +const argIsFinal = "final" // the final argument only '--' + +// determineArgType determines if the specified arg is a flag with space +// separated value, a flag with a connected value, or neither (positional) +func determineArgType(arg string) string { + + // if the arg is --, then its the final arg + if arg == "--" { + return argIsFinal + } + + // if it has the prefix --, then its a long flag + if strings.HasPrefix(arg, "--") { + // if it contains an equals, it is a joined value + if strings.Contains(arg, "=") { + return argIsFlagWithValue + } + return argIsFlagWithSpace + } + + // if it has the prefix -, then its a short flag + if strings.HasPrefix(arg, "-") { + // if it contains an equals, it is a joined value + if strings.Contains(arg, "=") { + return argIsFlagWithValue + } + return argIsFlagWithSpace + } + + return argIsPositional +} + +// parseArgWithValue parses a key=value concatenated argument into a key and +// value +func parseArgWithValue(arg string) (key string, value string) { + + // remove up to two minuses from start of flag + arg = strings.TrimPrefix(arg, "-") + arg = strings.TrimPrefix(arg, "-") + + // debugPrint("parseArgWithValue parsing", arg) + + // break at the equals + args := strings.SplitN(arg, "=", 2) + + // if its a bool arg, with no explicit value, we return a blank + if len(args) == 1 { + return args[0], "" + } + + // if its a key and value pair, we return those + if len(args) == 2 { + // debugPrint("parseArgWithValue parsed", args[0], args[1]) + return args[0], args[1] + } + + fmt.Println("Warning: attempted to parseArgWithValue but did not have correct parameter count.", arg, "->", args) + return "", "" +} + +// parseFlagToName parses a flag with space value down to a key name: +// --path -> path +// -p -> p +func parseFlagToName(arg string) string { + // remove minus from start + arg = strings.TrimLeft(arg, "-") + arg = strings.TrimLeft(arg, "-") + return arg +} + +// flagIsBool determines if the flag is a bool within the specified parser +// and subcommand's context +func flagIsBool(sc *Subcommand, p *Parser, key string) bool { + for _, f := range append(sc.Flags, p.Flags...) { + if f.HasName(key) { + _, isBool := f.AssignmentVar.(*bool) + _, isBoolSlice := f.AssignmentVar.(*[]bool) + if isBool || isBoolSlice { + return true + } + } + } + + // by default, the answer is false + return false +} + +// returnAssignmentVarValueAsString returns the value of the flag's +// assignment variable as a string. This is used to display the +// default value of flags before they are assigned (like when help is output). +func (f *Flag) returnAssignmentVarValueAsString() (string, error) { + + debugPrint("returning current value of assignment var of flag", f.LongName) + + var err error + + // depending on the type of the assignment variable, we convert the + // incoming string and assign it. We only use pointers to variables + // in flagy. No returning vars by value. + switch f.AssignmentVar.(type) { + case *string: + v, _ := (f.AssignmentVar).(*string) + return *v, err + case *[]string: + v := f.AssignmentVar.(*[]string) + return strings.Join(*v, ","), err + case *bool: + a, _ := (f.AssignmentVar).(*bool) + return strconv.FormatBool(*a), err + case *[]bool: + value := f.AssignmentVar.(*[]bool) + var ss []string + for _, b := range *value { + ss = append(ss, strconv.FormatBool(b)) + } + return strings.Join(ss, ","), err + case *time.Duration: + a := f.AssignmentVar.(*time.Duration) + return (*a).String(), err + case *[]time.Duration: + tds := f.AssignmentVar.(*[]time.Duration) + var asSlice []string + for _, td := range *tds { + asSlice = append(asSlice, td.String()) + } + return strings.Join(asSlice, ","), err + case *float32: + a := f.AssignmentVar.(*float32) + return strconv.FormatFloat(float64(*a), 'f', 2, 32), err + case *[]float32: + v := f.AssignmentVar.(*[]float32) + var strSlice []string + for _, f := range *v { + formatted := strconv.FormatFloat(float64(f), 'f', 2, 32) + strSlice = append(strSlice, formatted) + } + return strings.Join(strSlice, ","), err + case *float64: + a := f.AssignmentVar.(*float64) + return strconv.FormatFloat(float64(*a), 'f', 2, 64), err + case *[]float64: + v := f.AssignmentVar.(*[]float64) + var strSlice []string + for _, f := range *v { + formatted := strconv.FormatFloat(float64(f), 'f', 2, 64) + strSlice = append(strSlice, formatted) + } + return strings.Join(strSlice, ","), err + case *int: + a := f.AssignmentVar.(*int) + return strconv.Itoa(*a), err + case *[]int: + val := f.AssignmentVar.(*[]int) + var strSlice []string + for _, i := range *val { + str := strconv.Itoa(i) + strSlice = append(strSlice, str) + } + return strings.Join(strSlice, ","), err + case *uint: + v := f.AssignmentVar.(*uint) + return strconv.FormatUint(uint64(*v), 10), err + case *[]uint: + values := f.AssignmentVar.(*[]uint) + var strVars []string + for _, i := range *values { + strVars = append(strVars, strconv.FormatUint(uint64(i), 10)) + } + return strings.Join(strVars, ","), err + case *uint64: + v := f.AssignmentVar.(*uint64) + return strconv.FormatUint(*v, 10), err + case *[]uint64: + values := f.AssignmentVar.(*[]uint64) + var strVars []string + for _, i := range *values { + strVars = append(strVars, strconv.FormatUint(i, 10)) + } + return strings.Join(strVars, ","), err + case *uint32: + v := f.AssignmentVar.(*uint32) + return strconv.FormatUint(uint64(*v), 10), err + case *[]uint32: + values := f.AssignmentVar.(*[]uint32) + var strVars []string + for _, i := range *values { + strVars = append(strVars, strconv.FormatUint(uint64(i), 10)) + } + return strings.Join(strVars, ","), err + case *uint16: + v := f.AssignmentVar.(*uint16) + return strconv.FormatUint(uint64(*v), 10), err + case *[]uint16: + values := f.AssignmentVar.(*[]uint16) + var strVars []string + for _, i := range *values { + strVars = append(strVars, strconv.FormatUint(uint64(i), 10)) + } + return strings.Join(strVars, ","), err + case *uint8: + v := f.AssignmentVar.(*uint8) + return strconv.FormatUint(uint64(*v), 10), err + case *[]uint8: + values := f.AssignmentVar.(*[]uint8) + var strVars []string + for _, i := range *values { + strVars = append(strVars, strconv.FormatUint(uint64(i), 10)) + } + return strings.Join(strVars, ","), err + case *int64: + v := f.AssignmentVar.(*int64) + return strconv.FormatInt(int64(*v), 10), err + case *[]int64: + values := f.AssignmentVar.(*[]int64) + var strVars []string + for _, i := range *values { + strVars = append(strVars, strconv.FormatInt(i, 10)) + } + return strings.Join(strVars, ","), err + case *int32: + v := f.AssignmentVar.(*int32) + return strconv.FormatInt(int64(*v), 10), err + case *[]int32: + values := f.AssignmentVar.(*[]int32) + var strVars []string + for _, i := range *values { + strVars = append(strVars, strconv.FormatInt(int64(i), 10)) + } + return strings.Join(strVars, ","), err + case *int16: + v := f.AssignmentVar.(*int16) + return strconv.FormatInt(int64(*v), 10), err + case *[]int16: + values := f.AssignmentVar.(*[]int16) + var strVars []string + for _, i := range *values { + strVars = append(strVars, strconv.FormatInt(int64(i), 10)) + } + return strings.Join(strVars, ","), err + case *int8: + v := f.AssignmentVar.(*int8) + return strconv.FormatInt(int64(*v), 10), err + case *[]int8: + values := f.AssignmentVar.(*[]int8) + var strVars []string + for _, i := range *values { + strVars = append(strVars, strconv.FormatInt(int64(i), 10)) + } + return strings.Join(strVars, ","), err + case *net.IP: + val := f.AssignmentVar.(*net.IP) + return val.String(), err + case *[]net.IP: + val := f.AssignmentVar.(*[]net.IP) + var strSlice []string + for _, ip := range *val { + strSlice = append(strSlice, ip.String()) + } + return strings.Join(strSlice, ","), err + case *net.HardwareAddr: + val := f.AssignmentVar.(*net.HardwareAddr) + return val.String(), err + case *[]net.HardwareAddr: + val := f.AssignmentVar.(*[]net.HardwareAddr) + var strSlice []string + for _, mac := range *val { + strSlice = append(strSlice, mac.String()) + } + return strings.Join(strSlice, ","), err + case *net.IPMask: + val := f.AssignmentVar.(*net.IPMask) + return val.String(), err + case *[]net.IPMask: + val := f.AssignmentVar.(*[]net.IPMask) + var strSlice []string + for _, m := range *val { + strSlice = append(strSlice, m.String()) + } + return strings.Join(strSlice, ","), err + default: + return "", errors.New("Unknown flag assignmentVar found in flag " + f.LongName + " " + f.ShortName + ". Type not supported: " + reflect.TypeOf(f.AssignmentVar).String()) + } +} diff --git a/vendor/github.com/integrii/flaggy/help.go b/vendor/github.com/integrii/flaggy/help.go new file mode 100644 index 00000000..cdbb02b2 --- /dev/null +++ b/vendor/github.com/integrii/flaggy/help.go @@ -0,0 +1,23 @@ +package flaggy + +// defaultHelpTemplate is the help template used by default +// {{if (or (or (gt (len .StringFlags) 0) (gt (len .IntFlags) 0)) (gt (len .BoolFlags) 0))}} +// {{if (or (gt (len .StringFlags) 0) (gt (len .BoolFlags) 0))}} +const defaultHelpTemplate = `{{.CommandName}}{{if .Description}} - {{.Description}}{{end}}{{if .PrependMessage}} +{{.PrependMessage}}{{end}} +{{if .UsageString}} + Usage: + {{.UsageString}}{{end}}{{if .Positionals}} + + Positional Variables: {{range .Positionals}} + {{.Name}}{{if .Required}} (Required){{end}}{{if .Description}} - {{.Description}}{{end}}{{if .DefaultValue}} (default: {{.DefaultValue}}){{end}}{{end}}{{end}}{{if .Subcommands}} + + Subcommands: {{range .Subcommands}} + {{.LongName}}{{if .ShortName}} ({{.ShortName}}){{end}}{{if .Position}}{{if gt .Position 1}} (position {{.Position}}){{end}}{{end}}{{if .Description}} - {{.Description}}{{end}}{{end}} +{{end}}{{if (gt (len .Flags) 0)}} + Flags: {{if .Flags}}{{range .Flags}} + {{if .ShortName}}-{{.ShortName}} {{else}} {{end}}{{if .LongName}}--{{.LongName}} {{end}}{{if .Description}} {{.Description}}{{if .DefaultValue}} (default: {{.DefaultValue}}){{end}}{{end}}{{end}}{{end}} +{{end}}{{if .AppendMessage}}{{.AppendMessage}} +{{end}}{{if .Message}} +{{.Message}}{{end}} +` diff --git a/vendor/github.com/integrii/flaggy/helpValues.go b/vendor/github.com/integrii/flaggy/helpValues.go new file mode 100644 index 00000000..8a5146b1 --- /dev/null +++ b/vendor/github.com/integrii/flaggy/helpValues.go @@ -0,0 +1,215 @@ +package flaggy + +// Help represents the values needed to render a Help page +type Help struct { + Subcommands []HelpSubcommand + Positionals []HelpPositional + Flags []HelpFlag + UsageString string + CommandName string + PrependMessage string + AppendMessage string + Message string + Description string +} + +// HelpSubcommand is used to template subcommand Help output +type HelpSubcommand struct { + ShortName string + LongName string + Description string + Position int +} + +// HelpPositional is used to template positional Help output +type HelpPositional struct { + Name string + Description string + Required bool + Position int + DefaultValue string +} + +// HelpFlag is used to template string flag Help output +type HelpFlag struct { + ShortName string + LongName string + Description string + DefaultValue string +} + +// ExtractValues extracts Help template values from a subcommand and its parent +// parser. The parser is required in order to detect default flag settings +// for help and version outut. +func (h *Help) ExtractValues(p *Parser, message string) { + + // accept message string for output + h.Message = message + + // extract Help values from the current subcommand in context + // prependMessage string + h.PrependMessage = p.subcommandContext.AdditionalHelpPrepend + // appendMessage string + h.AppendMessage = p.subcommandContext.AdditionalHelpAppend + // command name + h.CommandName = p.subcommandContext.Name + // description + h.Description = p.subcommandContext.Description + + // subcommands []HelpSubcommand + for _, cmd := range p.subcommandContext.Subcommands { + if cmd.Hidden { + continue + } + newHelpSubcommand := HelpSubcommand{ + ShortName: cmd.ShortName, + LongName: cmd.Name, + Description: cmd.Description, + Position: cmd.Position, + } + h.Subcommands = append(h.Subcommands, newHelpSubcommand) + } + + // parse positional flags into help output structs + for _, pos := range p.subcommandContext.PositionalFlags { + if pos.Hidden { + continue + } + newHelpPositional := HelpPositional{ + Name: pos.Name, + Position: pos.Position, + Description: pos.Description, + Required: pos.Required, + DefaultValue: pos.defaultValue, + } + h.Positionals = append(h.Positionals, newHelpPositional) + } + + // if the built-in version flag is enabled, then add it as a help flag + if p.ShowVersionWithVersionFlag { + defaultVersionFlag := HelpFlag{ + ShortName: "", + LongName: versionFlagLongName, + Description: "Displays the program version string.", + DefaultValue: "", + } + h.Flags = append(h.Flags, defaultVersionFlag) + } + + // if the built-in help flag exists, then add it as a help flag + if p.ShowHelpWithHFlag { + defaultHelpFlag := HelpFlag{ + ShortName: helpFlagShortName, + LongName: helpFlagLongName, + Description: "Displays help with available flag, subcommand, and positional value parameters.", + DefaultValue: "", + } + h.Flags = append(h.Flags, defaultHelpFlag) + } + + // go through every flag in the subcommand and add it to help output + h.parseFlagsToHelpFlags(p.subcommandContext.Flags) + + // go through every flag in the parent parser and add it to help output + h.parseFlagsToHelpFlags(p.Flags) + + // formulate the usage string + // first, we capture all the command and positional names by position + commandsByPosition := make(map[int]string) + for _, pos := range p.subcommandContext.PositionalFlags { + if pos.Hidden { + continue + } + if len(commandsByPosition[pos.Position]) > 0 { + commandsByPosition[pos.Position] = commandsByPosition[pos.Position] + "|" + pos.Name + } else { + commandsByPosition[pos.Position] = pos.Name + } + } + for _, cmd := range p.subcommandContext.Subcommands { + if cmd.Hidden { + continue + } + if len(commandsByPosition[cmd.Position]) > 0 { + commandsByPosition[cmd.Position] = commandsByPosition[cmd.Position] + "|" + cmd.Name + } else { + commandsByPosition[cmd.Position] = cmd.Name + } + } + + // find the highest position count in the map + var highestPosition int + for i := range commandsByPosition { + if i > highestPosition { + highestPosition = i + } + } + + // only have a usage string if there are positional items + var usageString string + if highestPosition > 0 { + // find each positional value and make our final string + usageString = p.subcommandContext.Name + for i := 1; i <= highestPosition; i++ { + if len(commandsByPosition[i]) > 0 { + usageString = usageString + " [" + commandsByPosition[i] + "]" + } else { + // dont keep listing after the first position without any properties + // it will be impossible to reach anything beyond here anyway + break + } + } + } + + h.UsageString = usageString + +} + +// parseFlagsToHelpFlags parses the specified slice of flags into +// help flags on the the calling help command +func (h *Help) parseFlagsToHelpFlags(flags []*Flag) { + for _, f := range flags { + if f.Hidden { + continue + } + + // determine the default value based on the assignment variable + defaultValue := f.defaultValue + + // dont show nils + if defaultValue == "" { + defaultValue = "" + } + + // for bools, dont show a default of false + _, isBool := f.AssignmentVar.(*bool) + if isBool { + b := f.AssignmentVar.(*bool) + if *b == false { + defaultValue = "" + } + } + + newHelpFlag := HelpFlag{ + ShortName: f.ShortName, + LongName: f.LongName, + Description: f.Description, + DefaultValue: defaultValue, + } + + h.AddFlagToHelp(newHelpFlag) + } +} + +// AddFlagToHelp adds a flag to help output if it does not exist +func (h *Help) AddFlagToHelp(f HelpFlag) { + for _, existingFlag := range h.Flags { + if len(existingFlag.ShortName) > 0 && existingFlag.ShortName == f.ShortName { + return + } + if len(existingFlag.LongName) > 0 && existingFlag.LongName == f.LongName { + return + } + } + h.Flags = append(h.Flags, f) +} diff --git a/vendor/github.com/integrii/flaggy/main.go b/vendor/github.com/integrii/flaggy/main.go new file mode 100644 index 00000000..b44cd915 --- /dev/null +++ b/vendor/github.com/integrii/flaggy/main.go @@ -0,0 +1,341 @@ +// Package flaggy is a input flag parsing package that supports recursive +// subcommands, positional values, and any-position flags without +// unnecessary complexeties. +// +// For a getting started tutorial and full feature list, check out the +// readme at https://github.com/integrii/flaggy. +package flaggy // import "github.com/integrii/flaggy" + +import ( + "fmt" + "log" + "net" + "os" + "strconv" + "strings" + "time" +) + +// strings used for builtin help and version flags both short and long +const versionFlagLongName = "version" +const helpFlagLongName = "help" +const helpFlagShortName = "h" + +// defaultVersion is applied to parsers when they are created +const defaultVersion = "0.0.0" + +// DebugMode indicates that debug output should be enabled +var DebugMode bool + +// DefaultHelpTemplate is the help template that will be used +// for newly created subcommands and commands +var DefaultHelpTemplate = defaultHelpTemplate + +// DefaultParser is the default parser that is used with the package-level public +// functions +var DefaultParser *Parser + +// TrailingArguments holds trailing arguments in the main parser after parsing +// has been run. +var TrailingArguments []string + +func init() { + + // set the default help template + // allow usage like flaggy.StringVar by enabling a default Parser + ResetParser() +} + +// ResetParser resets the default parser to a fresh instance. Uses the +// name of the binary executing as the program name by default. +func ResetParser() { + if len(os.Args) > 0 { + chunks := strings.Split(os.Args[0], "/") + DefaultParser = NewParser(chunks[len(chunks)-1]) + } else { + DefaultParser = NewParser("default") + } +} + +// Parse parses flags as requested in the default package parser +func Parse() { + err := DefaultParser.Parse() + TrailingArguments = DefaultParser.TrailingArguments + if err != nil { + log.Panicln("Error from argument parser:", err) + } +} + +// ParseArgs parses the passed args as if they were the arguments to the +// running binary. Targets the default main parser for the package. +func ParseArgs(args []string) { + err := DefaultParser.ParseArgs(args) + TrailingArguments = DefaultParser.TrailingArguments + if err != nil { + log.Panicln("Error from argument parser:", err) + } +} + +// String adds a new string flag +func String(assignmentVar *string, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// StringSlice adds a new slice of strings flag +// Specify the flag multiple times to fill the slice +func StringSlice(assignmentVar *[]string, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// Bool adds a new bool flag +func Bool(assignmentVar *bool, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// BoolSlice adds a new slice of bools flag +// Specify the flag multiple times to fill the slice +func BoolSlice(assignmentVar *[]bool, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// ByteSlice adds a new slice of bytes flag +// Specify the flag multiple times to fill the slice. Takes hex as input. +func ByteSlice(assignmentVar *[]byte, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// Duration adds a new time.Duration flag. +// Input format is described in time.ParseDuration(). +// Example values: 1h, 1h50m, 32s +func Duration(assignmentVar *time.Duration, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// DurationSlice adds a new time.Duration flag. +// Input format is described in time.ParseDuration(). +// Example values: 1h, 1h50m, 32s +// Specify the flag multiple times to fill the slice. +func DurationSlice(assignmentVar *[]time.Duration, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// Float32 adds a new float32 flag. +func Float32(assignmentVar *float32, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// Float32Slice adds a new float32 flag. +// Specify the flag multiple times to fill the slice. +func Float32Slice(assignmentVar *[]float32, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// Float64 adds a new float64 flag. +func Float64(assignmentVar *float64, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// Float64Slice adds a new float64 flag. +// Specify the flag multiple times to fill the slice. +func Float64Slice(assignmentVar *[]float64, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// Int adds a new int flag +func Int(assignmentVar *int, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// IntSlice adds a new int slice flag. +// Specify the flag multiple times to fill the slice. +func IntSlice(assignmentVar *[]int, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// UInt adds a new uint flag +func UInt(assignmentVar *uint, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// UIntSlice adds a new uint slice flag. +// Specify the flag multiple times to fill the slice. +func UIntSlice(assignmentVar *[]uint, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// UInt64 adds a new uint64 flag +func UInt64(assignmentVar *uint64, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// UInt64Slice adds a new uint64 slice flag. +// Specify the flag multiple times to fill the slice. +func UInt64Slice(assignmentVar *[]uint64, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// UInt32 adds a new uint32 flag +func UInt32(assignmentVar *uint32, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// UInt32Slice adds a new uint32 slice flag. +// Specify the flag multiple times to fill the slice. +func UInt32Slice(assignmentVar *[]uint32, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// UInt16 adds a new uint16 flag +func UInt16(assignmentVar *uint16, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// UInt16Slice adds a new uint16 slice flag. +// Specify the flag multiple times to fill the slice. +func UInt16Slice(assignmentVar *[]uint16, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// UInt8 adds a new uint8 flag +func UInt8(assignmentVar *uint8, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// UInt8Slice adds a new uint8 slice flag. +// Specify the flag multiple times to fill the slice. +func UInt8Slice(assignmentVar *[]uint8, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// Int64 adds a new int64 flag +func Int64(assignmentVar *int64, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// Int64Slice adds a new int64 slice flag. +// Specify the flag multiple times to fill the slice. +func Int64Slice(assignmentVar *[]int64, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// Int32 adds a new int32 flag +func Int32(assignmentVar *int32, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// Int32Slice adds a new int32 slice flag. +// Specify the flag multiple times to fill the slice. +func Int32Slice(assignmentVar *[]int32, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// Int16 adds a new int16 flag +func Int16(assignmentVar *int16, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// Int16Slice adds a new int16 slice flag. +// Specify the flag multiple times to fill the slice. +func Int16Slice(assignmentVar *[]int16, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// Int8 adds a new int8 flag +func Int8(assignmentVar *int8, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// Int8Slice adds a new int8 slice flag. +// Specify the flag multiple times to fill the slice. +func Int8Slice(assignmentVar *[]int8, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// IP adds a new net.IP flag. +func IP(assignmentVar *net.IP, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// IPSlice adds a new int8 slice flag. +// Specify the flag multiple times to fill the slice. +func IPSlice(assignmentVar *[]net.IP, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// HardwareAddr adds a new net.HardwareAddr flag. +func HardwareAddr(assignmentVar *net.HardwareAddr, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// HardwareAddrSlice adds a new net.HardwareAddr slice flag. +// Specify the flag multiple times to fill the slice. +func HardwareAddrSlice(assignmentVar *[]net.HardwareAddr, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// IPMask adds a new net.IPMask flag. IPv4 Only. +func IPMask(assignmentVar *net.IPMask, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// IPMaskSlice adds a new net.HardwareAddr slice flag. IPv4 only. +// Specify the flag multiple times to fill the slice. +func IPMaskSlice(assignmentVar *[]net.IPMask, shortName string, longName string, description string) { + DefaultParser.add(assignmentVar, shortName, longName, description) +} + +// AttachSubcommand adds a subcommand for parsing +func AttachSubcommand(subcommand *Subcommand, relativePosition int) { + DefaultParser.AttachSubcommand(subcommand, relativePosition) +} + +// ShowHelp shows parser help +func ShowHelp(message string) { + DefaultParser.ShowHelpWithMessage(message) +} + +// SetDescription sets the description of the default package command parser +func SetDescription(description string) { + DefaultParser.Description = description +} + +// SetVersion sets the version of the default package command parser +func SetVersion(version string) { + DefaultParser.Version = version +} + +// SetName sets the name of the default package command parser +func SetName(name string) { + DefaultParser.Name = name +} + +// ShowHelpAndExit shows parser help and exits with status code 2 +func ShowHelpAndExit(message string) { + ShowHelp(message) + exitOrPanic(2) +} + +// PanicInsteadOfExit is used when running tests +var PanicInsteadOfExit bool + +// exitOrPanic panics instead of calling os.Exit so that tests can catch +// more failures +func exitOrPanic(code int) { + if PanicInsteadOfExit { + panic("Panic instead of exit with code: " + strconv.Itoa(code)) + } + os.Exit(code) +} + +// AddPositionalValue adds a positional value to the main parser at the global +// context +func AddPositionalValue(assignmentVar *string, name string, relativePosition int, required bool, description string) { + DefaultParser.AddPositionalValue(assignmentVar, name, relativePosition, required, description) +} + +// debugPrint prints if debugging is enabled +func debugPrint(i ...interface{}) { + if DebugMode { + fmt.Println(i...) + } +} diff --git a/vendor/github.com/integrii/flaggy/parser.go b/vendor/github.com/integrii/flaggy/parser.go new file mode 100644 index 00000000..06639326 --- /dev/null +++ b/vendor/github.com/integrii/flaggy/parser.go @@ -0,0 +1,111 @@ +package flaggy + +import ( + "errors" + "fmt" + "os" + + "text/template" +) + +// Parser represents the set of vars and subcommands we are expecting +// from our input args, and the parser than handles them all. +type Parser struct { + Subcommand + Version string // the optional version of the parser. + ShowHelpWithHFlag bool // display help when -h or --help passed + ShowVersionWithVersionFlag bool // display the version when --version passed + ShowHelpOnUnexpected bool // display help when an unexpected flag is passed + TrailingArguments []string // everything after a -- is placed here + HelpTemplate *template.Template // template for Help output + trailingArgumentsExtracted bool // indicates that trailing args have been parsed and should not be appended again + parsed bool // indicates this parser has parsed + subcommandContext *Subcommand // points to the most specific subcommand being used +} + +// NewParser creates a new ArgumentParser ready to parse inputs +func NewParser(name string) *Parser { + // this can not be done inline because of struct embedding + p := &Parser{} + p.Name = name + p.Version = defaultVersion + p.ShowHelpOnUnexpected = true + p.ShowHelpWithHFlag = true + p.ShowVersionWithVersionFlag = true + p.SetHelpTemplate(DefaultHelpTemplate) + p.subcommandContext = &Subcommand{} + return p +} + +// ParseArgs parses as if the passed args were the os.Args, but without the +// binary at the 0 position in the array. An error is returned if there +// is a low level issue converting flags to their proper type. No error +// is returned for invalid arguments or missing require subcommands. +func (p *Parser) ParseArgs(args []string) error { + if p.parsed { + return errors.New("Parser.Parse() called twice on parser with name: " + " " + p.Name + " " + p.ShortName) + } + p.parsed = true + // debugPrint("Kicking off parsing with args:", args) + return p.parse(p, args, 0) +} + +// ShowVersionAndExit shows the version of this parser +func (p *Parser) ShowVersionAndExit() { + fmt.Println("Version:", p.Version) + exitOrPanic(0) +} + +// SetHelpTemplate sets the go template this parser will use when rendering +// Help. +func (p *Parser) SetHelpTemplate(tmpl string) error { + var err error + p.HelpTemplate = template.New(helpFlagLongName) + p.HelpTemplate, err = p.HelpTemplate.Parse(tmpl) + if err != nil { + return err + } + return nil +} + +// Parse calculates all flags and subcommands +func (p *Parser) Parse() error { + + err := p.ParseArgs(os.Args[1:]) + if err != nil { + return err + } + return nil + +} + +// ShowHelp shows Help without an error message +func (p *Parser) ShowHelp() { + debugPrint("showing help for", p.subcommandContext.Name) + p.ShowHelpWithMessage("") +} + +// ShowHelpAndExit shows parser help and exits with status code 2 +func (p *Parser) ShowHelpAndExit(message string) { + p.ShowHelpWithMessage(message) + exitOrPanic(2) +} + +// ShowHelpWithMessage shows the Help for this parser with an optional string error +// message as a header. The supplied subcommand will be the context of Help +// displayed to the user. +func (p *Parser) ShowHelpWithMessage(message string) { + + // create a new Help values template and extract values into it + help := Help{} + help.ExtractValues(p, message) + err := p.HelpTemplate.Execute(os.Stderr, help) + if err != nil { + fmt.Fprintln(os.Stderr, "Error rendering Help template:", err) + } +} + +// Disable show version with --version. It is enabled by default. +func (p *Parser) DisableShowVersionWithVersion() { + p.ShowVersionWithVersionFlag = false +} diff --git a/vendor/github.com/integrii/flaggy/positionalValue.go b/vendor/github.com/integrii/flaggy/positionalValue.go new file mode 100644 index 00000000..bf649a9d --- /dev/null +++ b/vendor/github.com/integrii/flaggy/positionalValue.go @@ -0,0 +1,14 @@ +package flaggy + +// PositionalValue represents a value which is determined by its position +// relative to where a subcommand was detected. +type PositionalValue struct { + Name string // used in documentation only + Description string + AssignmentVar *string // the var that will get this variable + Position int // the position, not including switches, of this variable + Required bool // this subcommand must always be specified + Found bool // was this positional found during parsing? + Hidden bool // indicates this positional value should be hidden from help + defaultValue string // used for help output +} diff --git a/vendor/github.com/integrii/flaggy/subCommand.go b/vendor/github.com/integrii/flaggy/subCommand.go new file mode 100644 index 00000000..95d87295 --- /dev/null +++ b/vendor/github.com/integrii/flaggy/subCommand.go @@ -0,0 +1,691 @@ +package flaggy + +import ( + "fmt" + "log" + "net" + "os" + "strconv" + "strings" + "time" +) + +// Subcommand represents a subcommand which contains a set of child +// subcommands along with a set of flags relevant to it. Parsing +// runs until a subcommand is detected by matching its name and +// position. Once a matching subcommand is found, the next set +// of parsing occurs within that matched subcommand. +type Subcommand struct { + Name string + ShortName string + Description string + Position int // the position of this subcommand, not including flags + Subcommands []*Subcommand + Flags []*Flag + PositionalFlags []*PositionalValue + AdditionalHelpPrepend string // additional prepended message when Help is displayed + AdditionalHelpAppend string // additional appended message when Help is displayed + Used bool // indicates this subcommand was found and parsed + Hidden bool // indicates this subcommand should be hidden from help +} + +// NewSubcommand creates a new subcommand that can have flags or PositionalFlags +// added to it. The position starts with 1, not 0 +func NewSubcommand(name string) *Subcommand { + newSC := &Subcommand{ + Name: name, + } + return newSC +} + +// parseAllFlagsFromArgs parses the non-positional flags such as -f or -v=value +// out of the supplied args and returns the positional items in order. +func (sc *Subcommand) parseAllFlagsFromArgs(p *Parser, args []string) ([]string, bool, error) { + + var err error + var positionalOnlyArguments []string + var helpRequested bool // indicates the user has supplied -h and we + // should render help if we are the last subcommand + + // indicates we should skip the next argument, like when parsing a flag + // that separates key and value by space + var skipNext bool + + // endArgfound indicates that a -- was found and everything + // remaining should be added to the trailing arguments slices + var endArgFound bool + + // find all the normal flags (not positional) and parse them out + for i, a := range args { + + debugPrint("parsing arg", 1, a) + + // evaluate if there is a following arg to avoid panics + var nextArgExists bool + var nextArg string + if len(args)-1 >= i+1 { + nextArgExists = true + nextArg = args[i+1] + } + + // if end arg -- has been found, just add everything to TrailingArguments + if endArgFound { + if !p.trailingArgumentsExtracted { + p.TrailingArguments = append(p.TrailingArguments, a) + } + continue + } + + // skip this run if specified + if skipNext { + skipNext = false + debugPrint("skipping flag because it is an arg:", a) + continue + } + + // parse the flag into its name for consideration without dashes + flagName := parseFlagToName(a) + + // if the flag being passed is version or v and the option to display + // version with version flags, then display version + if p.ShowVersionWithVersionFlag { + if flagName == versionFlagLongName { + p.ShowVersionAndExit() + } + } + + // if the show Help on h flag option is set, then show Help when h or Help + // is passed as an option + if p.ShowHelpWithHFlag { + if flagName == helpFlagShortName || flagName == helpFlagLongName { + // Ensure this is the last subcommand passed so we give the correct + // help output + helpRequested = true + continue + } + } + + // determine what kind of flag this is + argType := determineArgType(a) + + // strip flags from arg + // debugPrint("Parsing flag named", a, "of type", argType) + + // depending on the flag type, parse the key and value out, then apply it + switch argType { + case argIsFinal: + // debugPrint("Arg", i, "is final:", a) + endArgFound = true + case argIsPositional: + // debugPrint("Arg is positional or subcommand:", a) + // this positional argument into a slice of their own, so that + // we can determine if its a subcommand or positional value later + positionalOnlyArguments = append(positionalOnlyArguments, a) + case argIsFlagWithSpace: + a = parseFlagToName(a) + // debugPrint("Arg", i, "is flag with space:", a) + // parse next arg as value to this flag and apply to subcommand flags + // if the flag is a bool flag, then we check for a following positional + // and skip it if necessary + if flagIsBool(sc, p, a) { + debugPrint(sc.Name, "bool flag", a, "next var is:", nextArg) + _, err = setValueForParsers(a, "true", p, sc) + + // if an error occurs, just return it and quit parsing + if err != nil { + return []string{}, false, err + } + // by default, we just assign the next argument to the value and continue + continue + } + + skipNext = true + debugPrint(sc.Name, "NOT bool flag", a) + + // if the next arg was not found, then show a Help message + if !nextArgExists { + p.ShowHelpWithMessage("Expected a following arg for flag " + a + ", but it did not exist.") + exitOrPanic(2) + } + _, err = setValueForParsers(a, nextArg, p, sc) + if err != nil { + return []string{}, false, err + } + case argIsFlagWithValue: + // debugPrint("Arg", i, "is flag with value:", a) + a = parseFlagToName(a) + // parse flag into key and value and apply to subcommand flags + key, val := parseArgWithValue(a) + _, err = setValueForParsers(key, val, p, sc) + if err != nil { + return []string{}, false, err + } + // if this flag type was found and not set, and the parser is set to show + // Help when an unknown flag is found, then show Help and exit. + } + + } + + return positionalOnlyArguments, helpRequested, nil +} + +// Parse causes the argument parser to parse based on the supplied []string. +// depth specifies the non-flag subcommand positional depth +func (sc *Subcommand) parse(p *Parser, args []string, depth int) error { + + debugPrint("- Parsing subcommand", sc.Name, "with depth of", depth, "and args", args) + + // if a command is parsed, its used + sc.Used = true + + // as subcommands are used, they become the context of the parser. This helps + // us understand how to display help based on which subcommand is being used + p.subcommandContext = sc + + // ensure that help and version flags are not used if the parser has the + // built-in help and version flags enabled + if p.ShowHelpWithHFlag { + sc.ensureNoConflictWithBuiltinHelp() + } + if p.ShowVersionWithVersionFlag { + sc.ensureNoConflictWithBuiltinVersion() + } + + // Parse the normal flags out of the argument list and retain the positionals. + // Apply the flags to the parent parser and the current subcommand context. + // ./command -f -z subcommand someVar -b becomes ./command subcommand somevar + positionalOnlyArguments, helpRequested, err := sc.parseAllFlagsFromArgs(p, args) + if err != nil { + return err + } + + // indicate that trailing arguments have been extracted, so that they aren't + // appended a second time + p.trailingArgumentsExtracted = true + + // loop over positional values and look for their matching positional + // parameter, or their positional command. If neither are found, then + // we throw an error + var parsedArgCount int + for pos, v := range positionalOnlyArguments { + + // the first relative positional argument will be human natural at position 1 + // but offset for the depth of relative commands being parsed for currently. + relativeDepth := pos - depth + 1 + // debugPrint("Parsing positional only position", relativeDepth, "with value", v) + + if relativeDepth < 1 { + // debugPrint(sc.Name, "skipped value:", v) + continue + } + parsedArgCount++ + + // determine subcommands and parse them by positional value and name + for _, cmd := range sc.Subcommands { + // debugPrint("Subcommand being compared", relativeDepth, "==", cmd.Position, "and", v, "==", cmd.Name, "==", cmd.ShortName) + if relativeDepth == cmd.Position && (v == cmd.Name || v == cmd.ShortName) { + debugPrint("Decending into positional subcommand", cmd.Name, "at relativeDepth", relativeDepth, "and absolute depth", depth+1) + return cmd.parse(p, args, depth+parsedArgCount) // continue recursive positional parsing + } + } + + // determine positional args and parse them by positional value and name + var foundPositional bool + for _, val := range sc.PositionalFlags { + if relativeDepth == val.Position { + debugPrint("Found a positional value at relativePos:", relativeDepth, "value:", v) + + // set original value for help output + val.defaultValue = *val.AssignmentVar + + // defrerence the struct pointer, then set the pointer property within it + *val.AssignmentVar = v + // debugPrint("set positional to value", *val.AssignmentVar) + foundPositional = true + val.Found = true + break + } + } + + // if there aren't any positional flags but there are subcommands that + // were not used, display a useful message with subcommand options. + if !foundPositional && p.ShowHelpOnUnexpected { + debugPrint("No positional at position", relativeDepth) + var foundSubcommandAtDepth bool + for _, cmd := range sc.Subcommands { + if cmd.Position == relativeDepth { + foundSubcommandAtDepth = true + } + } + + // if there is a subcommand here but it was not specified, display them all + // as a suggestion to the user before exiting. + if foundSubcommandAtDepth { + // determine which name to use in upcoming help output + fmt.Fprintln(os.Stderr, sc.Name+":", "No subcommand or positional value found at position", strconv.Itoa(relativeDepth)+".") + var output string + for _, cmd := range sc.Subcommands { + if cmd.Hidden { + continue + } + output = output + " " + cmd.Name + } + // if there are available subcommands, let the user know + if len(output) > 0 { + output = strings.TrimLeft(output, " ") + fmt.Println("Available subcommands:", output) + } + exitOrPanic(2) + } + + // if there were not any flags or subcommands at this position at all, then + // throw an error (display Help if necessary) + p.ShowHelpWithMessage("Unexpected argument: " + v) + exitOrPanic(2) + } + } + + // if help was requested and we should show help when h is passed, + if helpRequested && p.ShowHelpWithHFlag { + p.ShowHelp() + exitOrPanic(0) + } + + // find any positionals that were not used on subcommands that were + // found and throw help (unknown argument) + for _, pv := range p.PositionalFlags { + if pv.Required && !pv.Found { + p.ShowHelpWithMessage("Required global positional variable " + pv.Name + " not found at position " + strconv.Itoa(pv.Position)) + exitOrPanic(2) + } + } + for _, pv := range sc.PositionalFlags { + if pv.Required && !pv.Found { + p.ShowHelpWithMessage("Required positional of subcommand " + sc.Name + " named " + pv.Name + " not found at position " + strconv.Itoa(pv.Position)) + exitOrPanic(2) + } + } + + return nil +} + +// FlagExists lets you know if the flag name exists as either a short or long +// name in the (sub)command +func (sc *Subcommand) FlagExists(name string) bool { + + for _, f := range sc.Flags { + if f.HasName(name) { + return true + } + } + + return false +} + +// AttachSubcommand adds a possible subcommand to the Parser. +func (sc *Subcommand) AttachSubcommand(newSC *Subcommand, relativePosition int) { + + // assign the depth of the subcommand when its attached + newSC.Position = relativePosition + + // ensure no subcommands at this depth with this name + for _, other := range sc.Subcommands { + if newSC.Position == other.Position { + if newSC.Name != "" { + if newSC.Name == other.Name { + log.Panicln("Unable to add subcommand because one already exists at position" + strconv.Itoa(newSC.Position) + " with name " + other.Name) + } + } + if newSC.ShortName != "" { + if newSC.ShortName == other.ShortName { + log.Panicln("Unable to add subcommand because one already exists at position" + strconv.Itoa(newSC.Position) + " with name " + other.ShortName) + } + } + } + } + + // ensure no positionals at this depth + for _, other := range sc.PositionalFlags { + if newSC.Position == other.Position { + log.Panicln("Unable to add subcommand because a positional value already exists at position " + strconv.Itoa(newSC.Position) + ": " + other.Name) + } + } + + sc.Subcommands = append(sc.Subcommands, newSC) +} + +// add is a "generic" to add flags of any type. Checks the supplied parent +// parser to ensure that the user isn't setting version or help flags that +// conflict with the built-in help and version flag behavior. +func (sc *Subcommand) add(assignmentVar interface{}, shortName string, longName string, description string) { + + // if the flag is already used, throw an error + for _, existingFlag := range sc.Flags { + if longName != "" && existingFlag.LongName == longName { + log.Panicln("Flag " + longName + " added to subcommand " + sc.Name + " but the name is already assigned.") + } + if shortName != "" && existingFlag.ShortName == shortName { + log.Panicln("Flag " + shortName + " added to subcommand " + sc.Name + " but the short name is already assigned.") + } + } + + newFlag := Flag{ + AssignmentVar: assignmentVar, + ShortName: shortName, + LongName: longName, + Description: description, + } + sc.Flags = append(sc.Flags, &newFlag) +} + +// String adds a new string flag +func (sc *Subcommand) String(assignmentVar *string, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// StringSlice adds a new slice of strings flag +// Specify the flag multiple times to fill the slice +func (sc *Subcommand) StringSlice(assignmentVar *[]string, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// Bool adds a new bool flag +func (sc *Subcommand) Bool(assignmentVar *bool, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// BoolSlice adds a new slice of bools flag +// Specify the flag multiple times to fill the slice +func (sc *Subcommand) BoolSlice(assignmentVar *[]bool, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// ByteSlice adds a new slice of bytes flag +// Specify the flag multiple times to fill the slice. Takes hex as input. +func (sc *Subcommand) ByteSlice(assignmentVar *[]byte, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// Duration adds a new time.Duration flag. +// Input format is described in time.ParseDuration(). +// Example values: 1h, 1h50m, 32s +func (sc *Subcommand) Duration(assignmentVar *time.Duration, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// DurationSlice adds a new time.Duration flag. +// Input format is described in time.ParseDuration(). +// Example values: 1h, 1h50m, 32s +// Specify the flag multiple times to fill the slice. +func (sc *Subcommand) DurationSlice(assignmentVar *[]time.Duration, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// Float32 adds a new float32 flag. +func (sc *Subcommand) Float32(assignmentVar *float32, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// Float32Slice adds a new float32 flag. +// Specify the flag multiple times to fill the slice. +func (sc *Subcommand) Float32Slice(assignmentVar *[]float32, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// Float64 adds a new float64 flag. +func (sc *Subcommand) Float64(assignmentVar *float64, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// Float64Slice adds a new float64 flag. +// Specify the flag multiple times to fill the slice. +func (sc *Subcommand) Float64Slice(assignmentVar *[]float64, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// Int adds a new int flag +func (sc *Subcommand) Int(assignmentVar *int, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// IntSlice adds a new int slice flag. +// Specify the flag multiple times to fill the slice. +func (sc *Subcommand) IntSlice(assignmentVar *[]int, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// UInt adds a new uint flag +func (sc *Subcommand) UInt(assignmentVar *uint, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// UIntSlice adds a new uint slice flag. +// Specify the flag multiple times to fill the slice. +func (sc *Subcommand) UIntSlice(assignmentVar *[]uint, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// UInt64 adds a new uint64 flag +func (sc *Subcommand) UInt64(assignmentVar *uint64, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// UInt64Slice adds a new uint64 slice flag. +// Specify the flag multiple times to fill the slice. +func (sc *Subcommand) UInt64Slice(assignmentVar *[]uint64, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// UInt32 adds a new uint32 flag +func (sc *Subcommand) UInt32(assignmentVar *uint32, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// UInt32Slice adds a new uint32 slice flag. +// Specify the flag multiple times to fill the slice. +func (sc *Subcommand) UInt32Slice(assignmentVar *[]uint32, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// UInt16 adds a new uint16 flag +func (sc *Subcommand) UInt16(assignmentVar *uint16, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// UInt16Slice adds a new uint16 slice flag. +// Specify the flag multiple times to fill the slice. +func (sc *Subcommand) UInt16Slice(assignmentVar *[]uint16, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// UInt8 adds a new uint8 flag +func (sc *Subcommand) UInt8(assignmentVar *uint8, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// UInt8Slice adds a new uint8 slice flag. +// Specify the flag multiple times to fill the slice. +func (sc *Subcommand) UInt8Slice(assignmentVar *[]uint8, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// Int64 adds a new int64 flag. +func (sc *Subcommand) Int64(assignmentVar *int64, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// Int64Slice adds a new int64 slice flag. +// Specify the flag multiple times to fill the slice. +func (sc *Subcommand) Int64Slice(assignmentVar *[]int64, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// Int32 adds a new int32 flag +func (sc *Subcommand) Int32(assignmentVar *int32, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// Int32Slice adds a new int32 slice flag. +// Specify the flag multiple times to fill the slice. +func (sc *Subcommand) Int32Slice(assignmentVar *[]int32, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// Int16 adds a new int16 flag +func (sc *Subcommand) Int16(assignmentVar *int16, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// Int16Slice adds a new int16 slice flag. +// Specify the flag multiple times to fill the slice. +func (sc *Subcommand) Int16Slice(assignmentVar *[]int16, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// Int8 adds a new int8 flag +func (sc *Subcommand) Int8(assignmentVar *int8, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// Int8Slice adds a new int8 slice flag. +// Specify the flag multiple times to fill the slice. +func (sc *Subcommand) Int8Slice(assignmentVar *[]int8, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// IP adds a new net.IP flag. +func (sc *Subcommand) IP(assignmentVar *net.IP, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// IPSlice adds a new int8 slice flag. +// Specify the flag multiple times to fill the slice. +func (sc *Subcommand) IPSlice(assignmentVar *[]net.IP, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// HardwareAddr adds a new net.HardwareAddr flag. +func (sc *Subcommand) HardwareAddr(assignmentVar *net.HardwareAddr, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// HardwareAddrSlice adds a new net.HardwareAddr slice flag. +// Specify the flag multiple times to fill the slice. +func (sc *Subcommand) HardwareAddrSlice(assignmentVar *[]net.HardwareAddr, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// IPMask adds a new net.IPMask flag. IPv4 Only. +func (sc *Subcommand) IPMask(assignmentVar *net.IPMask, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// IPMaskSlice adds a new net.HardwareAddr slice flag. IPv4 only. +// Specify the flag multiple times to fill the slice. +func (sc *Subcommand) IPMaskSlice(assignmentVar *[]net.IPMask, shortName string, longName string, description string) { + sc.add(assignmentVar, shortName, longName, description) +} + +// AddPositionalValue adds a positional value to the subcommand. the +// relativePosition starts at 1 and is relative to the subcommand it belongs to +func (sc *Subcommand) AddPositionalValue(assignmentVar *string, name string, relativePosition int, required bool, description string) { + + // ensure no other positionals are at this depth + for _, other := range sc.PositionalFlags { + if relativePosition == other.Position { + log.Panicln("Unable to add positional value because one already exists at position: " + strconv.Itoa(relativePosition)) + } + } + + // ensure no subcommands at this depth + for _, other := range sc.Subcommands { + if relativePosition == other.Position { + log.Panicln("Unable to add positional value a subcommand already exists at position: " + strconv.Itoa(relativePosition)) + } + } + + newPositionalValue := PositionalValue{ + Name: name, + Position: relativePosition, + AssignmentVar: assignmentVar, + Required: required, + Description: description, + } + sc.PositionalFlags = append(sc.PositionalFlags, &newPositionalValue) +} + +// SetValueForKey sets the value for the specified key. If setting a bool +// value, then send "true" or "false" as strings. The returned bool indicates +// that a value was set. +func (sc *Subcommand) SetValueForKey(key string, value string) (bool, error) { + + // debugPrint("Looking to set key", key, "to value", value) + // check for and assign flags that match the key + for _, f := range sc.Flags { + // debugPrint("Evaluating string flag", f.ShortName, "==", key, "||", f.LongName, "==", key) + if f.ShortName == key || f.LongName == key { + // debugPrint("Setting string value for", key, "to", value) + f.identifyAndAssignValue(value) + return true, nil + } + } + + // debugPrint(sc.Name, "was unable to find a key named", key, "to set to value", value) + return false, nil +} + +// ensureNoConflictWithBuiltinHelp ensures that the flags on this subcommand do +// not conflict with the builtin help flags (-h or --help). Exits the program +// if a conflict is found. +func (sc *Subcommand) ensureNoConflictWithBuiltinHelp() { + for _, f := range sc.Flags { + if f.LongName == helpFlagLongName { + sc.exitBecauseOfHelpFlagConflict(f.LongName) + } + if f.LongName == helpFlagShortName { + sc.exitBecauseOfHelpFlagConflict(f.LongName) + } + if f.ShortName == helpFlagLongName { + sc.exitBecauseOfHelpFlagConflict(f.ShortName) + } + if f.ShortName == helpFlagShortName { + sc.exitBecauseOfHelpFlagConflict(f.ShortName) + } + } +} + +// ensureNoConflictWithBuiltinVersion ensures that the flags on this subcommand do +// not conflict with the builtin version flag (--version). Exits the program +// if a conflict is found. +func (sc *Subcommand) ensureNoConflictWithBuiltinVersion() { + for _, f := range sc.Flags { + if f.LongName == versionFlagLongName { + sc.exitBecauseOfVersionFlagConflict(f.LongName) + } + if f.ShortName == versionFlagLongName { + sc.exitBecauseOfVersionFlagConflict(f.ShortName) + } + } +} + +// exitBecauseOfVersionFlagConflict exits the program with a message about how to prevent +// flags being defined from conflicting with the builtin flags. +func (sc *Subcommand) exitBecauseOfVersionFlagConflict(flagName string) { + fmt.Println(`Flag with name '` + flagName + `' conflicts with the internal --version flag in flaggy. + +You must either change the flag's name, or disable flaggy's internal version +flag with 'flaggy.DefaultParser.ShowVersionWithVersionFlag = false'. If you are using +a custom parser, you must instead set '.ShowVersionWithVersionFlag = false' on it.`) + exitOrPanic(1) +} + +// exitBecauseOfHelpFlagConflict exits the program with a message about how to prevent +// flags being defined from conflicting with the builtin flags. +func (sc *Subcommand) exitBecauseOfHelpFlagConflict(flagName string) { + fmt.Println(`Flag with name '` + flagName + `' conflicts with the internal --help or -h flag in flaggy. + +You must either change the flag's name, or disable flaggy's internal help +flag with 'flaggy.DefaultParser.ShowHelpWithHFlag = false'. If you are using +a custom parser, you must instead set '.ShowHelpWithHFlag = false' on it.`) + exitOrPanic(1) +} From d0521c1a85c10e89d02675b4a470a4f27fd4d531 Mon Sep 17 00:00:00 2001 From: Devin Date: Mon, 1 Jul 2019 11:27:20 -0700 Subject: [PATCH 24/26] Updates README.md with a better alias suggestion `ld` is actually a pretty important command-line tool, so overwriting it with the suggested alias is not preferable. `lzd` is just my idea, but really this is just to notify you. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0182b011..df665815 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ go get github.com/jesseduffield/lazydocker Call `lazydocker` in your terminal. I personally use this a lot so I've made an alias for it like so: ``` -echo "alias ld='lazydocker'" >> ~/.zshrc +echo "alias lzd='lazydocker'" >> ~/.zshrc ``` (you can substitute .zshrc for whatever rc file you're using) From 2bbdb9bf6e332b0165e71205ccbb01c54ffc2a1a Mon Sep 17 00:00:00 2001 From: Callum McIntyre Date: Mon, 1 Jul 2019 20:18:39 +0100 Subject: [PATCH 25/26] Add support for -f flag - If passed, passes to docker-compose as -f flag - Supports multiple docker-compose files --- main.go | 4 +++- pkg/config/app_config.go | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index be1e3dd7..9c05b7c8 100644 --- a/main.go +++ b/main.go @@ -23,6 +23,7 @@ var ( configFlag = false debuggingFlag = false + composeFiles []string ) func main() { @@ -33,6 +34,7 @@ func main() { flaggy.Bool(&configFlag, "c", "config", "Print the current default config") flaggy.Bool(&debuggingFlag, "d", "debug", "a boolean") + flaggy.StringSlice(&composeFiles, "f", "file", "Specify alternate compose files") flaggy.SetVersion(fmt.Sprintf("commit=%s, build date=%s, build source=%s, version=%s, os=%s, arch=%s\n", commit, date, buildSource, version, runtime.GOOS, runtime.GOARCH)) flaggy.Parse() @@ -44,7 +46,7 @@ func main() { os.Exit(0) } - appConfig, err := config.NewAppConfig("lazydocker", version, commit, date, buildSource, debuggingFlag) + appConfig, err := config.NewAppConfig("lazydocker", version, commit, date, buildSource, debuggingFlag, composeFiles) if err != nil { log.Fatal(err.Error()) } diff --git a/pkg/config/app_config.go b/pkg/config/app_config.go index cfaa7194..18243b9a 100644 --- a/pkg/config/app_config.go +++ b/pkg/config/app_config.go @@ -16,6 +16,7 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" "time" yaml "github.com/jesseduffield/yaml" @@ -364,7 +365,7 @@ type AppConfig struct { } // NewAppConfig makes a new app config -func NewAppConfig(name, version, commit, date string, buildSource string, debuggingFlag bool) (*AppConfig, error) { +func NewAppConfig(name, version, commit, date string, buildSource string, debuggingFlag bool, composeFiles []string) (*AppConfig, error) { configDir, err := findOrCreateConfigDir(name) if err != nil { return nil, err @@ -375,6 +376,11 @@ func NewAppConfig(name, version, commit, date string, buildSource string, debugg return nil, err } + // Pass compose files as individual -f flags to docker-compose + if len(composeFiles) > 0 { + userConfig.CommandTemplates.DockerCompose += " -f " + strings.Join(composeFiles, " -f ") + } + appConfig := &AppConfig{ Name: name, Version: version, From b2d98a9ff55a03437ecf76a75cd673c9ec8fffcc Mon Sep 17 00:00:00 2001 From: Callum McIntyre Date: Mon, 1 Jul 2019 20:30:25 +0100 Subject: [PATCH 26/26] Add unit tests for NewAppConfig composeFiles --- pkg/config/app_config_test.go | 50 +++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 pkg/config/app_config_test.go diff --git a/pkg/config/app_config_test.go b/pkg/config/app_config_test.go new file mode 100644 index 00000000..bae43e3a --- /dev/null +++ b/pkg/config/app_config_test.go @@ -0,0 +1,50 @@ +package config + +import ( + "testing" +) + +func TestDockerComposeCommandNoFiles(t *testing.T) { + composeFiles := []string{} + conf, err := NewAppConfig("name", "version", "commit", "date", "buildSource", false, composeFiles) + + if err != nil { + t.Fatalf("Unexpected error: %s", err) + } + + actual := conf.UserConfig.CommandTemplates.DockerCompose + expected := "docker-compose" + if actual != expected { + t.Fatalf("Expected %s but got %s", expected, actual) + } +} + +func TestDockerComposeCommandSingleFile(t *testing.T) { + composeFiles := []string{"one.yml"} + conf, err := NewAppConfig("name", "version", "commit", "date", "buildSource", false, composeFiles) + + if err != nil { + t.Fatalf("Unexpected error: %s", err) + } + + actual := conf.UserConfig.CommandTemplates.DockerCompose + expected := "docker-compose -f one.yml" + if actual != expected { + t.Fatalf("Expected %s but got %s", expected, actual) + } +} + +func TestDockerComposeCommandMultipleFiles(t *testing.T) { + composeFiles := []string{"one.yml", "two.yml", "three.yml"} + conf, err := NewAppConfig("name", "version", "commit", "date", "buildSource", false, composeFiles) + + if err != nil { + t.Fatalf("Unexpected error: %s", err) + } + + actual := conf.UserConfig.CommandTemplates.DockerCompose + expected := "docker-compose -f one.yml -f two.yml -f three.yml" + if actual != expected { + t.Fatalf("Expected %s but got %s", expected, actual) + } +}