diff --git a/e2etest/setup/setup.go b/e2etest/setup/setup.go
index a2840daf..c47c1eb4 100644
--- a/e2etest/setup/setup.go
+++ b/e2etest/setup/setup.go
@@ -13,7 +13,6 @@ import (
breverrors "github.com/brevdev/brev-cli/pkg/errors"
"github.com/brevdev/brev-cli/pkg/files"
"github.com/brevdev/brev-cli/pkg/store"
- "github.com/hashicorp/go-multierror"
"github.com/stretchr/testify/assert"
)
@@ -106,20 +105,6 @@ func NewWorkspaceTestClient(setupParams *store.SetupParamsV0, containerParams []
}
}
-func (w WorkspaceTestClient) Done() error {
- var allError error
- for _, w := range w.TestWorkspaces {
- err := w.Done()
- if err != nil {
- allError = multierror.Append(allError, err)
- }
- }
- if allError != nil {
- return breverrors.WrapAndTrace(allError)
- }
- return nil
-}
-
type workspaceTest func(workspace Workspace, err error)
func (w WorkspaceTestClient) Test(test workspaceTest) error {
@@ -482,12 +467,6 @@ func AssertPathExists(t *testing.T, workspace Workspace, path string) bool {
return assert.Nil(t, err)
}
-func AssertPathNotExist(t *testing.T, workspace Workspace, path string) bool {
- t.Helper()
- _, err := workspace.Exec("ls", path)
- return assert.NotNil(t, err)
-}
-
func AssertPathDoesNotExist(t *testing.T, workspace Workspace, path string) bool {
t.Helper()
_, err := workspace.Exec("ls", path)
@@ -520,13 +499,6 @@ func AssertDockerRunning(t *testing.T, w Workspace) bool {
return strings.Contains(string(out), "active")
}
-func AssertRepoHasNumFiles(t *testing.T, w Workspace, filePath string, num int) {
- t.Helper()
- out, err := w.Exec("ls", "-a", filePath)
- assert.Nil(t, err)
- assert.Len(t, strings.Fields(string(out)), num)
-}
-
func UpdateFile(w Workspace, filePath string, content string) error {
_, err := w.Exec("sh", "-c", fmt.Sprintf(`echo '%s' > %s`, content, filePath))
if err != nil {
diff --git a/pkg/auth/auth.go b/pkg/auth/auth.go
index b7d4c674..2363c896 100644
--- a/pkg/auth/auth.go
+++ b/pkg/auth/auth.go
@@ -320,7 +320,3 @@ func isAccessTokenValid(token string) (bool, error) {
}
return true, nil
}
-
-func IsAuthError(err error) bool {
- return strings.Contains(err.Error(), "403")
-}
diff --git a/pkg/auth/auth0.go b/pkg/auth/auth0.go
index 600471c9..21b9a9b6 100644
--- a/pkg/auth/auth0.go
+++ b/pkg/auth/auth0.go
@@ -70,18 +70,8 @@ type State struct {
}
// RequiredScopes returns the scopes used for login.
-func RequiredScopes() []string { return requiredScopes }
// RequiredScopesMin returns minimum scopes used for login in integration tests.
-func RequiredScopesMin() []string {
- min := []string{}
- for _, s := range requiredScopes {
- if s != "offline_access" && s != "openid" {
- min = append(min, s)
- }
- }
- return min
-}
func (s *State) IntervalDuration() time.Duration {
return time.Duration(s.Interval+waitThresholdInSeconds) * time.Second
diff --git a/pkg/autostartconf/autostartconf.go b/pkg/autostartconf/autostartconf.go
index db1f1a8f..eff094f2 100644
--- a/pkg/autostartconf/autostartconf.go
+++ b/pkg/autostartconf/autostartconf.go
@@ -44,127 +44,6 @@ func firstAndRest(commandstring []string) (string, []string) {
return first, rest
}
-func NewVPNConfig(store AutoStartStore) DaemonConfigurer {
- switch runtime.GOOS {
- case osLinux:
- return LinuxSystemdConfigurer{
- Store: store,
- ValueConfigFile: `
-[Install]
-WantedBy=multi-user.target
-
-[Unit]
-Description=Brev vpn daemon
-After=systemd-user-sessions.service
-
-[Service]
-Type=simple
-ExecStart=brev tasks run vpnd
-Restart=always
-`,
- ServiceName: "brevvpnd.service",
- ServiceType: "system",
- TargetBin: targetBin,
- }
- case osDarwin:
- return DarwinPlistConfigurer{
- Store: store,
- ValueConfigFile: `
-
-
-
-
-
- Label
- com.brev.vpnd
-
- ProgramArguments
-
- /usr/local/bin/brev
- tasks
- run
- vpnd
-
-
- RunAtLoad
-
-
- StandardOutPath
- /var/log/brevvpnd.log
- StandardErrorPath
- /var/log/brevvpnd.log
-
-
-
- `,
- ServiceName: "com.brev.vpnd",
- ServiceType: System,
- }
- }
- return nil
-}
-
-func NewRPCConfig(store AutoStartStore) DaemonConfigurer {
- switch runtime.GOOS {
- case osLinux:
- return LinuxSystemdConfigurer{
- Store: store,
- ValueConfigFile: `
-[Install]
-WantedBy=multi-user.target
-
-[Unit]
-Description=Brev rpc daemon
-After=systemd-user-sessions.service
-
-[Service]
-Type=simple
-ExecStart=brev tasks run rpcd --user ` + store.GetOSUser() + `
-Restart=always
-`,
- ServiceName: "brevrpcd.service",
- ServiceType: "system",
- }
- case osDarwin:
- return DarwinPlistConfigurer{
- Store: store,
- ValueConfigFile: `
-
-
-
-
-
- Label
- com.brev.rpcd
-
- ProgramArguments
-
- /usr/local/bin/brev
- tasks
- run
- rpcd
- --user
- ` + store.GetOSUser() + `
-
-
- RunAtLoad
-
-
- StandardOutPath
- /var/log/brevrpcd.log
- StandardErrorPath
- /var/log/brevrpcd.log
-
-
-
- `,
- ServiceName: "com.brev.rpcd",
- ServiceType: System,
- }
- }
- return nil
-}
-
// func NewDaemonConfiguration(user string, command string, serviceName string, serviceType string) DaemonConfigurer {
// switch runtime.GOOS {
// case osLinux:
diff --git a/pkg/autostartconf/staticbinary.go b/pkg/autostartconf/staticbinary.go
index f48a6778..19ecc7db 100644
--- a/pkg/autostartconf/staticbinary.go
+++ b/pkg/autostartconf/staticbinary.go
@@ -1,48 +1,11 @@
package autostartconf
-import (
- "path/filepath"
-
- breverrors "github.com/brevdev/brev-cli/pkg/errors"
-)
-
type StaticBinaryConfigurer struct {
LinuxSystemdConfigurer
URL string
Name string
}
-func (sbc StaticBinaryConfigurer) Install() error {
- _ = sbc.UnInstall() // best effort
-
- // download binary
- err := sbc.Store.DownloadBinary(
- sbc.URL,
- filepath.Join("/usr/local/bin", sbc.Name),
- )
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
+// best effort
- err = sbc.Store.WriteString(sbc.getDestConfigFile(), sbc.ValueConfigFile)
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
-
- if ShouldSymlink() {
- errother := sbc.CreateForcedSymlink()
- if errother != nil {
- return breverrors.WrapAndTrace(errother)
- }
- } else {
- errother := ExecCommands([][]string{
- {"systemctl", "enable", sbc.ServiceName},
- {"systemctl", "start", sbc.ServiceName},
- {"systemctl", "daemon-reload"},
- })
- if errother != nil {
- return breverrors.WrapAndTrace(errother)
- }
- }
- return nil
-}
+// download binary
diff --git a/pkg/cmd/cmderrors/cmderrors.go b/pkg/cmd/cmderrors/cmderrors.go
index c13f94e6..0d6aa3e2 100644
--- a/pkg/cmd/cmderrors/cmderrors.go
+++ b/pkg/cmd/cmderrors/cmderrors.go
@@ -15,24 +15,8 @@ import (
)
// determines if should print error stack trace and/or send to crash monitor
-func DisplayAndHandleCmdError(name string, cmdFunc func() error) error {
- er := breverrors.GetDefaultErrorReporter()
- er.AddTag("command", name)
- err := cmdFunc()
- if err != nil {
- er.AddBreadCrumb(breverrors.ErrReportBreadCrumb{
- Type: "err",
- Message: err.Error(),
- })
- er.ReportError(err)
- if featureflag.Debug() || featureflag.IsDev() {
- return err
- } else {
- return errors.Cause(err) //nolint:wrapcheck //no check
- }
- }
- return nil
-}
+
+//nolint:wrapcheck //no check
func DisplayAndHandleError(err error) {
er := breverrors.GetDefaultErrorReporter()
diff --git a/pkg/cmd/hello/onboarding_utils.go b/pkg/cmd/hello/onboarding_utils.go
index ab773f67..7ea80b2f 100644
--- a/pkg/cmd/hello/onboarding_utils.go
+++ b/pkg/cmd/hello/onboarding_utils.go
@@ -200,31 +200,13 @@ func SetOnboardingObject(oo OnboardingObject) error {
return nil
}
-func SetOnboardingStep(step int) error {
- // get path
- path, err := GetOnboardingFilePath()
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
+// get path
- // Ensure file exists
- err = SetupDefaultOnboardingFile()
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
+// Ensure file exists
- // write file
- oo := OnboardingObject{
- Step: step,
- }
- err = files.OverwriteJSON(files.AppFs, path, &oo)
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
+// write file
- // return data
- return nil
-}
+// return data
func SetHasRunShell(hasRunShell bool) error {
// get path
@@ -287,8 +269,3 @@ func SetHasRunOpen(hasRunOpen bool) error {
// return data
return nil
}
-
-func Poll() {
- s := "Got it."
- TypeItToMe(s)
-}
diff --git a/pkg/cmd/login/login.go b/pkg/cmd/login/login.go
index 98a7dd0c..61b6c9f0 100644
--- a/pkg/cmd/login/login.go
+++ b/pkg/cmd/login/login.go
@@ -2,11 +2,9 @@
package login
import (
- "bufio"
"fmt"
"os"
"os/exec"
- "path/filepath"
"strings"
"github.com/brevdev/brev-cli/pkg/auth"
@@ -283,50 +281,11 @@ func CreateNewUser(loginStore LoginStore, idToken string) (bool, error) {
return true, nil
}
-func OnboardUserWithSSHKeys(t *terminal.Terminal, user *entity.User, _ LoginStore, firstLoop bool) error {
- if firstLoop {
- t.Vprint(t.Yellow("\n\nYou must add your SSH key to pull and push from your repos.\n"))
- } else {
- t.Vprint(t.Red("\n\nYou must add your SSH key to pull and push from your repos.\n"))
- }
- // SSH Keys
- _ = terminal.PromptGetInput(terminal.PromptContent{
- Label: "🔒 Click enter to get your secure SSH key:",
- ErrorMsg: "error",
- AllowEmpty: true,
- })
-
- t.Vprintf("\n" + user.PublicKey + "\n\n")
-
- _ = terminal.PromptGetInput(terminal.PromptContent{
- Label: "Copy your public key 👆 then hit enter",
- ErrorMsg: "error",
- AllowEmpty: true,
- })
+// SSH Keys
- fmt.Print("\n")
-
- t.Vprint(t.Green("Add the key to your git repo provider"))
- t.Vprint(t.Green("\tClick here if you use Github 👉 https://github.com/settings/ssh/new\n\n"))
- // t.Eprintf(t.Yellow("\n\tClick here for Gitlab: https://gitlab.com/-/profile/keys\n"))
-
- isFin := terminal.PromptSelectInput(terminal.PromptSelectContent{
- Label: "Did you finish adding your SSH key?",
- Items: []string{"Yes", "No"},
- ErrorMsg: "error",
- })
- if isFin == "Yes" {
- return nil
- } else {
- // t.Vprint(t.Red("\nYou must add your SSH key to pull and push from your repos. "))
- err := OnboardUserWithSSHKeys(t, user, nil, false)
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
- }
+// t.Eprintf(t.Yellow("\n\tClick here for Gitlab: https://gitlab.com/-/profile/keys\n"))
- return nil
-}
+// t.Vprint(t.Red("\nYou must add your SSH key to pull and push from your repos. "))
func OnboardUserWithEditors(t *terminal.Terminal, _ LoginStore, ide string) (string, error) {
if ide == "VSCode" {
@@ -381,115 +340,17 @@ func (o LoginOptions) showBreadCrumbs(t *terminal.Terminal, org *entity.Organiza
return nil
}
-func CheckAndInstallGateway(t *terminal.Terminal, store LoginStore) error {
- localOS := terminal.PromptSelectInput(terminal.PromptSelectContent{
- Label: "Which operating system does your local computer have?",
- ErrorMsg: "error",
- Items: []string{"Mac OS (Intel)", "Mac OS (M1 Chip)", "Linux"},
- })
-
- home, err := store.UserHomeDir()
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
-
- jetBrainsDirectory, installScript, err := CreateDownloadPathAndInstallScript(localOS, home)
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
-
- t.Print("Searching for JetBrains Gateway...")
- t.Print("")
-
- // Check if Gateway is already installed
- gatewayInstalled := IsGatewayInstalled(jetBrainsDirectory)
- if gatewayInstalled {
- terminal.DisplayGatewayAlreadyInstalledInstructions(t)
- return nil
- }
+// Check if Gateway is already installed
- // Check if Toolbox is already installed
- toolboxInstalled, gatewayInToolboxInstalled := IsToolboxInstalled(jetBrainsDirectory)
- if gatewayInToolboxInstalled {
- terminal.DisplayGatewayAlreadyInstalledInstructions(t)
- return nil
- }
-
- if toolboxInstalled {
- terminal.DisplayToolboxInstalledInstructions(t)
- return nil
- }
-
- InstallGateway(installScript, t)
- return nil
-}
+// Check if Toolbox is already installed
-func IsToolboxInstalled(jetBrainsBaseDirectory string) (toolboxInstalled bool, gatewayInToolboxInstalled bool) {
- _, err := os.Stat(jetBrainsBaseDirectory + `/Toolbox`)
- if !os.IsNotExist(err) {
- // Check if Gateway is already installed in Toolbox
- _, err = os.Stat(jetBrainsBaseDirectory + `/Toolbox/apps/JetBrainsGateway`)
- return true, !os.IsNotExist(err)
- }
- return false, false
-}
+// Check if Gateway is already installed in Toolbox
-func IsGatewayInstalled(jetBrainsBaseDirectory string) bool {
- matches, _ := filepath.Glob(jetBrainsBaseDirectory + `/JetBrainsGateway*`)
- return len(matches) > 0
-}
+// n
-func InstallGateway(installScript string, t *terminal.Terminal) {
- reader := bufio.NewReader(os.Stdin)
- t.Print("You will need to install JetBrains Gateway to use JetBrains IDEs.")
- t.Print(`Would you like to install JetBrains Gateway? [y/n]: `)
- text, _ := reader.ReadString('\n')
- if strings.Compare(text, "y") != 1 {
- // n
- t.Print("")
- t.Print(t.Yellow("Click here to install manually: "))
- t.Print("https://www.jetbrains.com/remote-development/gateway")
- t.Print("")
- } else {
- // y
- spinner := t.NewSpinner()
- spinner.Suffix = " Installing JetBrains Gateway..."
- spinner.Start()
- // #nosec
- cmd := exec.Command("/bin/sh", "-c", installScript)
- _, err := cmd.Output()
- spinner.Stop()
- if err != nil {
- t.Errprint(err, "Error installing JetBrains Gateway")
- t.Print("")
- t.Print(t.Yellow("Click here to install manually: "))
- t.Print("https://www.jetbrains.com/remote-development/gateway")
- t.Print("")
- } else {
- t.Print("")
- t.Print("")
- t.Print(t.Yellow("JetBrains Gateway successfully installed!"))
- t.Print("")
- t.Print("Run " + t.Green("brev jetbrains") + " and then open Gateway to begin.")
- t.Print("")
- }
- }
-}
+// y
-func CreateDownloadPathAndInstallScript(localOS string, homeDirectory string) (jetBrainsDirectory string, installScript string, err error) {
- switch localOS {
- case "Mac OS (Intel)":
- jetBrainsDirectory = homeDirectory + `/Library/Application Support/JetBrains`
- installScript = `set -e; echo "Start installation..."; curl "https://data.services.jetbrains.com/products/download?code=GW&platform=macM1&type=eap,rc,release,beta" --output ./gateway.dmg -L; hdiutil attach gateway.dmg; cp -R "/Volumes/JetBrains Gateway/JetBrains Gateway.app" /Applications; hdiutil unmount "/Volumes/JetBrains Gateway"; rm ./gateway.dmg; echo "JetBrains Gateway successfully installed"`
- case "Mac OS (M1 Chip)":
- jetBrainsDirectory = homeDirectory + `/Library/Application Support/JetBrains`
- installScript = `set -e; echo "Start installation..."; curl "https://data.services.jetbrains.com/products/download?code=GW&platform=macM1&type=eap,rc,release,beta" --output ./gateway.dmg -L; hdiutil attach gateway.dmg; cp -R "/Volumes/JetBrains Gateway/JetBrains Gateway.app" /Applications; hdiutil unmount "/Volumes/JetBrains Gateway"; rm ./gateway.dmg; echo "JetBrains Gateway successfully installed"`
- case "Linux":
- jetBrainsDirectory = homeDirectory + `/.local/share/JetBrains`
- installScript = `set -e; echo "Start installation..."; wget --show-progress -qO ./gateway.tar.gz "https://data.services.jetbrains.com/products/download?code=GW&platform=linux&type=eap,rc,release,beta"; GATEWAY_TEMP_DIR=$(mktemp -d); tar -C "$GATEWAY_TEMP_DIR" -xf gateway.tar.gz; rm ./gateway.tar.gz; "$GATEWAY_TEMP_DIR"/*/bin/gateway.sh; rm -r "$GATEWAY_TEMP_DIR"; echo "JetBrains Gateway was successfully installed";`
- }
- return jetBrainsDirectory, installScript, nil
-}
+// #nosec
func makeFirstOrgName(username string) string {
return fmt.Sprintf("%s-hq", username)
diff --git a/pkg/cmd/ls/ls.go b/pkg/cmd/ls/ls.go
index ae1e3528..e4324c10 100644
--- a/pkg/cmd/ls/ls.go
+++ b/pkg/cmd/ls/ls.go
@@ -336,27 +336,6 @@ func (ls Ls) displayWorkspacesAndHelp(org *entity.Organization, otherOrgs []enti
}
}
-func DisplayLsConnectBreadCrumb(t *terminal.Terminal, workspaces []entity.Workspace) {
- foundRunning := false
- for _, w := range workspaces {
- if w.Status == entity.Running {
- foundRunning = true
- t.Vprintf(t.Green("Connect to running instance:\n"))
- t.Vprintf(t.Yellow(fmt.Sprintf("\tbrev open %s\t# brev open -> open instance in preferred editor\n", w.Name)))
- t.Vprintf(t.Yellow(fmt.Sprintf("\tbrev shell %s\t# brev shell -> ssh into instance (shortcut)\n", w.Name)))
- t.Vprintf(t.Yellow(fmt.Sprintf("\tssh %s\t# ssh -> ssh directly to instance\n", w.GetLocalIdentifier())))
- if enableSSHCol {
- t.Vprintf(t.Yellow("\tssh ex: ssh %s\n", w.GetLocalIdentifier()))
- }
- break
- }
- }
- if !foundRunning && len(workspaces) > 0 {
- t.Vprintf(t.Green("Start a stopped instance:\n"))
- t.Vprintf(t.Yellow("\tbrev start %s # brev start -> start stopped instance\n", workspaces[0].Name))
- }
-}
-
func displayLsResetBreadCrumb(t *terminal.Terminal, workspaces []entity.Workspace) {
foundAResettableWorkspace := false
for _, w := range workspaces {
diff --git a/pkg/cmd/paths/paths.go b/pkg/cmd/paths/paths.go
index b68bdfb0..e1e69f4c 100644
--- a/pkg/cmd/paths/paths.go
+++ b/pkg/cmd/paths/paths.go
@@ -3,32 +3,9 @@ package paths
import (
"fmt"
"io/ioutil"
- "strings"
-
- "github.com/brevdev/brev-cli/pkg/terminal"
- "github.com/spf13/cobra"
// breverrors "github.com/brevdev/brev-cli/pkg/errors"
)
-func NewCmdApprove(_ *terminal.Terminal) *cobra.Command {
- cmd := &cobra.Command{
- Annotations: map[string]string{},
- Use: "paths",
- RunE: func(cmd *cobra.Command, args []string) error {
- paths := GetPaths()
- fmt.Println(paths)
- return nil
- },
- }
-
- return cmd
-}
-
-func GetPaths() string {
- vscodePaths := GetVsCodePaths()
- return strings.Join(vscodePaths, ":")
-}
-
func GetVsCodePaths() []string {
fi, err := ioutil.ReadDir("/home/brev/.vscode-server/bin")
if err != nil {
diff --git a/pkg/cmd/stop/stop.go b/pkg/cmd/stop/stop.go
index e08ce1a1..e746e849 100644
--- a/pkg/cmd/stop/stop.go
+++ b/pkg/cmd/stop/stop.go
@@ -146,18 +146,6 @@ func stopWorkspace(workspaceName string, t *terminal.Terminal, stopStore StopSto
return nil
}
-func StopThisWorkspace(store StopStore, _ *terminal.Terminal) error {
- isWorkspace, err := store.IsWorkspace()
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
- if isWorkspace {
- _ = 0
- // get current workspace
- // stopWorkspace("")
- // stop the workspace
- } else {
- return breverrors.NewValidationError("this is not a workspace -- please provide a workspace id")
- }
- return nil
-}
+// get current workspace
+// stopWorkspace("")
+// stop the workspace
diff --git a/pkg/cmd/tasks/tasks.go b/pkg/cmd/tasks/tasks.go
index 1103355f..1b0af8e7 100644
--- a/pkg/cmd/tasks/tasks.go
+++ b/pkg/cmd/tasks/tasks.go
@@ -117,10 +117,6 @@ func NewCmdRun(_ *terminal.Terminal, _ TaskStore, taskMap TaskMap) *cobra.Comman
return cmd
}
-func Tasks(_ *terminal.Terminal, _ TaskStore, _ TaskMap) error {
- return nil
-}
-
func getTaskMap(store TaskStore) TaskMap {
taskmap := make(TaskMap)
sshcd := ssh.NewSSHConfigurerTask(store)
diff --git a/pkg/cmd/textceo/textceo.go b/pkg/cmd/textceo/textceo.go
index dfd66bfa..638fbe85 100644
--- a/pkg/cmd/textceo/textceo.go
+++ b/pkg/cmd/textceo/textceo.go
@@ -4,9 +4,6 @@ import (
"github.com/brevdev/brev-cli/pkg/cmd/completions"
"github.com/brevdev/brev-cli/pkg/entity"
"github.com/brevdev/brev-cli/pkg/store"
- "github.com/brevdev/brev-cli/pkg/terminal"
-
- "github.com/spf13/cobra"
)
var (
@@ -25,21 +22,5 @@ type TextCEOStore interface {
GetWorkspaceMetaData(workspaceID string) (*entity.WorkspaceMetaData, error)
}
-func NewCmdTextCEO(t *terminal.Terminal, _ TextCEOStore) *cobra.Command {
- cmd := &cobra.Command{
- Annotations: map[string]string{"housekeeping": ""},
- Use: "test",
- DisableFlagsInUseLine: true,
- Short: "Send a text message to our CEO, Nader",
- Long: startLong,
- Example: startExample,
- Run: func(cmd *cobra.Command, args []string) {
- t.Vprint("\ntest cmd\n")
- },
- }
-
- // cmd.Flags().StringVarP(&message, "message", "m", "", "message to send Brev's CEO, Nader")
- // cmd.Flags().StringVarP(&message, "phone", "p", "", "(Optional) leave a number for Nader to follow up")
-
- return cmd
-}
+// cmd.Flags().StringVarP(&message, "message", "m", "", "message to send Brev's CEO, Nader")
+// cmd.Flags().StringVarP(&message, "phone", "p", "", "(Optional) leave a number for Nader to follow up")
diff --git a/pkg/cmd/util/util.go b/pkg/cmd/util/util.go
index 223364d9..88855168 100644
--- a/pkg/cmd/util/util.go
+++ b/pkg/cmd/util/util.go
@@ -64,18 +64,6 @@ type MakeWorkspaceWithMetaStore interface {
GetWorkspaceMetaData(workspaceID string) (*entity.WorkspaceMetaData, error)
}
-func MakeWorkspaceWithMeta(store MakeWorkspaceWithMetaStore, workspace *entity.Workspace) (entity.WorkspaceWithMeta, error) {
- workspaceMetaData, err := store.GetWorkspaceMetaData(workspace.ID)
- if err != nil {
- return entity.WorkspaceWithMeta{}, breverrors.WrapAndTrace(err)
- }
-
- return entity.WorkspaceWithMeta{
- WorkspaceMetaData: *workspaceMetaData,
- Workspace: *workspace,
- }, nil
-}
-
func GetClassIDString(classID string) string {
// switch statement on class ID
switch classID {
diff --git a/pkg/cmdcontext/cmdwriter.go b/pkg/cmdcontext/cmdwriter.go
index 56009f9f..80ef4386 100644
--- a/pkg/cmdcontext/cmdwriter.go
+++ b/pkg/cmdcontext/cmdwriter.go
@@ -3,7 +3,3 @@ package cmdcontext
// NoopWriter is an implementation of the standard Writer which takes no action
// upon being asked to write.
type NoopWriter struct{}
-
-func (w NoopWriter) Write(_ []byte) (n int, err error) {
- return 0, nil
-}
diff --git a/pkg/collections/collections.go b/pkg/collections/collections.go
index bf159ff5..9f094ae1 100644
--- a/pkg/collections/collections.go
+++ b/pkg/collections/collections.go
@@ -1,29 +1,14 @@
package collections
import (
- "bytes"
"context"
- "encoding/base64"
- "encoding/json"
- "fmt"
- "math"
"net/http"
- "reflect"
- "runtime"
- "runtime/debug"
"sort"
- "strings"
"sync"
- "testing"
"time"
"github.com/brevdev/brev-cli/pkg/errors"
- "github.com/cenkalti/backoff/v4"
"github.com/jinzhu/copier"
- "github.com/mitchellh/mapstructure"
- "golang.org/x/exp/constraints"
- "google.golang.org/protobuf/encoding/protojson"
- "google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/timestamppb"
)
@@ -45,47 +30,19 @@ func GetRequestWithContext(ctx context.Context, url string) (*http.Response, err
return resp, nil
}
-func Foldr[T any, R any](fn func(next T, carry R) R, base R, list []T) R {
- for idx := len(list) - 1; idx >= 0; idx-- {
- base = fn(list[idx], base)
- }
-
- return base
-}
-
-func Fmap[T any, R any](fn func(some T) R, list []T) []R {
+func Fmap[T, R any](fn func(some T) R, list []T) []R {
return Foldl(func(acc []R, next T) []R {
return append(acc, fn(next))
}, []R{}, list)
}
-// there is no function overloading [and the need to describe dependent relations between the types of the functions rules out variadic arguments]
-// so we will define c2, c3, c4, and c5 which will allow simple composition of up to 5 functions
-// anything more than that should be refactored so that subcomponents of the composition are renamed, anyway (or named itself)
-
-func Compose[T any, S any, R any](fn1 func(some S) R, fn2 func(some T) S) func(some T) R {
+func Compose[T, S, R any](fn1 func(some S) R, fn2 func(some T) S) func(some T) R {
return func(some T) R {
return fn1(fn2(some))
}
}
-func C2[T any, S any, R any](fn1 func(some S) R, fn2 func(some T) S) func(some T) R {
- return Compose(fn1, fn2)
-}
-
-func C3[T any, S any, R any, U any](fn0 func(some R) U, fn1 func(some S) R, fn2 func(some T) S) func(some T) U {
- return func(some T) U {
- return fn0(fn1(fn2(some)))
- }
-}
-
-func C4[T any, S any, R any, U any, V any](fn01 func(some U) V, fn0 func(some R) U, fn1 func(some S) R, fn2 func(some T) S) func(some T) V {
- return func(some T) V {
- return fn01(fn0(fn1(fn2(some))))
- }
-}
-
-func C5[T any, S any, R any, U any, V any, W any](fn02 func(some V) W, fn01 func(some U) V, fn0 func(some R) U, fn1 func(some S) R, fn2 func(some T) S) func(some T) W {
+func C5[T, S, R, U, V, W any](fn02 func(some V) W, fn01 func(some U) V, fn0 func(some R) U, fn1 func(some S) R, fn2 func(some T) S) func(some T) W {
return func(some T) W {
return fn02(fn01(fn0(fn1(fn2(some)))))
}
@@ -95,21 +52,17 @@ func ID[T any](x T) T {
return x
}
-func C[T any](fns ...func(some T) T) func(some T) T {
- return Foldr(Compose[T, T, T], ID[T], fns)
-}
-
func S[T any](fns ...func(some T) T) func(some T) T {
return Foldl(Compose[T, T, T], ID[T], fns)
}
-func P2[X any, Y any, Z any](fn func(X, Y) Z, x X) func(Y) Z {
+func P2[X, Y, Z any](fn func(X, Y) Z, x X) func(Y) Z {
return func(y Y) Z {
return fn(x, y)
}
}
-func Flip[X any, Y any, Z any](fn func(X, Y) Z) func(Y, X) Z {
+func Flip[X, Y, Z any](fn func(X, Y) Z) func(Y, X) Z {
return func(y Y, x X) Z {
return fn(x, y)
}
@@ -122,25 +75,7 @@ func First[X any](list []X) *X {
return nil
}
-func Cons[X any](x X, list []X) []X {
- return Concat([]X{x}, list)
-}
-
-func Enconcat[X any](before []X, x X, after []X) []X {
- return Concat(before, Cons(x, after))
-}
-
-func Any[T any](f func(T) bool, list []T) {
- Foldl(func(acc bool, el T) bool {
- if acc {
- return acc
- } else {
- return f(el)
- }
- }, false, list)
-}
-
-func Fanout[T any, R any](fs []func(T) R, item T) []R {
+func Fanout[T, R any](fs []func(T) R, item T) []R {
return Fmap(func(f func(T) R) R {
return f(item)
}, fs)
@@ -169,7 +104,7 @@ func ToDict[T comparable](xs []T) map[T]bool {
}, map[T]bool{}, xs)
}
-func Difference[T comparable](from []T, remove []T) []T {
+func Difference[T comparable](from, remove []T) []T {
returnval := Foldl(func(acc maplist[T], el T) maplist[T] {
if _, ok := acc.Map[el]; !ok {
acc.Map[el] = true
@@ -180,7 +115,7 @@ func Difference[T comparable](from []T, remove []T) []T {
return returnval.List
}
-func DictMerge[K comparable, V any](left map[K]V, right map[K]V) map[K]V {
+func DictMerge[K comparable, V any](left, right map[K]V) map[K]V {
newMap := map[K]V{}
for key, val := range left {
if _, ok := right[key]; ok {
@@ -222,33 +157,11 @@ func Contains[T comparable](s []T, e T) bool {
return false
}
-func MapContainsKey[K comparable, V any](m map[K]V, key K) bool {
- _, ok := m[key]
- return ok
-}
-
-func ValueOrZero[T any](ptr *T) T {
- if ptr == nil {
- res, _ := reflect.Zero(reflect.TypeOf(ptr)).Interface().(T)
- return res
- } else {
- return *ptr
- }
-}
-
-func MapFromList[T any, R comparable](list []T, keySelector func(l T) R) map[R]T {
- result := map[R]T{}
- for _, item := range list {
- result[keySelector(item)] = item
+func Foldl[T any, R any](fn func(acc R, next T) R, base R, list []T) R {
+ for _, value := range list {
+ base = fn(base, value)
}
- return result
-}
-
-// Await blocks until the asynchronous operation completes, returning the result and error.
-func Except[T comparable](items []T, except []T) []T {
- return Filter(items, func(item T) bool {
- return !ListContains(except, item)
- })
+ return base
}
// loops over list and returns when has returns true
@@ -260,459 +173,23 @@ func ListHas[K any](list []K, has func(l K) bool) bool {
return false
}
-func MapHasKey[K comparable, V any](m map[K]V, key K) bool {
- _, ok := m[key]
- return ok
-}
-
func ListContains[K comparable](list []K, item K) bool {
return ListHas(list, func(l K) bool { return l == item })
}
-func ManyIntegersToInts[T constraints.Integer](i []T) []int {
- return Map(i, func(i T) int { return int(i) })
-}
-
-func ManyStringLikeToStrings[T ~string](i []T) []string {
- return Map(i, func(i T) string { return string(i) })
-}
-
-// map over a go map
-func MapMap[K comparable, V any, R any](m map[K]V, f func(K, V) R) []R {
- results := []R{}
- for k, v := range m {
- r := f(k, v)
- results = append(results, r)
- }
- return results
-}
-
-func MapMapE[K comparable, V any, R any](m map[K]V, f func(K, V) (R, error)) ([]R, error) {
- results := []R{}
- for k, v := range m {
- r, e := f(k, v)
- if e != nil {
- return nil, e
- }
- results = append(results, r)
- }
- return results, nil
-}
-
-// map over a go map and return a map, merge the maps
-func MapMapMerge[K1 comparable, V1 any, K2 comparable, V2 any](m map[K1]V1, f func(K1, V1) map[K2]V2) map[K2]V2 {
- return MergeMaps(MapMap(m, f)...)
-}
-
-func MapE[T, R any](items []T, mapper func(T) (R, error)) ([]R, error) {
- results := []R{}
- for _, item := range items {
- res, err := mapper(item)
- if err != nil {
- return results, errors.WrapAndTrace(err)
- }
- results = append(results, res)
- }
- return results, nil
-}
-
-func ParallelMapE[T, R any](items []T, mapper func(T) (R, error)) ([]R, error) {
- return ParallelWorkerMapE(items, mapper, 100)
-}
-
-func AccumulateMap[A any, K comparable, V any](m map[K]V, accumulator func(A, K, V) A) A {
- var result A
- for k, v := range m {
- result = accumulator(result, k, v)
- }
- return result
-}
-
-func Accumulate[A any, T any](items []T, accumulator func(A, T) A) A {
- var result A
- for _, item := range items {
- result = accumulator(result, item)
- }
- return result
-}
-
-func AccumulateE[A any, T any](items []T, accumulator func(A, T) (A, error)) (A, error) {
- var result A
- for _, item := range items {
- var err error
- result, err = accumulator(result, item)
- if err != nil {
- var zero A
- return zero, errors.WrapAndTrace(err)
- }
- }
- return result, nil
-}
-
-func Flatten[T any](listOfLists [][]T) []T {
- result := []T{}
- for _, list := range listOfLists {
- result = append(result, list...)
- }
- return result
-}
-
-func Foldl[T any, R any](fn func(acc R, next T) R, base R, list []T) R {
- for _, value := range list {
- base = fn(base, value)
- }
- return base
-}
-
-func FoldlE[T any, R any](fn func(acc R, next T) (R, error), base R, list []T) (R, error) {
- for _, value := range list {
- var err error
- base, err = fn(base, value)
- if err != nil {
- var zero R
- return zero, errors.WrapAndTrace(err)
- }
- }
- return base, nil
-}
-
-// Take a list of things and a function that returns a list of things then combines list after mapping (return early from error)
-// func T -> [R, R, R ...]
-// [T, T, T ...] -> [R, R, R ...]
-func FlatmapE[T any, R any](fn func(some T) ([]R, error), list []T) ([]R, error) {
- return FoldlE(func(acc []R, el T) ([]R, error) {
- res, err := fn(el)
- if err != nil {
- return nil, errors.WrapAndTrace(err)
- }
- return Concat(acc, res), nil
- }, []R{}, list)
-}
-
// Take a list of things and a function that returns a list of things then combines list after mapping
// func T -> [R, R, R ...]
// [T, T, T ...] -> [R, R, R ...]
-func Flatmap[T any, R any](fn func(some T) []R, list []T) []R {
+func Flatmap[T, R any](fn func(some T) []R, list []T) []R {
return Foldl(func(acc []R, el T) []R {
return Concat(acc, fn(el))
}, []R{}, list)
}
-func Concat[T any](left []T, right []T) []T {
+func Concat[T any](left, right []T) []T {
return append(left, right...)
}
-// func T -> R
-// [T, T, T ...] -> [R, R, R ...]
-func Map[T, R any](items []T, mapper func(T) R) []R {
- results := []R{}
- for _, item := range items {
- results = append(results, mapper(item))
- }
- return results
-}
-
-func ListToMap[T any, R comparable](list []T, keySelector func(l T) R) map[R]T {
- result := map[R]T{}
- for _, item := range list {
- result[keySelector(item)] = item
- }
- return result
-}
-
-func ListToMapE[T any, R comparable](list []T, keySelector func(l T) (R, error)) (map[R]T, error) {
- result := map[R]T{}
- for _, item := range list {
- res, err := keySelector(item)
- if err != nil {
- return nil, errors.WrapAndTrace(err)
- }
- result[res] = item
- }
- return result, nil
-}
-
-func ListToMapKV[T any, R comparable, V any](list []T, keySelector func(l T) R, valueSelector func(l T) V) map[R]V {
- result := map[R]V{}
- for _, item := range list {
- result[keySelector(item)] = valueSelector(item)
- }
- return result
-}
-
-func ListToCollisionMap[T comparable](list []T) map[T]bool {
- result := map[T]bool{}
- for _, item := range list {
- result[item] = true
- }
- return result
-}
-
-func ListOfPointersToListOfValues[T any](list []*T) []T {
- return Map(list, func(i *T) T { return *i })
-}
-
-func DefaultValue[T any](value T, defaultValue T) T {
- if reflect.ValueOf(value).IsZero() {
- return defaultValue
- } else {
- return value
- }
-}
-
-func DefaultPtr[T any](value *T, defaultValue T) T {
- if reflect.ValueOf(value).IsZero() {
- return defaultValue
- } else {
- return *value
- }
-}
-
-// return default if ptr is nil or de-referenced ptr value is empty
-func DefaultPtrOrValue[T any](value *T, defaultValue T) T {
- if value == nil || reflect.ValueOf(*value).IsZero() {
- return defaultValue
- } else {
- return *value
- }
-}
-
-// right maps override left if they have the same key
-func MergeMaps[K comparable, V any](maps ...map[K]V) map[K]V {
- result := map[K]V{}
- for _, m := range maps {
- for k, v := range m {
- result[k] = v
- }
- }
- return result
-}
-
-func MapToGenericMap[v any](m map[string]v) map[string]interface{} {
- result := map[string]interface{}{}
- for k, v := range m {
- result[k] = v
- }
- return result
-}
-
-func GetAValueFromMap[K comparable, V any](m map[K]V) *V {
- for _, v := range m {
- return &v
- }
- return nil
-}
-
-func ListOfSomethingToListOfAny[T any](l []T) []any {
- newList := []any{}
- for _, item := range l {
- newList = append(newList, item)
- }
- return newList
-}
-
-func Ptr[T any](x T) *T {
- return &x
-}
-
-func Deref[T any](x *T) T {
- return *x
-}
-
-// return value or nil if value is zero
-func ZeroValueToNil[T any](x T) *T {
- if reflect.ValueOf(x).IsZero() {
- return nil
- } else {
- return &x
- }
-}
-
-func IsEmpty[T any](x T) bool {
- return reflect.ValueOf(x).IsZero()
-}
-
-func IsEmptyValP[T any](x *T) bool {
- if x == nil {
- return true
- } else {
- return reflect.ValueOf(*x).IsZero()
- }
-}
-
-func ReturnOnCondition[T any](ctx context.Context, fetcher func(ctx context.Context) (T, error), conditional func(i T) bool, updateDuration time.Duration) (T, error) {
- for ctx.Err() == nil {
- result, err := fetcher(ctx)
- if err != nil {
- return result, errors.WrapAndTrace(err)
- }
- if conditional(result) {
- return result, nil
- }
- time.Sleep(updateDuration)
- }
- var t T
- return t, ctx.Err() //nolint:wrapcheck // fine
-}
-
-func InitialNotEqual[T any](i T) func(l T) bool {
- return func(l T) bool {
- return !reflect.DeepEqual(i, l)
- }
-}
-
-func DeepEqual[T any](i T, l T) bool {
- return reflect.DeepEqual(i, l)
-}
-
-func FromJSON[T any](j []byte) (T, error) {
- var t T
- err := json.Unmarshal(j, &t)
- if err != nil {
- return t, errors.WrapAndTrace(err)
- }
- return t, nil
-}
-
-func CopyVal[T any](t T) (T, error) {
- var r T
- if err := copier.CopyWithOption(&r, t, CopyOptions{}.ToCopierOptions()); err != nil {
- return r, errors.WrapAndTrace(err)
- }
- return r, nil
-}
-
-func CopyPtrVal[T any](t *T) (*T, error) {
- var r T
- if err := copier.CopyWithOption(&r, t, CopyOptions{}.ToCopierOptions()); err != nil {
- return nil, errors.WrapAndTrace(err)
- }
- return &r, nil
-}
-
-func TryCopyToNew[T any, R any](t T, options ...CopyOption) (R, error) {
- var r R
- copyOptions := CopyOptions{}
- for _, o := range options {
- o.apply(t, r, ©Options)
- }
- if err := copier.CopyWithOption(&r, t, copyOptions.ToCopierOptions()); err != nil {
- return r, errors.WrapAndTrace(err)
- }
- return r, nil
-}
-
-type CopyOption interface {
- apply(t any, r any, o *CopyOptions)
-}
-
-type CopyMap map[string]string
-
-func (c CopyMap) apply(t any, r any, o *CopyOptions) {
- o.Mappers = append(o.Mappers, DumbCopyMapper{Mapping: copier.FieldNameMapping{
- SrcType: t,
- DstType: r,
- Mapping: c,
- }})
-}
-
-func TryCopyToNewOptions[T any, R any](t T, options CopyOptions) (R, error) {
- var r R
- if err := copier.CopyWithOption(&r, t, options.ToCopierOptions()); err != nil {
- return r, errors.WrapAndTrace(err)
- }
- return r, nil
-}
-
-// For testing different DX
-func TryCopyToNewE[T any, R any](t T, mappers ...CopyMappingFunc[T, R]) (R, error) {
- var r R
- opts := CopyOptions{}.ToCopierOptions()
- opts.FieldNameMapping = append(opts.FieldNameMapping, Map(mappers, func(m CopyMappingFunc[T, R]) copier.FieldNameMapping { return m.ToCopierMapping() })...)
- if err := copier.CopyWithOption(&r, t, opts); err != nil {
- return r, errors.WrapAndTrace(err)
- }
- return r, nil
-}
-
-type CopyOptions struct {
- ShallowCopy bool
- OmitDefaultConverters bool
- Converters CopierConverters
- Mappers CopyMappers // create mappings for any arbitrary type
-}
-
-type CopyMappers []CopyMapper
-
-func (c CopyMappers) ToCopierMappings() []copier.FieldNameMapping {
- var result []copier.FieldNameMapping
- for _, cc := range c {
- result = append(result, cc.ToCopierMapping())
- }
- return result
-}
-
-type CopyMapper interface {
- ToCopierMapping() copier.FieldNameMapping
-}
-
-type DumbCopyMapper struct {
- Mapping copier.FieldNameMapping
-}
-
-func (d DumbCopyMapper) ToCopierMapping() copier.FieldNameMapping {
- return d.Mapping
-}
-
-type CopyMapping[T, R any] map[string]string
-
-func (c CopyMapping[T, R]) ToCopierMapping() copier.FieldNameMapping {
- var t T
- var r R
- return copier.FieldNameMapping{
- SrcType: t,
- DstType: r,
- Mapping: c,
- }
-}
-
-type CopyMappingFunc[T, R any] func(T, R) map[any]any
-
-// Doesn't work but leaving for future reference
-func (c CopyMappingFunc[T, R]) ToCopierMapping() copier.FieldNameMapping {
- var t T
- valueT := reflect.ValueOf(&t).Elem()
- var r R
- valueR := reflect.ValueOf(&r).Elem()
- copierMapping := map[string]string{}
- realMapping := c(t, r)
- var allErr error
- for tf, rf := range realMapping {
- tfFound := findStructField(valueT, reflect.ValueOf(tf))
- rfFound := findStructField(valueR, reflect.ValueOf(rf))
- isErr := false
- if tfFound == nil {
- allErr = errors.Join(allErr, errors.Errorf("field %s not found in struct %T", tf, t))
- isErr = true
- }
- if rfFound == nil {
- allErr = errors.Join(allErr, errors.Errorf("field %s not found in struct %T", rf, r))
- isErr = true
- }
- if !isErr {
- copierMapping[tfFound.Name] = rfFound.Name
- }
- }
- if allErr != nil {
- panic(allErr)
- }
- return copier.FieldNameMapping{
- SrcType: t,
- DstType: r,
- Mapping: copierMapping,
- }
-}
-
var timeToPBTimeStamp CopyConverter[time.Time, *timestamppb.Timestamp] = func(src time.Time) (*timestamppb.Timestamp, error) {
return timestamppb.New(src), nil
}
@@ -743,28 +220,8 @@ var DefaultConverters = CopierConverters{
pbTimeStampToTimePtr,
}
-func (c CopyOptions) ToCopierOptions() copier.Option {
- convs := c.Converters.ToCopierTypeConverters()
- if !c.OmitDefaultConverters {
- convs = append(convs, DefaultConverters.ToCopierTypeConverters()...)
- }
- return copier.Option{
- DeepCopy: !c.ShallowCopy,
- Converters: convs,
- FieldNameMapping: c.Mappers.ToCopierMappings(),
- }
-}
-
type CopierConverters []CopierConverter
-func (c CopierConverters) ToCopierTypeConverters() []copier.TypeConverter {
- var result []copier.TypeConverter
- for _, cc := range c {
- result = append(result, cc.ToCopierTypeConverter())
- }
- return result
-}
-
type CopierConverter interface {
ToCopierTypeConverter() copier.TypeConverter
}
@@ -788,58 +245,14 @@ func (c CopyConverter[T, R]) ToCopierTypeConverter() copier.TypeConverter {
return ctc
}
-func TryCopyTo[T any, R any](t T, r R) (R, error) {
- if err := copier.CopyWithOption(&r, t, CopyOptions{}.ToCopierOptions()); err != nil {
- return r, errors.WrapAndTrace(err)
- }
- return r, nil
-}
-
-func TryCopyToOptions[T any, R any](t T, r R, options CopyOptions) (R, error) {
- if err := copier.CopyWithOption(&r, t, options.ToCopierOptions()); err != nil {
- return r, errors.WrapAndTrace(err)
- }
- return r, nil
+type Params[T any] struct {
+ Value T
+ Ctx context.Context
}
-func GetMapKeys[K comparable, V any](m map[K]V) []K {
- keys := []K{}
- for k := range m {
- keys = append(keys, k)
- }
- return keys
-}
-
-func GetMapValues[K comparable, V any](m map[K]V) []V {
- values := []V{}
- for _, v := range m {
- values = append(values, v)
- }
- return values
-}
-
-type Params[T any] struct {
- Value T
- Ctx context.Context
-}
-
-type Result[T any] struct {
- Value T
- Err error
-}
-
-func (r Result[T]) Unwrap() (T, error) {
- return r.Value, r.Err
-}
-
-// pass in m a map of string to any
-func MapToStruct[T any](m any) (T, error) {
- var t T
- err := mapstructure.Decode(m, &t)
- if err != nil {
- return t, errors.WrapAndTrace(err)
- }
- return t, nil
+type Result[T any] struct {
+ Value T
+ Err error
}
type MapKeyVal[K comparable, V any] struct {
@@ -847,27 +260,6 @@ type MapKeyVal[K comparable, V any] struct {
Value V
}
-func MapToList[K comparable, T any](m map[K]T) []MapKeyVal[K, T] {
- var results []MapKeyVal[K, T]
- for k, v := range m {
- results = append(results, MapKeyVal[K, T]{Key: k, Value: v})
- }
- return results
-}
-
-// sortFn if i < j then ascending (1,2,3), if i > j then descending (3,2,1)
-func SortByE[T any](sortFn func(T, T) (bool, error), list []T) ([]T, error) {
- var retErr error
- sort.SliceStable(list, func(i, j int) bool {
- cmp, err := sortFn(list[i], list[j])
- if err != nil {
- retErr = err
- }
- return cmp
- })
- return list, retErr
-}
-
// sortFn if i < j then ascending (1,2,3), if i > j then descending (3,2,1)
func SortBy[T any](sortFn func(T, T) bool, list []T) []T {
sort.SliceStable(list, func(i, j int) bool {
@@ -876,43 +268,6 @@ func SortBy[T any](sortFn func(T, T) bool, list []T) []T {
return list
}
-func RemoveDuplicates[T comparable](list []T) []T {
- seen := map[T]bool{}
- result := []T{}
- for _, item := range list {
- if !seen[item] {
- result = append(result, item)
- seen[item] = true
- }
- }
- return result
-}
-
-func ContainsDuplicatesErr[T comparable](list []T) error {
- seen := map[T]bool{}
- for _, item := range list {
- if seen[item] {
- return errors.Errorf("duplicate item: %v", item)
- }
- seen[item] = true
- }
- return nil
-}
-
-// takes a list of items and checks if items are elements in another list
-func ListItemsAreErr[T comparable](items []T, are []T) error {
- check := map[T]bool{}
- for _, r := range are {
- check[r] = true
- }
- for _, i := range items {
- if !check[i] {
- return errors.Errorf("item %v is not in list %v", i, are)
- }
- }
- return nil
-}
-
func Find[T any](list []T, f func(T) bool) *T {
for _, item := range list {
if f(item) {
@@ -922,30 +277,6 @@ func Find[T any](list []T, f func(T) bool) *T {
return nil
}
-func FindPtr[T any](list []*T, f func(*T) bool) *T {
- for _, item := range list {
- if f(item) {
- return item
- }
- }
- return nil
-}
-
-// returns those that are true
-func FilterE[T any](list []T, f func(T) (bool, error)) ([]T, error) {
- result := []T{}
- for _, item := range list {
- res, err := f(item)
- if err != nil {
- return nil, errors.WrapAndTrace(err)
- }
- if res {
- result = append(result, item)
- }
- }
- return result, nil
-}
-
// returns those that are true
func Filter[T any](list []T, f func(T) bool) []T {
result := []T{}
@@ -957,783 +288,20 @@ func Filter[T any](list []T, f func(T) bool) []T {
return result
}
-func FilterOutEmpty[T any](list []T) []T {
- return Filter(list, func(i T) bool {
- return !IsEmpty(i)
- })
-}
-
-func Max[T constraints.Ordered](x T, y T) T {
- if x > y {
- return x
- } else {
- return y
- }
-}
-
-func Min[T constraints.Ordered](x T, y T) T {
- if x < y {
- return x
- } else {
- return y
- }
-}
-
-func Deduplicate[T comparable](list []T) []T {
- seen := map[T]bool{}
- result := []T{}
- for _, item := range list {
- if !seen[item] {
- result = append(result, item)
- seen[item] = true
- }
- }
- return result
-}
-
-func MultiGroupBy[T comparable, A any](list []A, f func(A) []T) map[T][]A {
- result := map[T][]A{}
- for _, item := range list {
- key := f(item)
- for _, k := range key {
- result[k] = append(result[k], item)
- }
- }
- return result
-}
-
-func GroupBy[K comparable, A any](list []A, keyGetter func(A) K) map[K][]A {
- result := map[K][]A{}
- for _, item := range list {
- key := keyGetter(item)
- result[key] = append(result[key], item)
- }
- return result
-}
-
-func SortEachBucket[T comparable, A any](bucketedMap map[T][]A, f func(a A, b A) bool) map[T][]A {
- for k, v := range bucketedMap {
- sorted := SortBy(f, v)
- bucketedMap[k] = sorted
- }
- return bucketedMap
-}
-
-func GroupByE[T comparable, A any](list []A, f func(A) (T, error)) (map[T][]A, error) {
- result := map[T][]A{}
- for _, item := range list {
- key, err := f(item)
- if err != nil {
- return nil, errors.WrapAndTrace(err)
- }
- result[key] = append(result[key], item)
- }
- return result, nil
-}
-
-func Chunk[T any](list []T, chunkSize int) [][]T {
- var result [][]T
- for i := 0; i < len(list); i += chunkSize {
- end := i + chunkSize
- if end > len(list) {
- end = len(list)
- }
- result = append(result, list[i:end])
- }
- return result
-}
-
-func DecodeBase64OrValue(s string) (string, error) {
- if strings.HasPrefix(s, "base64:") {
- s = strings.TrimPrefix(s, "base64:")
- decoded, err := base64.StdEncoding.DecodeString(s)
- if err != nil {
- return "", errors.WrapAndTrace(err)
- }
- return string(decoded), nil
- }
- return s, nil
-}
-
-func LastXChars(s string, x int) string {
- if len(s) < x {
- return s
- }
- return s[len(s)-x:]
-}
-
-// creates a map of the keys in a and not in b
-func MapDiff[K comparable, V1 any, V2 any](a map[K]V1, b map[K]V2) map[K]V1 {
- c := CloneMap(a)
- for k := range b {
- delete(c, k)
- }
- return c
-}
-
-func ListAnyDiff[T any, C comparable](a []T, b []T, toComp func(t T) C) []T {
- aM := ListToMap(a, toComp)
- bM := ListToMap(b, toComp)
- return GetMapValues(MapDiff(aM, bM))
-}
-
-func ListDiff[T comparable](a []T, b []T) []T {
- aCM := ListToCollisionMap(a)
- bCM := ListToCollisionMap(b)
- aNotB := MapDiff(aCM, bCM)
- return GetMapKeys(aNotB)
-}
-
-func CloneMap[T any, K comparable](m map[K]T) map[K]T {
- result := map[K]T{}
- for k, v := range m {
- result[k] = v
- }
- return result
-}
-
-func CloneList[T any](l []T) []T {
- result := []T{}
- for _, v := range l { //nolint:gosimple //ok
- result = append(result, v)
- }
- return result
-}
-
-func ReverseList[T any](list []T) {
- length := len(list)
- for i := 0; i < length/2; i++ {
- list[i], list[length-i-1] = list[length-i-1], list[i]
- }
-}
-
-func GetFirstKeyThatContainsNoCase[T any](m map[string]T, s string) string {
- s = strings.ToLower(s)
- for k := range m {
- if strings.Contains(strings.ToLower(k), s) {
- return k
- }
- }
- return ""
-}
-
-func Run[T any](l []T, f func(t T)) {
- for _, item := range l {
- f(item)
- }
-}
-
-func ParallelWorkerMapE[T, R any](items []T, mapper func(T) (R, error), maxWorkers int) ([]R, error) {
- var wg sync.WaitGroup
- var mu sync.Mutex
-
- length := len(items)
- results := make([]R, length)
- var allErr error
-
- // Create a buffered channel to act as a semaphore.
- semaphore := make(chan struct{}, maxWorkers)
-
- for idx, item := range items {
- // Acquire a token from the semaphore.
- semaphore <- struct{}{}
-
- wg.Add(1)
- go func(i int, itm T) {
- defer wg.Done()
- defer func() {
- if p := recover(); p != nil {
- // attach call stack to avoid missing in different goroutine
- mu.Lock()
- allErr = errors.Join(allErr, errors.Errorf("%+v\n\n%s", p, strings.TrimSpace(string(debug.Stack()))))
- mu.Unlock()
- }
- }()
- res, err := mapper(itm)
- mu.Lock()
- if err != nil {
- allErr = errors.Join(allErr, errors.Wrap(err, fmt.Sprint(i)))
- } else {
- results[i] = res
- }
- mu.Unlock()
-
- // Release a token back to the semaphore.
- <-semaphore
- }(idx, item)
- }
-
- wg.Wait()
-
- return results, allErr //nolint:wrapcheck // fine for internal
-}
-
-// Early returns if one error is found, will return partial work
-func ParallelWorkerMapExitOnE[T, R any](ctx context.Context, items []T, mapper func(context.Context, T) (R, error), maxWorkers int) ([]R, error) {
- var wg sync.WaitGroup
- var mu sync.Mutex
-
- length := len(items)
- results := make([]R, length)
-
- ctx, cancel := context.WithCancel(ctx)
- defer cancel()
-
- var firstErr error
-
- // Create a buffered channel to act as a semaphore.
- semaphore := make(chan struct{}, maxWorkers)
-
- for idx, item := range items {
- select {
- case <-ctx.Done():
- case semaphore <- struct{}{}:
- wg.Add(1)
- go func(i int, itm T) {
- defer wg.Done()
- defer func() { <-semaphore }()
- defer func() {
- if p := recover(); p != nil {
- err := errors.Errorf("%+v\n\n%s", p, strings.TrimSpace(string(debug.Stack())))
- mu.Lock()
- if firstErr == nil {
- firstErr = err
- cancel()
- }
- mu.Unlock()
- }
- }()
-
- if res, err := mapper(ctx, itm); err != nil {
- mu.Lock()
- if firstErr == nil {
- firstErr = err
- cancel()
- }
- mu.Unlock()
- } else {
- mu.Lock()
- results[i] = res
- mu.Unlock()
- }
- }(idx, item)
- }
- }
-
- wg.Wait()
-
- // Priority is given to firstErr if it's set
- if firstErr != nil {
- return results, errors.WrapAndTrace(firstErr)
- }
-
- // If firstErr is nil, then we check if the context was canceled
- return results, errors.WrapAndTrace(ctx.Err())
-}
-
-func Iterate[T any](hasNext func() bool, next func() (T, error), do func(a T) (bool, error)) error {
- for hasNext() {
- a, err := next()
- if err != nil {
- return errors.WrapAndTrace(err)
- }
- cont, err := do(a)
- if err != nil {
- return errors.WrapAndTrace(err)
- }
- if !cont {
- break
- }
- }
- return nil
-}
-
-// Assumes that if cont is false res is empty
-func IterateToSlice[T any](f func() (bool, T, error)) ([]T, error) {
- allRes := []T{}
- for {
- cont, res, err := f()
- if err != nil {
- return nil, errors.WrapAndTrace(err)
- }
- if !cont {
- return allRes, nil
- }
- allRes = append(allRes, res)
- }
-}
-
-func RetryWithDataAndAttemptCount[T any](o backoff.OperationWithData[T], b backoff.BackOff) (T, error) {
- attemptCount := 0
- t, err := backoff.RetryWithData(func() (T, error) {
- attemptCount++
- return o()
- }, b)
- if err != nil {
- return t, errors.WrapAndTrace(errors.Errorf("attemptCount %d: %w", attemptCount, err))
- }
- return t, nil
-}
-
-func RetryWithAttemptCount(o backoff.Operation, b backoff.BackOff) error {
- attemptCount := 0
- err := backoff.Retry(func() error {
- attemptCount++
- return o()
- }, b)
- if err != nil {
- return errors.WrapAndTrace(errors.Errorf("attemptCount %d: %w", attemptCount, err))
- }
- return nil
-}
-
type Runnable interface {
Run(ctx context.Context) error
Shutdown(ctx context.Context) error
}
-// RunAllWithShutdown runs Runnabls in parallel and waits for shutdown signal (max n seconds)
-// if one runner errors or panics
-func RunAllWithShutdown(ctx context.Context, runners []Runnable, shutdownChan <-chan any) error {
- ctx, cancel := context.WithCancel(ctx)
- defer cancel()
-
- var wgRun sync.WaitGroup
- errChan := make(chan error, len(runners))
- doneChan := make(chan struct{})
- for _, r := range runners {
- wgRun.Add(1)
- go func(runner Runnable) {
- defer wgRun.Done()
- defer func() {
- if p := recover(); p != nil {
- // attach call stack to avoid missing in different goroutine
- errChan <- errors.Errorf("%+v\n\n%s", p, strings.TrimSpace(string(debug.Stack())))
- }
- }()
- if err := runner.Run(ctx); err != nil {
- errChan <- err
- }
- }(r)
- }
-
- go func() {
- wgRun.Wait()
- close(doneChan)
- }()
-
- var runErr error
- select {
- case <-shutdownChan:
- // Received shutdown signal
- case err := <-errChan:
- // One of the Run methods returned an error
- runErr = err
- case <-doneChan:
- return nil
- }
-
- // Initiate shutdown of all runners
- var shutdownErrors error
- var mu sync.Mutex
- var wgShutdown sync.WaitGroup
- for _, r := range runners {
- wgShutdown.Add(1)
- go func(runner Runnable) {
- defer wgShutdown.Done()
- err := DoWithTimeout(func(ctx context.Context) error {
- err := runner.Shutdown(ctx)
- if err != nil {
- return errors.WrapAndTrace(err)
- }
- return nil
- }, 5*time.Second, TimeoutOptions{
- CatchPanic: true,
- })
- if err != nil {
- mu.Lock()
- shutdownErrors = errors.Join(shutdownErrors, err)
- mu.Unlock()
- }
- }(r)
- }
-
- wgShutdown.Wait()
- return errors.WrapAndTrace(errors.Join(runErr, shutdownErrors))
-}
-
type ContextKey string
const IdempotencyKeyName ContextKey = "idempotencyKey"
-func ContextWithIdempotencyKey(ctx context.Context, idempotencyKey string) context.Context {
- if idempotencyKey == "" {
- return ctx
- }
- return context.WithValue(ctx, IdempotencyKeyName, idempotencyKey)
-}
-
-func GetIdempotencyKeyFromContext(ctx context.Context) string {
- idempotencyKey, _ := ctx.Value(IdempotencyKeyName).(string) // do not check for error because if fail, then just leave as empty string
- return idempotencyKey
-}
-
-func MakePrefixIdempotencyKeyFromCtx(ctx context.Context, prefix string) string {
- key := GetIdempotencyKeyFromContext(ctx)
- if key == "" {
- return ""
- }
- return fmt.Sprintf("%s-%s", prefix, key)
-}
-
-// for testing, and printing to screen, ignores error
-func ProtoToFormattedString(m proto.Message) string {
- res, _ := protojson.Marshal(m)
- var prettyJSON bytes.Buffer
- _ = json.Indent(&prettyJSON, res, "", " ")
- return prettyJSON.String()
-}
-
-type SafeSlice[T any] struct {
- slice []T
- mu sync.RWMutex
-}
-
-func NewSafeSlice[T any]() *SafeSlice[T] {
- return &SafeSlice[T]{
- slice: []T{},
- mu: sync.RWMutex{},
- }
-}
-
-// Append adds a new element to the slice.
-func (s *SafeSlice[T]) Append(value ...T) {
- s.mu.Lock()
- defer s.mu.Unlock()
- s.slice = append(s.slice, value...)
-}
-
-// Get retrieves an element at a specific index.
-func (s *SafeSlice[T]) Get(index int) (T, bool) {
- s.mu.RLock()
- defer s.mu.RUnlock()
- if index < 0 || index >= len(s.slice) {
- var zero T // Create a zero value of type T
- return zero, false
- }
- return s.slice[index], true
-}
-
-func (s *SafeSlice[T]) Set(slice []T) {
- s.mu.Lock()
- defer s.mu.Unlock()
- s.slice = slice
-}
-
-func (s *SafeSlice[T]) SetAt(index int, value T) bool {
- s.mu.Lock()
- defer s.mu.Unlock()
- if index < 0 || index >= len(s.slice) {
- return false
- }
- s.slice[index] = value
- return true
-}
-
-func (s *SafeSlice[T]) Delete(index int) bool {
- s.mu.Lock()
- defer s.mu.Unlock()
- if index < 0 || index >= len(s.slice) {
- return false
- }
- s.slice = append(s.slice[:index], s.slice[index+1:]...)
- return true
-}
-
-func (s *SafeSlice[T]) Slice() []T {
- s.mu.RLock()
- defer s.mu.RUnlock()
- newSlice := make([]T, len(s.slice))
- for i, v := range s.slice { //nolint:gosimple //ok
- newSlice[i] = v
- }
- return newSlice
-}
-
-func SliceToSafeSet[T comparable](s []T) *SafeSet[T] {
- set := SafeSet[T]{}
- for _, item := range s {
- set.Add(item)
- }
- return &set
-}
-
-type SafeSet[K comparable] struct {
- m SafeMap[K, any]
-}
-
-func NewSafeSet[K comparable]() *SafeSet[K] {
- return &SafeSet[K]{
- m: *NewSafeMap[K, any](),
- }
-}
-
-func (s *SafeSet[K]) Add(key K) {
- if _, ok := s.m.Get(key); !ok {
- s.m.Set(key, nil)
- }
-}
-
-func (s *SafeSet[K]) Remove(key K) {
- s.m.Delete(key)
-}
-
-func (s *SafeSet[K]) Clear() {
- s.m.Clear()
-}
-
-func (s *SafeSet[K]) Contains(key K) bool {
- _, ok := s.m.Get(key)
- return ok
-}
-
-func (s *SafeSet[K]) Len() int {
- return s.m.Len()
-}
-
-func (s *SafeSet[K]) Values() []K {
- return s.m.Keys()
-}
-
-// SafeMap is a generic map guarded by a RW mutex.
-type SafeMap[K comparable, V any] struct {
- mu sync.RWMutex
- items map[K]V
-}
-
-// NewSafeMap creates a new SafeMap.
-func NewSafeMap[K comparable, V any]() *SafeMap[K, V] {
- return &SafeMap[K, V]{
- items: map[K]V{},
- }
-}
-
-func (m *SafeMap[K, V]) Override(s map[K]V) {
- m.mu.Lock()
- defer m.mu.Unlock()
- m.items = s
-}
-
-// Set sets a value in the map.
-func (m *SafeMap[K, V]) Set(key K, value V) {
- m.mu.Lock()
- defer m.mu.Unlock()
- m.items[key] = value
-}
-
-// Get retrieves a value from the map.
-func (m *SafeMap[K, V]) Get(key K) (V, bool) {
- m.mu.RLock()
- defer m.mu.RUnlock()
- val, ok := m.items[key]
- return val, ok
-}
-
-// Delete removes a key from the map.
-func (m *SafeMap[K, V]) Delete(key K) {
- m.mu.Lock()
- defer m.mu.Unlock()
- delete(m.items, key)
-}
-
-// Clear removes all entries from the map.
-func (m *SafeMap[K, V]) Clear() {
- m.mu.Lock()
- defer m.mu.Unlock()
- m.items = make(map[K]V)
-}
-
-func (m *SafeMap[K, V]) Values() []V {
- m.mu.RLock()
- defer m.mu.RUnlock()
- return GetMapValues(m.items)
-}
-
-func (m *SafeMap[K, V]) Keys() []K {
- m.mu.RLock()
- defer m.mu.RUnlock()
- return GetMapKeys(m.items)
-}
-
-func (m *SafeMap[K, V]) Len() int {
- m.mu.RLock()
- defer m.mu.RUnlock()
- return len(m.items)
-}
-
-// Copy creates a new SafeMap with the same key-value pairs.
-func (m *SafeMap[K, V]) Copy() *SafeMap[K, V] {
- m.mu.RLock()
- defer m.mu.RUnlock()
-
- newMap := NewSafeMap[K, V]()
- for key, value := range m.items {
- newMap.items[key] = value
- }
- return newMap
-}
-
-// Sets the pointer of the current map to a copy of the map passed in.
-func (m *SafeMap[K, V]) CopyMap(c *SafeMap[K, V]) *SafeMap[K, V] {
- m.mu.Lock()
- defer m.mu.Unlock()
- m.items = c.Copy().items
- return m
-}
-
type SafeCounter struct {
mu sync.Mutex
c int
}
-func NewSafeCounter() *SafeCounter {
- return &SafeCounter{}
-}
-
-func (c *SafeCounter) Inc() {
- c.mu.Lock()
- defer c.mu.Unlock()
- c.c++
-}
-
-func (c *SafeCounter) Dec() {
- c.mu.Lock()
- defer c.mu.Unlock()
- c.c--
-}
-
-func (c *SafeCounter) Get() int {
- c.mu.Lock()
- defer c.mu.Unlock()
- return c.c
-}
-
-// SafeValue holds an arbitrary value with read and write protection.
-// T is the type of the value.
-type SafeValue[T any] struct {
- value T
- mutex sync.RWMutex
-}
-
-// NewSafeValue creates a new SafeValue.
-func NewSafeValue[T any](initialValue T) *SafeValue[T] {
- return &SafeValue[T]{
- value: initialValue,
- }
-}
-
-// Get returns the value safely.
-func (sv *SafeValue[T]) Get() T {
- sv.mutex.RLock()
- defer sv.mutex.RUnlock()
- return sv.value
-}
-
-// Set updates the value safely.
-func (sv *SafeValue[T]) Set(newValue T) {
- sv.mutex.Lock()
- defer sv.mutex.Unlock()
- sv.value = newValue
-}
-
-func RoundToNearestBase(num float64, base float64) float64 {
- return math.Round(num/base) * base
-}
-
-func RoundToNearestDecimal(num float64, decimalPlaces int) float64 {
- shift := math.Pow(10, float64(decimalPlaces))
- return math.Round(num*shift) / shift
-}
-
-func ListToChannel[T any](l []T) chan T {
- c := make(chan T, len(l))
- for _, item := range l {
- c <- item
- }
- close(c)
- return c
-}
-
-func DistinctChan[T any, K comparable](
- keyGetter func(T any) K, bufSize int,
-) (input chan T, output chan T) {
- input = make(chan T, bufSize)
- output = make(chan T, bufSize)
-
- go func() {
- set := make(map[K]T)
- for i := range input {
- k := keyGetter(i)
- if _, ok := set[k]; !ok {
- set[k] = i
- output <- i
- delete(set, k)
- }
- }
- close(output)
- }()
- return
-}
-
-func GetFunctionName(i any) string {
- nameStr, ok := i.(string)
- if ok {
- return nameStr
- }
- return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name()
-}
-
-func GetFieldName(structPtr any, fieldPtr any) string {
- res := findStructField(reflect.ValueOf(structPtr).Elem(), reflect.ValueOf(fieldPtr))
- return res.Name
-}
-
-// findStructField looks for a field in the given struct.
-// The field being looked for should be a pointer to the actual struct field.
-// If found, the field info will be returned. Otherwise, nil will be returned.
-func findStructField(structValue reflect.Value, fieldValue reflect.Value) *reflect.StructField {
- ptr := fieldValue.Pointer()
- for i := structValue.NumField() - 1; i >= 0; i-- {
- sf := structValue.Type().Field(i)
- if ptr == structValue.Field(i).UnsafeAddr() {
- // do additional type comparison because it's possible that the address of
- // an embedded struct is the same as the first field of the embedded struct
- if sf.Type == fieldValue.Elem().Type() {
- return &sf
- }
- }
- if sf.Anonymous {
- // delve into anonymous struct to look for the field
- fi := structValue.Field(i)
- if sf.Type.Kind() == reflect.Ptr {
- fi = fi.Elem()
- }
- if fi.Kind() == reflect.Struct {
- if f := findStructField(fi, fieldValue); f != nil {
- return f
- }
- }
- }
- }
- return nil
-}
-
-// returns json string or empty if fails
-func ToJSONString(i any) string {
- b, _ := json.Marshal(i)
- return string(b)
-}
-
type AsyncResult[T any] struct {
result chan result[T]
}
@@ -1762,287 +330,6 @@ type Rollback struct {
undos []func() error
}
-func NewRollback(undo func() error) *Rollback {
- return &Rollback{undos: []func() error{undo}}
-}
-
-func (r *Rollback) Add(undo func() error) {
- r.undos = append(r.undos, undo)
-}
-
-func (r Rollback) Rollback() error {
- var err error
- for i := len(r.undos) - 1; i >= 0; i-- {
- if e := r.undos[i](); e != nil {
- err = errors.Join(err, e)
- }
- }
- return err //nolint:wrapcheck // fine for internal
-}
-
-// SleepWithHealthCheck sleeps for the specified duration `d` and periodically calls `heartbeatFn`
-// at every `tickRate` until `d` has elapsed.
-func SleepWithHealthCheck(d time.Duration, tickRate time.Duration, heartbeatFn func()) {
- heartbeatFn() // Call the heartbeat function immediately
- // Timer to manage the total sleep duration
- sleepTimer := time.NewTimer(d)
- // Ticker to manage the heartbeat function calls
- tickTicker := time.NewTicker(tickRate)
- defer tickTicker.Stop() // Ensures the ticker is stopped to free resources
-
- go func() {
- for {
- select {
- case <-tickTicker.C: // On every tick, call the heartbeat function
- heartbeatFn()
- case <-sleepTimer.C: // Once the total duration has passed, return
- heartbeatFn()
- return
- }
- }
- }()
-
- <-sleepTimer.C // Wait for the sleep duration to pass before returning
-}
-
-func OnTick(ctx context.Context, d time.Duration, f func()) *time.Ticker {
- ticker := time.NewTicker(d)
- go func() {
- for {
- select {
- case <-ctx.Done():
- ticker.Stop()
- return
- case <-ticker.C:
- f()
- }
- }
- }()
- return ticker
-}
-
-// cancel context to end
-func DoForever(ctx context.Context, f func()) {
- _ = DoForeverE(ctx,
- func() error {
- f()
- return nil
- }, func(_ context.Context) error {
- return nil
- })
-}
-
-func DoForeverE(ctx context.Context,
- f func() error,
- done func(context.Context) error,
-) error {
- for {
- select {
- case <-ctx.Done():
- return done(ctx)
- default:
- return f()
- }
- }
-}
-
-func DoAfterE(ctx context.Context, d time.Duration,
- f func() error,
- done func(context.Context) error,
-) error {
- for {
- select {
- case <-ctx.Done():
- return done(ctx)
- case <-time.After(d):
- return f()
- }
- }
-}
-
-// cancel context to end
-func DoOnDuration(ctx context.Context, d time.Duration, f func()) {
- ticker := time.NewTicker(d)
- for {
- select {
- case <-ctx.Done():
- return
- case <-ticker.C:
- f()
- }
- }
-}
-
-// end early if err
-func DoOnDurationE(ctx context.Context, d time.Duration,
- f func() error,
- done func(context.Context) error,
-) error {
- ticker := time.NewTicker(d)
- for {
- select {
- case <-ctx.Done():
- return done(ctx)
- case <-ticker.C:
- err := f()
- if err != nil {
- return err
- }
- }
- }
-}
-
-type UniqueBufferedObjects[T any] struct {
- bufferedObjects *BufferedObjects[T]
- getID func(T) string
- objectsInBuffer *SafeSet[string]
-}
-
-func NewUniqueBufferedObjects[T any](
- flushSize int,
- flushInterval time.Duration,
- getID func(T) string,
- flushHandler func([]T),
-) *UniqueBufferedObjects[T] {
- ubo := &UniqueBufferedObjects[T]{
- getID: getID,
- objectsInBuffer: NewSafeSet[string](),
- }
- bo := NewBufferedObjects(flushSize, flushInterval, func(t []T) {
- flushHandler(t)
- for _, item := range t {
- ubo.objectsInBuffer.Remove(getID(item))
- }
- })
- ubo.bufferedObjects = bo
- return ubo
-}
-
-func (bi *UniqueBufferedObjects[T]) Add(object T) {
- objID := bi.getID(object)
- if bi.objectsInBuffer.Contains(objID) {
- return
- }
- bi.objectsInBuffer.Add(objID)
- bi.bufferedObjects.Add(object)
-}
-
-func (bi *UniqueBufferedObjects[T]) Flush() {
- bi.bufferedObjects.Flush()
-}
-
-func (bi *UniqueBufferedObjects[T]) Stop() {
- bi.bufferedObjects.Stop()
-}
-
-func (bi *UniqueBufferedObjects[T]) WaitTillEmpty() {
- bi.bufferedObjects.WaitTillEmpty()
-}
-
-type BufferedObjects[T any] struct {
- objects []T
- lock sync.Mutex
- flushSize int
- flushInterval time.Duration
- flushChan chan []T
- stopChan chan struct{}
- handlingFlush SafeValue[bool]
-}
-
-func NewBufferedObjects[T any](flushSize int, flushInterval time.Duration, flushHandler func([]T)) *BufferedObjects[T] {
- bi := &BufferedObjects[T]{
- flushSize: flushSize,
- flushInterval: flushInterval,
- flushChan: make(chan []T, 100), // [][]T buffer
- stopChan: make(chan struct{}),
- }
- go bi.run(flushHandler)
- return bi
-}
-
-func (bi *BufferedObjects[T]) SetBufferSize(flushSize int) {
- bi.flushChan = make(chan []T, flushSize)
-}
-
-func (bi *BufferedObjects[T]) Add(object T) {
- bi.lock.Lock()
- defer bi.lock.Unlock()
-
- bi.objects = append(bi.objects, object)
- if len(bi.objects) >= bi.flushSize {
- bi.Flush()
- }
-}
-
-func (bi *BufferedObjects[T]) Flush() {
- // Copy and reset buffer under lock to minimize lock time
- toFlush := make([]T, len(bi.objects))
- copy(toFlush, bi.objects)
- bi.objects = nil
-
- // Send to flush channel
- bi.flushChan <- toFlush
-}
-
-func (bi *BufferedObjects[T]) WaitTillEmpty() {
- for {
- bi.lock.Lock()
- if len(bi.objects) == 0 && len(bi.flushChan) == 0 && !bi.handlingFlush.Get() {
- bi.lock.Unlock()
- return
- }
- bi.lock.Unlock()
- time.Sleep(50 * time.Millisecond)
- }
-}
-
-func (bi *BufferedObjects[T]) run(flushHandler func([]T)) {
- ticker := time.NewTicker(bi.flushInterval)
- defer ticker.Stop()
-
- for {
- select {
- case <-ticker.C:
- bi.lock.Lock()
- if len(bi.objects) > 0 {
- bi.Flush()
- }
- bi.lock.Unlock()
- case objects := <-bi.flushChan:
- bi.handlingFlush.Set(true)
- flushHandler(objects)
- bi.handlingFlush.Set(false)
- case <-bi.stopChan:
- return
- }
- }
-}
-
-func (bi *BufferedObjects[T]) Stop() {
- close(bi.stopChan)
-}
-
-func ContainsAny(s string, subs ...string) bool {
- for _, sub := range subs {
- if strings.Contains(s, sub) {
- return true
- }
- }
- return false
-}
-
-func RetryTest(t *testing.T, testFunc func(t *testing.T), numRetries int) {
- t.Helper() // Mark this function as a helper
- for i := 0; i < numRetries; i++ {
- tt := &testing.T{}
- testFunc(tt)
- if !tt.Failed() {
- return
- }
- }
- t.Fail() // If we reach here, all retries failed
-}
-
var (
// ErrCanceled is the error returned when the context is canceled.
ErrCanceled = context.Canceled
@@ -2057,68 +344,3 @@ type TimeoutOptions struct {
ParentContext context.Context
CatchPanic bool
}
-
-// if you loop forever, make sure you have a way to break the loop
-// see Test_DoWithTimeoutTimeoutLoop
-func DoWithTimeout(fn func(ctx context.Context) error, timeout time.Duration, opts ...TimeoutOptions) error {
- _, err := DoWithTimeoutData(func(ctx context.Context) (interface{}, error) {
- return nil, fn(ctx)
- }, timeout, opts...)
- return err
-}
-
-// if you loop forever, make sure you have a way to break the loop
-// see Test_DoWithTimeoutTimeoutLoop
-func DoWithTimeoutData[T any](fn func(ctx context.Context) (T, error), timeout time.Duration, opts ...TimeoutOptions) (T, error) {
- type result struct {
- res T
- err error
- }
- options := TimeoutOptions{
- ParentContext: context.Background(),
- }
- for _, opt := range opts {
- options = opt
- }
- if options.ParentContext == nil {
- options.ParentContext = context.Background()
- }
- ctx, cancel := context.WithTimeout(options.ParentContext, timeout)
- defer cancel()
-
- // create channel with buffer size 1 to avoid goroutine leak
- resChan := make(chan result, 1)
- panicChan := make(chan interface{}, 1)
- go func() {
- defer func() {
- if p := recover(); p != nil {
- // attach call stack to avoid missing in different goroutine
- panicChan <- fmt.Sprintf("%+v\n\n%s", p, strings.TrimSpace(string(debug.Stack())))
- }
- }()
- res, err := fn(ctx)
- resChan <- result{res, err}
- }()
-
- var emptyT T
-
- select {
- case p := <-panicChan:
- if options.CatchPanic {
- return emptyT, fmt.Errorf("panic: %v", p)
- } else {
- panic(p)
- }
- case result := <-resChan:
- return result.res, result.err
- case <-ctx.Done():
- return emptyT, ctx.Err() //nolint:wrapcheck // no need to wrap
- }
-}
-
-// WithContext customizes a DoWithTimeout call with given ctx.
-func WithContext(ctx context.Context) DoOption {
- return func() context.Context {
- return ctx
- }
-}
diff --git a/pkg/config/config.go b/pkg/config/config.go
index 720c02af..f5538733 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -32,14 +32,6 @@ func (c ConstantsConfig) GetOllamaAPIURL() string {
return getEnvOrDefault(ollamaAPIURL, "https://registry.ollama.ai")
}
-func (c ConstantsConfig) GetServiceMeshCoordServerURL() string {
- return getEnvOrDefault(coordURL, "")
-}
-
-func (c ConstantsConfig) GetVersion() string {
- return getEnvOrDefault(version, "unknown")
-}
-
func (c ConstantsConfig) GetDefaultClusterID() string {
return getEnvOrDefault(clusterID, "devplane-brev-1")
}
@@ -53,10 +45,6 @@ func (c ConstantsConfig) GetDefaultWorkspaceTemplate() string {
return getEnvOrDefault(defaultWorkspaceTemplate, "")
}
-func (c ConstantsConfig) GetSentryURL() string {
- return getEnvOrDefault(sentryURL, "https://4f3dca96f17e4c7995588dda4a31b37f@o410659.ingest.sentry.io/6383105")
-}
-
func (c ConstantsConfig) GetDebugHTTP() bool {
return getEnvOrDefault(debugHTTP, "") != ""
}
@@ -75,26 +63,14 @@ type EnvVarConfig struct {
ConstantsConfig
}
-func (c *ConstantsConfig) WithEnvVars() *EnvVarConfig {
- return &EnvVarConfig{*c}
-}
-
type FileConfig struct {
EnvVarConfig
}
-func (c *EnvVarConfig) WithFileConfig() *FileConfig {
- return &FileConfig{*c}
-}
-
type FlagsConfig struct {
FileConfig
}
-func (c *FileConfig) WithFlags() *FlagsConfig {
- return &FlagsConfig{*c}
-}
-
type InitConfig interface{}
type AllConfig interface {
diff --git a/pkg/entity/entity.go b/pkg/entity/entity.go
index d4a5f302..daa871d5 100644
--- a/pkg/entity/entity.go
+++ b/pkg/entity/entity.go
@@ -224,14 +224,6 @@ type WorkspaceWithMeta struct {
Workspace
}
-func WorkspacesWithMetaToWorkspaces(wms []WorkspaceWithMeta) []Workspace {
- ws := []Workspace{}
- for _, wm := range wms {
- ws = append(ws, wm.Workspace)
- }
- return ws
-}
-
type Application struct {
ID string `json:"id"`
Name string `json:"name"`
@@ -498,25 +490,12 @@ func (w Workspace) GetHostIdentifier() WorkspaceLocalID {
return w.createSimpleName() + "-host"
}
-func MakeIDSuffix(id string) string {
- return id[len(id)-4:]
-}
-
var (
whitespaceCharPattern = regexp.MustCompile(`\s+`)
invalidCharPattern = regexp.MustCompile(`[^a-z0-9-]`)
)
// lowercase, replace whitespace with '-', remove all [^a-z0-9-], trim '-' front and back
-func CleanSubdomain(in string) string {
- lowered := strings.ToLower(in)
- whitespaceReplacedWithDash := whitespaceCharPattern.ReplaceAllString(lowered, "-")
- removedInvalidChars := invalidCharPattern.ReplaceAllString(whitespaceReplacedWithDash, "")
- removedPrefixSuffixDashses := strings.Trim(removedInvalidChars, "-")
-
- out := removedPrefixSuffixDashses
- return out
-}
func (w Workspace) GetID() string {
return w.ID
diff --git a/pkg/errors/errors.go b/pkg/errors/errors.go
index 5c021d37..be340a52 100644
--- a/pkg/errors/errors.go
+++ b/pkg/errors/errors.go
@@ -4,7 +4,6 @@ import (
"fmt"
"runtime"
"strconv"
- "strings"
"time"
stderrors "errors"
@@ -129,11 +128,6 @@ type DeclineToLoginError struct{}
func (d *DeclineToLoginError) Error() string { return "declined to login" }
func (d *DeclineToLoginError) Directive() string { return "log in to run this command" }
-func MakeErrorMessage(message string) string {
- _, fn, line, _ := runtime.Caller(2)
- return fmt.Sprintf("[error] %s:%d %s\n\t", fn, line, message)
-}
-
var NetworkErrorMessage = "possible internet connection problem"
type CredentialsFileNotFound struct{}
@@ -268,13 +262,6 @@ func WrapAndTraceInMsg(err error) error {
return pkgerrors.Wrap(err, makeErrorMessage("", 0)) // this wrap also adds a stacktrace which can be nice
}
-func WrapAndTrace2[T any](t T, err error) (T, error) {
- if err == nil {
- return t, nil
- }
- return t, pkgerrors.Wrap(err, makeErrorMessage("", 0))
-}
-
func makeErrorMessage(message string, skip int) string {
skip += 2
pc, file, line, _ := runtime.Caller(skip)
@@ -289,37 +276,4 @@ func makeErrorMessage(message string, skip int) string {
return fmt.Sprintf("[error] %s\n%s\n%s:%s\n", message, funcName, file, lineNum)
}
-func HandleErrDefer(f func() error) {
- _ = f()
- // logger.L().Error("", zap.Error(err))
-}
-
-func ErrorContainsAny(err error, substrs ...string) bool {
- for _, substr := range substrs {
- if ErrorContains(err, substr) {
- return true
- }
- }
- return false
-}
-
-func ErrorContains(err error, substr string) bool {
- return err != nil && strings.Contains(err.Error(), substr)
-}
-
-func IsErrorExcept(err error, errs ...error) bool {
- return err != nil && !IsAny(err, errs...)
-}
-
-func IsErrorExceptSubstr(err error, substr ...string) bool {
- return err != nil && !ErrorContainsAny(err, substr...)
-}
-
-func IsAny(err error, errs ...error) bool {
- for _, e := range errs {
- if Is(err, e) {
- return true
- }
- }
- return false
-}
+// logger.L().Error("", zap.Error(err))
diff --git a/pkg/featureflag/featureflag.go b/pkg/featureflag/featureflag.go
index acdf6646..80ea0af9 100644
--- a/pkg/featureflag/featureflag.go
+++ b/pkg/featureflag/featureflag.go
@@ -25,21 +25,11 @@ func IsAdmin(userType entity.GlobalUserType) bool {
}
// use feature flag if not provided default true for admin but not others
-func ServiceMeshSSH(userType entity.GlobalUserType) bool {
- if viper.IsSet("feature.service_mesh_ssh") {
- return viper.GetBool("feature.service_mesh_ssh")
- }
- return IsAdmin(userType)
-}
func DisableSSHProxyVersionCheck() bool {
return viper.GetBool("feature.disable_ssh_proxy_version_check")
}
-func DisableErrorReporting() bool {
- return viper.GetBool("feature.disable_error_reporting")
-}
-
func ShowVersionOnRun() bool {
return viper.GetBool("feature.show_version_on_run")
}
diff --git a/pkg/files/files.go b/pkg/files/files.go
index 81ac7cc1..c0554772 100644
--- a/pkg/files/files.go
+++ b/pkg/files/files.go
@@ -7,7 +7,6 @@ import (
"os"
"os/exec"
"path/filepath"
- "strings"
breverrors "github.com/brevdev/brev-cli/pkg/errors"
"golang.org/x/text/encoding/charmap"
@@ -34,38 +33,10 @@ const (
var AppFs = afero.NewOsFs()
-func GetBrevDirectory() string {
- return brevDirectory
-}
-
-func GetActiveOrgFile() string {
- return activeOrgFile
-}
-
-func GetPersonalSettingsCache() string {
- return personalSettingsCache
-}
-
-func GetOrgCacheFile() string {
- return orgCacheFile
-}
-
-func GetWorkspaceCacheFile() string {
- return workspaceCacheFile
-}
-
-func GetKubeCertFileName() string {
- return kubeCertFileName
-}
-
func GetSSHPrivateKeyFileName() string {
return sshPrivateKeyFileName
}
-func GetTailScaleOutFileName() string {
- return tailscaleOutFileName
-}
-
func GetNewBackupSSHConfigFileName() string {
return fmt.Sprintf("%s.%s", backupSSHConfigFileNamePrefix, uuid.New())
}
@@ -93,11 +64,6 @@ func GetActiveOrgsPath(home string) string {
return fpath
}
-func GetPersonalSettingsCachePath(home string) string {
- fpath := makeBrevFilePath(personalSettingsCache, home)
- return fpath
-}
-
func GetSSHPrivateKeyPath(home string) string {
fpath := makeBrevFilePath(GetSSHPrivateKeyFileName(), home)
return fpath
@@ -132,11 +98,6 @@ func GetNewBackupSSHConfigFilePath(home string) string {
return fp
}
-func GetTailScaleOutFilePath(home string) string {
- fp := makeBrevFilePath(GetTailScaleOutFileName(), home)
- return fp
-}
-
// ReadJSON reads data from a file into the given struct
//
// Usage:
@@ -232,29 +193,10 @@ func OverwriteJSON(fs afero.Fs, filepath string, v interface{}) error {
// Usage
//
// OverwriteString("tmp/a/b/c.txt", "hi there")
-func OverwriteString(fs afero.Fs, filepath string, data string) error {
- f, err := touchFile(fs, filepath)
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
-
- // clear
- err = f.Truncate(0)
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
- // write
- err = ioutil.WriteFile(filepath, []byte(data), os.ModePerm)
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
+// clear
- if err = f.Close(); err != nil {
- return breverrors.WrapAndTrace(err)
- }
- return breverrors.WrapAndTrace(err)
-}
+// write
func WriteSSHPrivateKey(fs afero.Fs, data string, home string) error {
pkPath := GetSSHPrivateKeyPath(home)
@@ -306,57 +248,6 @@ func CatFile(filePath string) (string, error) {
}
}
-func GetAliasesFromFile(file string) []string {
- var result []string
-
- dirname, err := os.UserHomeDir()
- if err != nil {
- // if this doesn't work, just exit
- return nil
- }
- lines, err := CatFile(dirname + "/" + file)
- if err != nil {
- // if this doesn't work, just exit
- return nil
- }
- for _, line := range strings.Split(lines, "\n") {
- if strings.HasPrefix(line, "alias ") {
- result = append(result, line)
- }
- }
- return result
-}
-
-func GetAllAliases() []string {
- var lines []string
- lines = append(lines, GetAliasesFromFile(".zshrc")...)
- lines = append(lines, GetAliasesFromFile(".bashrc")...)
- lines = append(lines, GetAliasesFromFile(".zprofile")...)
- lines = append(lines, GetAliasesFromFile(".bash_profile")...)
- lines = append(lines, GetAliasesFromFile(".config/fish/config.fish")...)
-
- var output []string
- for _, line := range lines {
- output = append(output, fmt.Sprintf("echo '%s' >> /home/brev/.zshrc", line))
- output = append(output, fmt.Sprintf("echo '%s' >> /home/brev/.bashrc", line))
- }
-
- return output
-}
-
-func GenerateSetupScript(lines []string) string {
- introString := `
-#!/bin/bash
-
-set -euo pipefail
+// if this doesn't work, just exit
-##### This is your brev.dev setup script
-##### Commit this file to the repo to make the environment reproducible
-##### https://docs.brev.dev/howto/automatically-set-up
-
- `
- output := []string{introString, `##### Adding Aliases From Your Local Machine #####\n`, `(echo ""; echo "##### Adding Aliases From Your Local Machine #####"; echo "";)\n`}
- output = append(output, lines...)
-
- return strings.Join(output, "\n")
-}
+// if this doesn't work, just exit
diff --git a/pkg/k8s/client.go b/pkg/k8s/client.go
index bc001af6..1ed5754b 100644
--- a/pkg/k8s/client.go
+++ b/pkg/k8s/client.go
@@ -1,14 +1,9 @@
package k8s
import (
- "fmt"
-
"github.com/brevdev/brev-cli/pkg/entity"
- "k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
-
- breverrors "github.com/brevdev/brev-cli/pkg/errors"
)
type K8sClient interface {
@@ -33,36 +28,6 @@ type K8sClientConfig interface {
GetCA() []byte
}
-func NewDefaultClient(config K8sClientConfig) (K8sClient, error) {
- restConfig := dynamic.ConfigFor(&rest.Config{
- Host: config.GetHost(),
- APIPath: "/api",
- TLSClientConfig: rest.TLSClientConfig{
- CertData: config.GetCert(),
- KeyData: config.GetKey(),
- CAData: config.GetCA(),
- },
- })
-
- k8sClient, err := kubernetes.NewForConfig(restConfig)
- if err != nil {
- return nil, breverrors.WrapAndTrace(err)
- }
-
- return &DefaultClient{
- k8sClientset: k8sClient,
- k8sRestConfig: restConfig,
- }, nil
-}
-
-func (c DefaultClient) GetK8sClient() *kubernetes.Clientset {
- return c.k8sClientset
-}
-
-func (c DefaultClient) GetK8sRestConfig() *rest.Config {
- return c.k8sRestConfig
-}
-
type DefaultWorkspaceGroupClientMapper struct {
workspaceK8sClientMap map[string]K8sClient
workspaceK8sAPIURLMap map[string]string
@@ -73,70 +38,9 @@ type K8sStore interface {
GetCurrentUserKeys() (*entity.UserKeys, error)
}
-func NewDefaultWorkspaceGroupClientMapper(k8sStore K8sStore) (*DefaultWorkspaceGroupClientMapper, error) {
- keys, err := k8sStore.GetCurrentUserKeys()
- if err != nil {
- return nil, breverrors.WrapAndTrace(err)
- }
-
- wkc := make(map[string]K8sClient)
- wka := make(map[string]string)
- for _, wk := range keys.WorkspaceGroups {
- rcc := RemoteK8sClientConfig{
- host: wk.APIURL,
- cert: []byte(wk.Cert),
- key: []byte(keys.PrivateKey),
- ca: []byte(wk.CA),
- }
- wkc[wk.GroupID], err = NewDefaultClient(rcc)
- if err != nil {
- return nil, breverrors.WrapAndTrace(err)
- }
- wka[wk.GroupID] = wk.APIURL
- }
-
- return &DefaultWorkspaceGroupClientMapper{workspaceK8sClientMap: wkc, workspaceK8sAPIURLMap: wka, privateKey: keys.PrivateKey}, nil
-}
-
-func (d DefaultWorkspaceGroupClientMapper) GetK8sClient(workspaceGroupID string) (K8sClient, error) {
- client, doesExists := d.workspaceK8sClientMap[workspaceGroupID]
- if !doesExists {
- return nil, fmt.Errorf("client for workspace group does not exist [workspace group id=%s]", workspaceGroupID)
- }
- return client, nil
-}
-
-func (d DefaultWorkspaceGroupClientMapper) GetK8sAPIURL(workspaceGroupID string) (string, error) {
- url, doesExists := d.workspaceK8sAPIURLMap[workspaceGroupID]
- if !doesExists {
- return "", fmt.Errorf("k8s api url for workspace group does not exist [workspace group id=%s]", workspaceGroupID)
- }
- return url, nil
-}
-
-func (d DefaultWorkspaceGroupClientMapper) GetPrivateKey() string {
- return d.privateKey
-}
-
type RemoteK8sClientConfig struct {
host string
cert []byte
key []byte
ca []byte
}
-
-func (k RemoteK8sClientConfig) GetHost() string {
- return k.host
-}
-
-func (k RemoteK8sClientConfig) GetCert() []byte {
- return k.cert
-}
-
-func (k RemoteK8sClientConfig) GetKey() []byte {
- return k.key
-}
-
-func (k RemoteK8sClientConfig) GetCA() []byte {
- return k.ca
-}
diff --git a/pkg/mergeshells/mergeshells.go b/pkg/mergeshells/mergeshells.go
index ddc7c4d2..6de97c7c 100644
--- a/pkg/mergeshells/mergeshells.go
+++ b/pkg/mergeshells/mergeshells.go
@@ -17,7 +17,6 @@ import (
"github.com/brevdev/brev-cli/pkg/files"
"github.com/brevdev/brev-cli/pkg/terminal"
"github.com/tidwall/gjson"
- "golang.org/x/text/encoding/charmap"
)
//go:embed templates/*
@@ -546,18 +545,6 @@ func goVersion(path string) *string {
return nil
}
-func IsRuby(path string) bool {
- paths := recursivelyFindFile([]string{"Gemfile.lock", "Gemfile"}, path)
-
- return len(paths) > 0
-}
-
-func IsPython(path string) bool {
- paths := recursivelyFindFile([]string{"Gemfile.lock", "Gemfile"}, path)
-
- return len(paths) > 0
-}
-
func appendPath(a string, b string) string {
if a == "." {
return b
@@ -613,20 +600,7 @@ func recursivelyFindFile(filenames []string, path string) []string {
// read from gomod
// read from json
-func CatFile(filePath string) (string, error) {
- gocmd := exec.Command("cat", filePath) // #nosec G204
- in, err := gocmd.Output()
- if err != nil {
- return "", breverrors.Wrap(err, "error reading file "+filePath)
- } else {
- d := charmap.CodePage850.NewDecoder()
- out, err := d.Bytes(in)
- if err != nil {
- return "", breverrors.Wrap(err, "error reading file "+filePath)
- }
- return string(out), nil
- }
-}
+// #nosec G204
func readGoMod(filePath string) (string, error) {
contents, err := files.CatFile(filePath)
diff --git a/pkg/portforward/portforward.go b/pkg/portforward/portforward.go
index 20aa9c62..89c65ec4 100644
--- a/pkg/portforward/portforward.go
+++ b/pkg/portforward/portforward.go
@@ -1,20 +1,10 @@
package portforward
import (
- "fmt"
- "net/http"
"net/url"
- "os"
- "os/signal"
- breverrors "github.com/brevdev/brev-cli/pkg/errors"
-
- "github.com/brevdev/brev-cli/pkg/entity"
"github.com/brevdev/brev-cli/pkg/k8s"
"k8s.io/cli-runtime/pkg/genericclioptions"
- "k8s.io/client-go/transport/spdy"
-
- toolsportforward "k8s.io/client-go/tools/portforward"
)
type PortForwardOptions struct {
@@ -37,101 +27,10 @@ type PortForwarder interface {
ForwardPorts(method string, url *url.URL, opts PortForwardOptions) error
}
-func NewPortForwardOptions(workspaceGroupClientMapper k8s.WorkspaceGroupClientMapper, portforwarder PortForwarder) *PortForwardOptions {
- p := &PortForwardOptions{
- PortForwarder: portforwarder,
- WorkspaceGroupClientMapper: workspaceGroupClientMapper,
- }
-
- p.Address = []string{"localhost"}
- p.StopChannel = make(chan struct{}, 1)
- p.ReadyChannel = make(chan struct{})
-
- return p
-}
-
-func (o *PortForwardOptions) WithWorkspace(workspace entity.WorkspaceWithMeta) (*PortForwardOptions, error) {
- o.Namespace = workspace.GetNamespaceName()
- o.PodName = workspace.GetPodName()
-
- k8sAPIURL, err := o.WorkspaceGroupClientMapper.GetK8sAPIURL(workspace.WorkspaceGroupID)
- if err != nil {
- return nil, breverrors.WrapAndTrace(err)
- }
- o.K8sAPIURL = k8sAPIURL
-
- k8sClient, err := o.WorkspaceGroupClientMapper.GetK8sClient(workspace.WorkspaceGroupID)
- if err != nil {
- return nil, breverrors.WrapAndTrace(err)
- }
- o.K8sClient = k8sClient
-
- if o.PodName == "" {
- return nil, fmt.Errorf("unable to forward port because pod is not found-- workspace may not be running")
- }
-
- return o, nil
-}
-
// TODO with stopchannel
-func (o *PortForwardOptions) WithPort(port string) *PortForwardOptions {
- o.Ports = []string{port}
- return o
-}
-
-func (o PortForwardOptions) RunPortforward() error {
- // cmd := portforward.NewCmdPortForward(tf, streams) // This command is useful to have around to go to def of kubectl cmd
-
- signals := make(chan os.Signal, 1)
- signal.Notify(signals, os.Interrupt)
- defer signal.Stop(signals)
-
- go func() {
- <-signals
- if o.StopChannel != nil {
- close(o.StopChannel)
- }
- }()
-
- urlStr := fmt.Sprintf("%s/api/v1/namespaces/%s/pods/%s/portforward", o.K8sAPIURL, o.Namespace, o.PodName)
-
- url, err := url.Parse(urlStr)
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
- err = o.PortForwarder.ForwardPorts("POST", url, o)
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
- return nil
-}
+// cmd := portforward.NewCmdPortForward(tf, streams) // This command is useful to have around to go to def of kubectl cmd
type DefaultPortForwarder struct {
genericclioptions.IOStreams
}
-
-func NewDefaultPortForwarder() *DefaultPortForwarder {
- return &DefaultPortForwarder{
- IOStreams: genericclioptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr},
- }
-}
-
-func (f *DefaultPortForwarder) ForwardPorts(method string, url *url.URL, opts PortForwardOptions) error {
- transport, upgrader, err := spdy.RoundTripperFor(opts.K8sClient.GetK8sRestConfig())
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
- var fw *toolsportforward.PortForwarder
- dialer := spdy.NewDialer(upgrader, &http.Client{Transport: transport}, method, url)
- fw, err = toolsportforward.NewOnAddresses(dialer, opts.Address, opts.Ports, opts.StopChannel, opts.ReadyChannel, f.Out, f.ErrOut)
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
-
- err = fw.ForwardPorts()
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
- return nil
-}
diff --git a/pkg/prefixid/prefixid.go b/pkg/prefixid/prefixid.go
index 1801424b..c83b1b2c 100644
--- a/pkg/prefixid/prefixid.go
+++ b/pkg/prefixid/prefixid.go
@@ -1,16 +1,7 @@
package prefixid
-import (
- "fmt"
-
- "github.com/segmentio/ksuid"
-)
-
type PrefixID string
const prefixSep = "-"
// New generates a unique ID that can be used as an identifier for an entity.
-func New(prefix string) PrefixID {
- return PrefixID(fmt.Sprintf("%s%s%s", prefix, prefixSep, ksuid.New().String()))
-}
diff --git a/pkg/setupworkspace/setupworkspace.go b/pkg/setupworkspace/setupworkspace.go
index 0403186a..a06340dc 100644
--- a/pkg/setupworkspace/setupworkspace.go
+++ b/pkg/setupworkspace/setupworkspace.go
@@ -311,14 +311,6 @@ func SendLogToFiles(cmd *exec.Cmd, filePaths ...string) (func(), error) {
}, nil
}
-func (w WorkspaceIniter) ChownFileToUser(file *os.File) error {
- err := ChownFileToUser(file, w.User)
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
- return nil
-}
-
func (w WorkspaceIniter) BuildHomePath(suffix ...string) string {
return filepath.Join(append([]string{w.User.HomeDir}, suffix...)...)
}
@@ -1050,14 +1042,6 @@ tar --no-same-owner -xzv --strip-components=1 -C ~/.vscode-server/bin/"${commit_
return nil
}
-func (w WorkspaceIniter) RunApplicationScripts(scripts []string) error {
- for _, s := range scripts {
- cmd := CmdStringBuilder(s)
- _ = cmd.Run()
- }
- return nil
-}
-
func allRepoFormats(repo string) []string {
repos := []string{
repo,
@@ -1332,35 +1316,7 @@ type CommandGroup struct {
User *user.User
}
-func NewCommandGroup() *CommandGroup {
- return &CommandGroup{}
-}
-
-func (c *CommandGroup) WithUser(user *user.User) *CommandGroup {
- c.User = user
- return c
-}
-
-func (c *CommandGroup) AddCmd(cmd *exec.Cmd) {
- c.Cmds = append(c.Cmds, cmd)
-}
-
-func (c *CommandGroup) Run() error {
- // TODO batch
- for _, cmd := range c.Cmds {
- if c.User != nil && (cmd.SysProcAttr == nil || cmd.SysProcAttr.Credential == nil) {
- err := CmdAsUser(cmd, c.User)
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
- }
- err := cmd.Run()
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
- }
- return nil
-}
+// TODO batch
func CmdAsUser(cmd *exec.Cmd, user *user.User) error {
uid, err := strconv.ParseInt(user.Uid, 10, 32)
diff --git a/pkg/setupworkspace/validate.go b/pkg/setupworkspace/validate.go
index aac5ad0b..9b0f388e 100644
--- a/pkg/setupworkspace/validate.go
+++ b/pkg/setupworkspace/validate.go
@@ -1,7 +1 @@
package setupworkspace
-
-import "github.com/brevdev/brev-cli/pkg/store"
-
-func ValidateSetup(_ store.SetupParamsV0) error {
- return nil
-}
diff --git a/pkg/ssh/sshconfigurer.go b/pkg/ssh/sshconfigurer.go
index 73374d0a..d93931bb 100644
--- a/pkg/ssh/sshconfigurer.go
+++ b/pkg/ssh/sshconfigurer.go
@@ -267,11 +267,6 @@ type SSHConfigEntryV2 struct {
Port int
}
-func MapContainsKey[K comparable, V any](m map[K]V, key K) bool {
- _, ok := m[key]
- return ok
-}
-
func tmplAndValToString(tmpl *template.Template, val interface{}) (string, error) {
buf := &bytes.Buffer{}
err := tmpl.Execute(buf, val)
@@ -526,82 +521,9 @@ type SSHConfigurerServiceMesh struct {
store SSHConfigurerV2Store
}
-var _ Config = SSHConfigurerServiceMesh{}
+// Deprecated: var _ Config = SSHConfigurerServiceMesh{}
-func NewSSHConfigurerServiceMesh(store SSHConfigurerV2Store) *SSHConfigurerServiceMesh {
- return &SSHConfigurerServiceMesh{
- store: store,
- }
-}
-
-func (s SSHConfigurerServiceMesh) Update(workspaces []entity.Workspace) error {
- newConfig, err := s.CreateNewSSHConfig(workspaces)
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
-
- err = s.store.WriteBrevSSHConfig(newConfig)
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
-
- err = s.EnsureConfigHasInclude()
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
-
- return nil
-}
-
-func (s SSHConfigurerServiceMesh) EnsureConfigHasInclude() error {
- // openssh-7.3
-
- brevConfigPath, err := s.store.GetBrevSSHConfigPath()
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
- conf, err := s.store.GetUserSSHConfig()
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
- if !doesUserSSHConfigIncludeBrevConfig(conf, brevConfigPath) {
- newConf, err := AddIncludeToUserConfig(conf, brevConfigPath)
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
- err = s.store.WriteUserSSHConfig(newConf)
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
- }
-
- return nil
-}
-
-func (s SSHConfigurerServiceMesh) CreateNewSSHConfig(workspaces []entity.Workspace) (string, error) {
- log.Print("creating new service mesh ssh config")
-
- configPath, err := s.store.GetUserSSHConfigPath()
- if err != nil {
- return "", breverrors.WrapAndTrace(err)
- }
-
- sshConfig := fmt.Sprintf("# included in %s\n", configPath)
- for _, w := range workspaces {
- pk, err := s.store.GetPrivateKeyPath()
- if err != nil {
- return "", breverrors.WrapAndTrace(err)
- }
- entry, err := makeSSHConfigServiceMeshEntry(string(w.GetLocalIdentifier()), w.GetNodeIdentifierForVPN(), pk)
- if err != nil {
- return "", breverrors.WrapAndTrace(err)
- }
-
- sshConfig += entry
- }
-
- return sshConfig, nil
-}
+// openssh-7.3
const SSHConfigEntryTemplateServiceMesh = `Host {{ .Alias }}
HostName {{ .Host }}
@@ -620,28 +542,6 @@ type SSHConfigEntryServiceMesh struct {
Port string
}
-func makeSSHConfigServiceMeshEntry(alias string, host string, privateKeyPath string) (string, error) {
- entry := SSHConfigEntryServiceMesh{
- Alias: alias,
- Host: host,
- IdentityFile: privateKeyPath,
- User: "brev",
- Port: "22",
- }
-
- tmpl, err := template.New(host).Parse(SSHConfigEntryTemplateServiceMesh)
- if err != nil {
- return "", breverrors.WrapAndTrace(err)
- }
- buf := &bytes.Buffer{}
- err = tmpl.Execute(buf, entry)
- if err != nil {
- return "", breverrors.WrapAndTrace(err)
- }
-
- return buf.String(), nil
-}
-
type SSHConfigurerJetBrains struct {
store SSHConfigurerV2Store
}
diff --git a/pkg/ssh/sshconfigurer_test.go b/pkg/ssh/sshconfigurer_test.go
index 67d11b06..d164369a 100644
--- a/pkg/ssh/sshconfigurer_test.go
+++ b/pkg/ssh/sshconfigurer_test.go
@@ -40,10 +40,6 @@ var somePlainWorkspaces = []entity.Workspace{
type DummyStore struct{}
-func (d DummyStore) GetWorkspaces() ([]entity.Workspace, error) {
- return []entity.Workspace{}, nil
-}
-
type DummySSHConfigurerV2Store struct{}
func (d DummySSHConfigurerV2Store) GetWSLHostUserSSHConfigPath() (string, error) {
diff --git a/pkg/store/authtoken.go b/pkg/store/authtoken.go
index 6221487b..2b7e1ede 100644
--- a/pkg/store/authtoken.go
+++ b/pkg/store/authtoken.go
@@ -18,10 +18,6 @@ const (
brevDirectory = ".brev"
)
-func GetBrevDirectory() string {
- return brevDirectory
-}
-
func (f FileStore) SaveAuthTokens(token entity.AuthTokens) error {
if token.AccessToken == "" {
return fmt.Errorf("access token is empty")
diff --git a/pkg/store/http.go b/pkg/store/http.go
index a0a8fc58..0e26e85a 100644
--- a/pkg/store/http.go
+++ b/pkg/store/http.go
@@ -36,14 +36,6 @@ type OllamaHTTPClient struct {
restyClient *resty.Client
}
-func NewOllamaHTTPClient(ollamaAPIURL string) *OllamaHTTPClient {
- restyClient := resty.New().SetBaseURL(ollamaAPIURL)
-
- return &OllamaHTTPClient{
- restyClient: restyClient,
- }
-}
-
func NewNoAuthHTTPClient(brevAPIURL string) *NoAuthHTTPClient {
restyClient := NewRestyClient(brevAPIURL)
return &NoAuthHTTPClient{restyClient}
diff --git a/pkg/terminal/display.go b/pkg/terminal/display.go
index e127caa2..398802eb 100644
--- a/pkg/terminal/display.go
+++ b/pkg/terminal/display.go
@@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"os"
- "os/exec"
breverrors "github.com/brevdev/brev-cli/pkg/errors"
"github.com/manifoldco/promptui"
@@ -98,43 +97,6 @@ func DisplayBrevLogo(t *Terminal) { //nolint:funlen // logo
t.Vprint(" ###@@@@@##")
}
-func DisplayVSCodeInstructions(t *Terminal) {
- t.Print("Run the following steps")
- t.Print("")
- t.Print("\t1) Install the following VSCode extension: " + t.Yellow("ms-vscode-remote.remote-ssh") + ".")
- t.Print("\t2) In VS Code, open the Command Palette and type in " + t.Yellow("Remote-SSH: Connect to Host...") + "to begin.")
-}
-
-func DisplayGatewayAlreadyInstalledInstructions(t *Terminal) {
- t.Print(t.Yellow("You already have JetBrains Gateway installed!"))
- t.Print("Run " + t.Green("brev jetbrains") + " and then open Gateway to begin.")
-}
-
-func DisplayToolboxInstalledInstructions(t *Terminal) {
- t.Print(t.Yellow("You already have JetBrains Toolbox installed!"))
- t.Print("")
- t.Print("\t1) Install JetBrains Gateway from Toolbox.")
- t.Print("\t2) Run " + t.Green("brev jetbrains") + " and then open Gateway to begin.")
-}
-
-func InstallVSCodeExtension(t *Terminal) {
- cmdd := exec.Command("which code")
- output, _ := cmdd.Output()
- t.Vprintf("%b", output)
- _, err := cmdd.Output()
-
- if err != nil {
- t.Vprintf(t.Yellow("Please install the following VS Code extension: ms-vscode-remote.remote-ssh\n"))
- } else {
- install := exec.Command("code --install-extension ms-vscode-remote.remote-ssh\n")
- _, err := install.Output()
- if err != nil {
- t.Vprintf("Please install the following VS Code extension: ms-vscode-remote.remote-ssh\n")
- }
-
- }
-}
-
type PromptContent struct {
ErrorMsg string
Label string
diff --git a/pkg/terminal/terminal.go b/pkg/terminal/terminal.go
index a492fb56..9d3a1a5f 100644
--- a/pkg/terminal/terminal.go
+++ b/pkg/terminal/terminal.go
@@ -50,22 +50,10 @@ func New() (t *Terminal) {
}
}
-func (t *Terminal) SetVerbose(verbose bool) {
- if verbose {
- t.out = os.Stdout
- } else {
- t.out = silentWriter{}
- }
-}
-
func (t *Terminal) Print(a string) {
fmt.Fprintln(t.out, a)
}
-func (t *Terminal) Printf(format string, a ...interface{}) {
- fmt.Fprintf(t.out, format, a...)
-}
-
func (t *Terminal) Vprint(a string) {
fmt.Fprintln(t.verbose, a)
}
@@ -92,22 +80,8 @@ func (t *Terminal) Errprint(err error, a string) {
}
}
-func (t *Terminal) Errprintf(err error, format string, a ...interface{}) {
- t.Eprint(t.Red("Error: " + err.Error()))
- if a != nil {
- t.Eprint(t.Red(format, a))
- }
- if brevErr, ok := err.(breverrors.BrevError); ok {
- t.Eprint(t.Red(brevErr.Directive()))
- }
-}
-
type silentWriter struct{}
-func (w silentWriter) Write(_ []byte) (n int, err error) {
- return 0, nil
-}
-
func (t *Terminal) NewSpinner() *spinner.Spinner {
spinner := spinner.New(spinner.CharSets[11], 100*time.Millisecond, spinner.WithWriter(os.Stderr))
err := spinner.Color("cyan", "bold")
@@ -118,39 +92,3 @@ func (t *Terminal) NewSpinner() *spinner.Spinner {
return spinner
}
-
-func (t *Terminal) NewProgressBar(description string, onComplete func()) *ProgressBar {
- bar := progressbar.NewOptions(ProgressBarMax,
- progressbar.OptionOnCompletion(onComplete),
- progressbar.OptionEnableColorCodes(true),
- progressbar.OptionShowBytes(false),
- progressbar.OptionSetWidth(15),
- progressbar.OptionSetDescription(description),
- progressbar.OptionSetTheme(progressbar.Theme{
- Saucer: "[green]=[reset]",
- SaucerHead: "[green]🤙[reset]",
- SaucerPadding: " ",
- BarStart: "[",
- BarEnd: "]",
- }))
-
- return &ProgressBar{
- Bar: bar,
- CurrPercentage: 0,
- }
-}
-
-func (bar *ProgressBar) AdvanceTo(percentage int) {
- for bar.CurrPercentage < percentage && bar.CurrPercentage <= 100 {
- bar.CurrPercentage++
- err := bar.Bar.Add(1)
- if err != nil {
- panic(err)
- }
- time.Sleep(5 * time.Millisecond)
- }
-}
-
-func (bar *ProgressBar) Describe(text string) {
- bar.Bar.Describe(text)
-}
diff --git a/pkg/uri/uri.go b/pkg/uri/uri.go
index af4de490..77757147 100644
--- a/pkg/uri/uri.go
+++ b/pkg/uri/uri.go
@@ -12,13 +12,6 @@ type (
URL string
)
-func NewHostFromString(host string) (Host, error) {
- if strings.HasPrefix(host, "http") {
- return "", fmt.Errorf("host can not start with 'http'")
- }
- return Host(host), nil
-}
-
func (h Host) AddPrefix(prefix string) Host {
return Host(fmt.Sprintf("%s%s", prefix, h))
}
diff --git a/pkg/workspacemanagerv2/volumes.go b/pkg/workspacemanagerv2/volumes.go
index dbfe9e22..14ce1294 100644
--- a/pkg/workspacemanagerv2/volumes.go
+++ b/pkg/workspacemanagerv2/volumes.go
@@ -103,39 +103,7 @@ type SymLinkVolume struct {
MountToPath string
}
-var _ Volume = SymLinkVolume{}
-
-func NewSymLinkVolume(fromSymLinkPath string, localVolumePath string, mountToPath string) *SymLinkVolume {
- return &SymLinkVolume{
- FromSymLinkPath: fromSymLinkPath,
- LocalVolumePath: localVolumePath,
- MountToPath: mountToPath,
- }
-}
-
-func (s SymLinkVolume) GetIdentifier() string {
- return s.LocalVolumePath
-}
-
-func (s SymLinkVolume) GetMountToPath() string {
- return s.MountToPath
-}
-
-func (s SymLinkVolume) Setup(_ context.Context) error {
- err := os.Symlink(s.FromSymLinkPath, s.LocalVolumePath)
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
- return nil
-}
-
-func (s SymLinkVolume) Teardown(_ context.Context) error {
- err := os.RemoveAll(s.LocalVolumePath)
- if err != nil {
- return breverrors.WrapAndTrace(err)
- }
- return nil
-}
+// Deprecated: var _ Volume = SymLinkVolume{}
type DynamicVolume struct {
FromMountPathPrefix string
@@ -143,38 +111,4 @@ type DynamicVolume struct {
FileMap map[string]func(string)
}
-// can be push or polled based?
-
-var _ Volume = DynamicVolume{}
-
-func NewDynamicVolume(path string, fileMap map[string]func(string)) *DynamicVolume {
- return &DynamicVolume{ToMountPath: path, FileMap: fileMap}
-}
-
-func (s DynamicVolume) WithPathPrefix(prefix string) DynamicVolume {
- s.FromMountPathPrefix = prefix
- return s
-}
-
-func (s DynamicVolume) GetIdentifier() string {
- return ""
-}
-
-func (s DynamicVolume) GetMountToPath() string {
- return ""
-}
-
-func (s DynamicVolume) GetMountFromPath() string {
- return s.FromMountPathPrefix
-}
-
-func (s DynamicVolume) Setup(_ context.Context) error {
- for f, d := range s.FileMap {
- d(filepath.Join(s.GetMountFromPath(), f))
- }
- return nil
-}
-
-func (s DynamicVolume) Teardown(_ context.Context) error {
- return nil
-}
+// Deprecated: var _ Volume = DynamicVolume{}