|
|
@@ -5,6 +5,7 @@ import (
|
|
|
|
"errors"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"os"
|
|
|
|
|
|
|
|
"path"
|
|
|
|
"path/filepath"
|
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
|
@@ -109,14 +110,27 @@ func (m *Model) handleShareFiles(msg shareFilesMsg) tea.Cmd {
|
|
|
|
return nil
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// shareTitle names the action: "Share .env", "Share 2 env files".
|
|
|
|
|
|
|
|
func shareTitle(s sharing) string {
|
|
|
|
|
|
|
|
if len(s.files) == 1 {
|
|
|
|
|
|
|
|
return "Share " + path.Base(s.files[0].Path)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return "Share " + plural(len(s.files), "env file")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// sharedFiles lists the files being shared, under what's happening.
|
|
|
|
|
|
|
|
func (m *Model) sharedFiles(s sharing) []string {
|
|
|
|
|
|
|
|
lines := []string{"Sharing " + plural(len(s.files), "env file") + " as an encrypted link:"}
|
|
|
|
|
|
|
|
for _, f := range s.files {
|
|
|
|
|
|
|
|
lines = append(lines, " "+m.repoLabel(s.repo.Name, f.Path))
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return lines
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// confirmShare says what the link will hold before making it.
|
|
|
|
// confirmShare says what the link will hold before making it.
|
|
|
|
func (m *Model) confirmShare(s sharing) {
|
|
|
|
func (m *Model) confirmShare(s sharing) {
|
|
|
|
lines := []string{m.st.Muted.Render(plural(len(s.files), "env file") + " from " + s.repo.Name + ":")}
|
|
|
|
lines := append(m.sharedFiles(s), "", m.st.Muted.Render("encrypted with ")+m.refLabel(s.key))
|
|
|
|
for _, f := range s.files {
|
|
|
|
m.showMenu(shareTitle(s), lines, []option{
|
|
|
|
lines = append(lines, " "+f.Path)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
lines = append(lines, "", m.st.Muted.Render("encrypted with ")+m.refLabel(s.key))
|
|
|
|
|
|
|
|
m.showMenu("Share as an encrypted link", lines, []option{
|
|
|
|
|
|
|
|
{key: "c", label: "Copy the link", run: func(m *Model) tea.Cmd { return m.seal(s) }},
|
|
|
|
{key: "c", label: "Copy the link", run: func(m *Model) tea.Cmd { return m.seal(s) }},
|
|
|
|
{key: "k", label: "Encrypt with another secret…", run: func(m *Model) tea.Cmd { return m.pickShareKey(s) }},
|
|
|
|
{key: "k", label: "Encrypt with another secret…", run: func(m *Model) tea.Cmd { return m.pickShareKey(s) }},
|
|
|
|
})
|
|
|
|
})
|
|
|
@@ -130,16 +144,10 @@ func (m *Model) pickShareKey(s sharing) tea.Cmd {
|
|
|
|
m.confirmShare(s)
|
|
|
|
m.confirmShare(s)
|
|
|
|
return nil
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m.search.pickTitle = "Encrypt with which secret?"
|
|
|
|
m.search.pickTitle = shareTitle(s)
|
|
|
|
what := s.files[0].Path
|
|
|
|
m.search.pickLines = append(m.sharedFiles(s), "",
|
|
|
|
if len(s.files) > 1 {
|
|
|
|
"Pick the secret to encrypt them with: whoever can read it can open the link.",
|
|
|
|
what = plural(len(s.files), "env file")
|
|
|
|
m.st.Muted.Render("Its value isn't shown or put in the link. share.key sets a default."))
|
|
|
|
}
|
|
|
|
|
|
|
|
m.search.pickLines = []string{
|
|
|
|
|
|
|
|
"Sharing " + what + " from " + s.repo.Name + " as an encrypted link.",
|
|
|
|
|
|
|
|
"Pick the secret to encrypt with: whoever can read it can open the link.",
|
|
|
|
|
|
|
|
m.st.Muted.Render("Its value isn't shown or put in the link. share.key sets a default."),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
m.fillSearch(false)
|
|
|
|
m.fillSearch(false)
|
|
|
|
return tea.Batch(cmd, m.searchLoads())
|
|
|
|
return tea.Batch(cmd, m.searchLoads())
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -213,10 +221,10 @@ func (m *Model) offerShare(r ref.Ref) tea.Cmd {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
from := ""
|
|
|
|
from := ""
|
|
|
|
if s.Repo != "" {
|
|
|
|
if s.Repo != "" {
|
|
|
|
from = " from " + s.Repo
|
|
|
|
from = m.st.Muted.Render(" from ") + m.repoLabel(s.Repo)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m.showMenu("Shared env files", []string{
|
|
|
|
m.showMenu("Shared env files", []string{
|
|
|
|
m.st.Muted.Render(plural(s.Files, "env file") + from),
|
|
|
|
m.st.Muted.Render(plural(s.Files, "env file")) + from,
|
|
|
|
m.st.Muted.Render("encrypted with ") + m.refLabel(s.Key),
|
|
|
|
m.st.Muted.Render("encrypted with ") + m.refLabel(s.Key),
|
|
|
|
}, []option{
|
|
|
|
}, []option{
|
|
|
|
{key: "o", label: "Decrypt them…", tip: "reads the secret, then asks before saving", run: func(m *Model) tea.Cmd { return m.openShare(s) }},
|
|
|
|
{key: "o", label: "Decrypt them…", tip: "reads the secret, then asks before saving", run: func(m *Model) tea.Cmd { return m.openShare(s) }},
|
|
|
@@ -302,10 +310,11 @@ func (m *Model) offerWrite(files []share.File, dir string) {
|
|
|
|
var lines []string
|
|
|
|
var lines []string
|
|
|
|
exist := 0
|
|
|
|
exist := 0
|
|
|
|
for _, t := range targets {
|
|
|
|
for _, t := range targets {
|
|
|
|
line := " " + t.Path + m.st.Muted.Render(" · new")
|
|
|
|
file := " " + m.repoLabel(filepath.Base(dir), t.Path)
|
|
|
|
|
|
|
|
line := file + m.st.Muted.Render(" · new")
|
|
|
|
if t.Exists {
|
|
|
|
if t.Exists {
|
|
|
|
exist++
|
|
|
|
exist++
|
|
|
|
line = " " + t.Path + m.st.Muted.Render(" · replaces the one there")
|
|
|
|
line = file + m.st.Muted.Render(" · replaces the one there")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if t.Exposed {
|
|
|
|
if t.Exposed {
|
|
|
|
line += m.st.Error.Render(" · not ignored by git")
|
|
|
|
line += m.st.Error.Render(" · not ignored by git")
|
|
|
@@ -339,7 +348,7 @@ func (m *Model) offerWrite(files []share.File, dir string) {
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
opts = append(opts,
|
|
|
|
opts = append(opts,
|
|
|
|
option{key: "w", label: fmt.Sprintf("Save all, replacing %d", exist), run: write(false)},
|
|
|
|
option{key: "w", label: fmt.Sprintf("Save all, replacing %d", exist), run: write(false)},
|
|
|
|
option{key: "n", label: "Save only the new " + plural(len(targets)-exist, "file"), run: write(true)},
|
|
|
|
option{key: "n", label: onlyNew(len(targets) - exist), run: write(true)},
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m.showMenu("Save the shared files", lines, opts)
|
|
|
|
m.showMenu("Save the shared files", lines, opts)
|
|
|
@@ -354,3 +363,11 @@ func expandHome(dir string) string {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return dir
|
|
|
|
return dir
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// onlyNew labels saving only the n files not there yet.
|
|
|
|
|
|
|
|
func onlyNew(n int) string {
|
|
|
|
|
|
|
|
if n == 1 {
|
|
|
|
|
|
|
|
return "Save only the new one"
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return fmt.Sprintf("Save only the %d new ones", n)
|
|
|
|
|
|
|
|
}
|