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.
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.
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
diff --git a/Gopkg.lock b/Gopkg.lock
index 5acb6e3d..1117b2bd 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"
@@ -129,14 +137,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 +151,7 @@
name = "github.com/jesseduffield/rollrus"
packages = ["."]
pruneopts = "NUT"
- revision = "7086c0b1b1bd21ef1f502e914ff2505a68c7d638"
+ revision = "dd028cb0bfd75da456151b389d1a32b68cc57360"
[[projects]]
branch = "master"
@@ -327,9 +327,9 @@
"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",
"github.com/jesseduffield/rollrus",
"github.com/jesseduffield/yaml",
"github.com/mcuadros/go-lookup",
diff --git a/README.md b/README.md
index 3dff58cb..dc1dc6aa 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.
[](https://circleci.com/gh/jesseduffield/lazydocker) [](https://goreportcard.com/report/github.com/jesseduffield/lazydocker) [](https://golangci.com) [](http://godoc.org/github.com/jesseduffield/lazydocker) []()
@@ -48,12 +48,24 @@ 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:
```
-echo "alias ld='lazydocker'" >> ~/.zshrc
+echo "alias lzd='lazydocker'" >> ~/.zshrc
```
(you can substitute .zshrc for whatever rc file you're using)
@@ -80,7 +92,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
-[](https://join.slack.com/t/lazydocker/shared_invite/enQtNDE3MjIwNTYyMDA0LTM3Yjk3NzdiYzhhNTA1YjM4Y2M4MWNmNDBkOTI0YTE4YjQ1ZmI2YWRhZTgwNjg2YzhhYjg3NDBlMmQyMTI5N2M)
+[](https://join.slack.com/t/lazydocker/shared_invite/enQtNjgwMjc0Njk3MzgwLTM0NThlMTZiZmNkNWJkY2VlYWYwZmY1NWYyYWViZmE0ZTcxMWZjMTFjNTU1ZTEwMDBiNWIxZTIxYzkwNDgyY2M)
## Donate
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/docs/keybindings/Keybindings_de.md b/docs/keybindings/Keybindings_de.md
new file mode 100644
index 00000000..68b42395
--- /dev/null
+++ b/docs/keybindings/Keybindings_de.md
@@ -0,0 +1,68 @@
+# Lazydocker menu
+
+## Status
+
+
+ e: bearbeite 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
+
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..8de2dfd5 100644
--- a/docs/keybindings/Keybindings_nl.md
+++ b/docs/keybindings/Keybindings_nl.md
@@ -3,67 +3,66 @@
## Status
- e: edit lazydocker config
- o: open lazydocker config
- [: previous tab
- ]: next 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/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/main.go b/main.go
index 7dbadb95..9c05b7c8 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,29 +21,32 @@ 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
+ composeFiles []string
)
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.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()
+
+ if configFlag {
var buf bytes.Buffer
yaml.NewEncoder(&buf).Encode(config.GetDefaultConfig())
fmt.Printf("%v\n", buf.String())
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)
+ appConfig, err := config.NewAppConfig("lazydocker", version, commit, date, buildSource, debuggingFlag, composeFiles)
if err != nil {
log.Fatal(err.Error())
}
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/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
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/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,
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)
+ }
+}
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..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},
@@ -177,10 +171,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
@@ -394,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/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",
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 {
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
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/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/german.go b/pkg/i18n/german.go
new file mode 100644
index 00000000..eb9f605d
--- /dev/null
+++ 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: "scrollen",
+ OpenConfig: "öffne lazydocker Konfiguration",
+ EditConfig: "bearbeite lazydocker Konfiguration",
+ Cancel: "abbrechen",
+ Remove: "entfernen",
+ ForceRemove: "Entfernen erzwingen",
+ RemoveWithVolumes: "entferne mit Volumen",
+ RemoveService: "entferne Container",
+ Stop: "anhalten",
+ 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 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 lazydocker besser zu machen",
+ AnonymousReportingPrompt: "Möchtest du anonymiserte Datensammlung erlauben, um zu helfen lazydocker zu erbessern? (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 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?",
+ 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 lazydocker zurück zu kehren. (Diese Nachfrage kann in Deiner Konfiguration deaktiviert werden, indem du folgenden Wert setzt: `gui.returnImmediately: true`)",
+ }
+}
diff --git a/pkg/i18n/i18n.go b/pkg/i18n/i18n.go
index 3b9a36e4..8d2d21cb 100644
--- a/pkg/i18n/i18n.go
+++ b/pkg/i18n/i18n.go
@@ -31,7 +31,11 @@ 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") {
+ mergo.Merge(&set, germanSet(), mergo.WithOverride)
}
return &set
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)
-}
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)
+}
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
-)