Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Package manager login command - Docker, Podman #1304

Merged
merged 66 commits into from
Dec 28, 2024
Merged
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
bb36015
Improve repositores code
sverdlov93 Oct 25, 2024
6583684
Improve repositores code
sverdlov93 Oct 25, 2024
fb20e20
Improve repositores code
sverdlov93 Oct 27, 2024
9a20c6c
Merge branch 'dev' of https://github.com/jfrog/jfrog-cli-core into np…
sverdlov93 Oct 29, 2024
ed7b39d
Improve repositores code
sverdlov93 Oct 30, 2024
633d8a0
Improve repositores code
sverdlov93 Nov 3, 2024
74c9a47
Improve repositores code
sverdlov93 Nov 3, 2024
e0e5024
Improve repositores code
sverdlov93 Nov 4, 2024
f51ae6d
Improve repositores code
sverdlov93 Nov 4, 2024
7233563
Merge branch 'dev' into npm-login
sverdlov93 Nov 5, 2024
f8e793a
Improve repositores code
sverdlov93 Nov 6, 2024
c53b4c2
Merge branch 'npm-login' of https://github.com/sverdlov93/jfrog-cli-c…
sverdlov93 Nov 6, 2024
c3e0486
Improve repositores code
sverdlov93 Nov 6, 2024
e8cc9f8
Improve repositores code
sverdlov93 Nov 6, 2024
95ba696
Improve repositores code
sverdlov93 Nov 6, 2024
3dff2bb
Improve repositores code
sverdlov93 Nov 6, 2024
0f0856e
Improve repositores code
sverdlov93 Nov 6, 2024
f280aa5
Improve repositores code
sverdlov93 Nov 6, 2024
ecb74bb
Improve repositores code
sverdlov93 Nov 6, 2024
cd0fda3
Improve repositores code
sverdlov93 Nov 6, 2024
547fa02
Improve repositores code
sverdlov93 Nov 6, 2024
265fea7
Improve repositores code
sverdlov93 Nov 6, 2024
e8f884c
Improve repositores code
sverdlov93 Nov 7, 2024
2ee5950
Merge branch 'dev' of https://github.com/jfrog/jfrog-cli-core into np…
sverdlov93 Nov 7, 2024
aec982a
Improve repositores code
sverdlov93 Nov 7, 2024
57df296
Improve repositores code
sverdlov93 Nov 7, 2024
e8d5842
Improve repositores code
sverdlov93 Nov 7, 2024
f84e6f8
Improve repositores code
sverdlov93 Nov 7, 2024
8c2b1c6
Merge branch 'dev' into npm-login
sverdlov93 Nov 10, 2024
e6afac1
Merge branch 'dev' of https://github.com/jfrog/jfrog-cli-core into np…
sverdlov93 Nov 10, 2024
f6eed54
Merge branch 'dev' into npm-login
sverdlov93 Nov 11, 2024
be5cdcb
Improve upload archive progress bar
sverdlov93 Nov 11, 2024
1087833
Merge remote-tracking branch 'sverdlov93/npm-login' into npm-login
sverdlov93 Nov 11, 2024
cd0ce91
Improve upload archive progress bar
sverdlov93 Nov 11, 2024
31b0627
Improve upload archive progress bar
sverdlov93 Nov 11, 2024
89cdb97
Improve upload archive progress bar
sverdlov93 Nov 11, 2024
02252d2
Improve upload archive progress bar
sverdlov93 Nov 11, 2024
76fd3b4
Improve upload archive progress bar
sverdlov93 Nov 11, 2024
77e8d71
Improve upload archive progress bar
sverdlov93 Nov 12, 2024
f28f014
Improve upload archive progress bar
sverdlov93 Nov 12, 2024
0e959a3
Improve upload archive progress bar
sverdlov93 Nov 12, 2024
01e0f45
Improve upload archive progress bar
sverdlov93 Nov 12, 2024
95bf72e
Improve upload archive progress bar
sverdlov93 Nov 12, 2024
c90cbb3
Improve upload archive progress bar
sverdlov93 Nov 12, 2024
5f37066
Improve upload archive progress bar
sverdlov93 Nov 12, 2024
1ecb8ed
Improve upload archive progress bar
sverdlov93 Nov 12, 2024
6e3f8b9
Improve upload archive progress bar
sverdlov93 Nov 17, 2024
07af542
Merge branch 'dev' of https://github.com/jfrog/jfrog-cli-core into np…
sverdlov93 Nov 17, 2024
746d67d
Improve upload archive progress bar
sverdlov93 Nov 20, 2024
5f8e0aa
Merge branch 'dev' of https://github.com/jfrog/jfrog-cli-core into np…
sverdlov93 Nov 20, 2024
43d1a80
Improve upload archive progress bar
sverdlov93 Nov 21, 2024
3f8ab57
Merge branch 'dev' of https://github.com/jfrog/jfrog-cli-core into np…
sverdlov93 Dec 16, 2024
b73d2eb
Merge branch 'dev' into npm-login
sverdlov93 Dec 22, 2024
0d5e16b
Merge branch 'dev' of https://github.com/jfrog/jfrog-cli-core into np…
sverdlov93 Dec 22, 2024
bc7f2d4
Merge branch 'dev' of https://github.com/jfrog/jfrog-cli-core into np…
sverdlov93 Dec 24, 2024
6e5def8
Improve upload archive progress bar
sverdlov93 Dec 24, 2024
a89e2f5
Improve upload archive progress bar
sverdlov93 Dec 24, 2024
e8566f1
Merge remote-tracking branch 'sverdlov93/npm-login' into npm-login
sverdlov93 Dec 24, 2024
3a1bcf0
Improve upload archive progress bar
sverdlov93 Dec 25, 2024
52894c8
Improve upload archive progress bar
sverdlov93 Dec 25, 2024
3a0f99b
Merge branch 'dev' into npm-login
sverdlov93 Dec 25, 2024
70015a8
Merge branch 'dev' into npm-login
sverdlov93 Dec 26, 2024
dc79716
Improve upload archive progress bar
sverdlov93 Dec 26, 2024
4355159
Merge remote-tracking branch 'sverdlov93/npm-login' into npm-login
sverdlov93 Dec 26, 2024
4908ff5
Improve upload archive progress bar
sverdlov93 Dec 26, 2024
84f28a3
Merge branch 'dev' into npm-login
sverdlov93 Dec 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion artifactory/commands/container/containermanagercommand.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ func (cm *ContainerCommand) PerformLogin(serverDetails *config.ServerDetails, co
}
}
loginConfig := &container.ContainerManagerLoginConfig{ServerDetails: serverDetails}
return container.ContainerManagerLogin(cm.image, loginConfig, containerManagerType)
imageRegistry, err := cm.image.GetRegistry()
if err != nil {
return err
}
return container.ContainerManagerLogin(imageRegistry, loginConfig, containerManagerType)
}
return nil
}
97 changes: 85 additions & 12 deletions artifactory/commands/packagemanagerlogin/packagemanagerlogin.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,42 @@ import (
"github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/repository"
commandsutils "github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/utils"
"github.com/jfrog/jfrog-cli-core/v2/artifactory/utils"
"github.com/jfrog/jfrog-cli-core/v2/artifactory/utils/container"
"github.com/jfrog/jfrog-cli-core/v2/artifactory/utils/npm"
"github.com/jfrog/jfrog-cli-core/v2/artifactory/utils/yarn"
"github.com/jfrog/jfrog-cli-core/v2/common/project"
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
"github.com/jfrog/jfrog-client-go/artifactory/services"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
"github.com/jfrog/jfrog-client-go/utils/log"
"golang.org/x/exp/maps"
"net/url"
"sort"
)

// packageManagerToRepositoryPackageType maps project types to corresponding Artifactory repository package types.
var packageManagerToRepositoryPackageType = map[project.ProjectType]string{
// Npm package managers
project.Npm: repository.Npm,
project.Yarn: repository.Npm,

// Python (pypi) package managers
project.Pip: repository.Pypi,
project.Pipenv: repository.Pypi,
project.Poetry: repository.Pypi,

// Nuget package managers
project.Nuget: repository.Nuget,
project.Dotnet: repository.Nuget,

// Docker package managers
project.Docker: repository.Docker,
project.Podman: repository.Docker,

project.Go: repository.Go,
}

// PackageManagerLoginCommand configures registries and authentication for various package manager (npm, Yarn, Pip, Pipenv, Poetry, Go)
type PackageManagerLoginCommand struct {
// packageManager represents the type of package manager (e.g., NPM, Yarn).
Expand All @@ -40,20 +67,31 @@ func NewPackageManagerLoginCommand(packageManager project.ProjectType) *PackageM
}
}

// GetSupportedPackageManagersList returns a sorted list of supported package managers.
func GetSupportedPackageManagersList() []project.ProjectType {
allSupportedPackageManagers := maps.Keys(packageManagerToRepositoryPackageType)
sort.Slice(allSupportedPackageManagers, func(i, j int) bool {
return allSupportedPackageManagers[i] < allSupportedPackageManagers[j]
})
return allSupportedPackageManagers
}

func IsSupportedPackageManager(packageManager project.ProjectType) bool {
_, exists := packageManagerToRepositoryPackageType[packageManager]
return exists
}

// packageManagerToPackageType maps project types to corresponding Artifactory package types (e.g., npm, pypi).
func packageManagerToPackageType(packageManager project.ProjectType) (string, error) {
switch packageManager {
case project.Npm, project.Yarn:
return repository.Npm, nil
case project.Pip, project.Pipenv, project.Poetry:
return repository.Pypi, nil
case project.Go:
return repository.Go, nil
case project.Nuget, project.Dotnet:
return repository.Nuget, nil
default:
return "", errorutils.CheckErrorf("unsupported package manager: %s", packageManager)
// Retrieve the package type from the map.
if packageType, exists := packageManagerToRepositoryPackageType[packageManager]; exists {
return packageType, nil
}
if !IsSupportedPackageManager(packageManager) {
return "", errorutils.CheckErrorf("unsupported package type for package manager: %s", packageManager)
}
// Return an error if the package manager is unsupported.
return packageManagerToRepositoryPackageType[packageManager], nil
}

// CommandName returns the name of the login command.
Expand Down Expand Up @@ -95,14 +133,16 @@ func (pmlc *PackageManagerLoginCommand) Run() (err error) {
err = pmlc.configureGo()
case project.Nuget, project.Dotnet:
err = pmlc.configureDotnetNuget()
case project.Docker, project.Podman:
err = pmlc.configureContainer()
default:
err = errorutils.CheckErrorf("unsupported package manager: %s", pmlc.packageManager)
}
if err != nil {
return fmt.Errorf("failed to configure %s: %w", pmlc.packageManager.String(), err)
}

log.Info(fmt.Sprintf("Successfully configured %s to use JFrog Artifactory repository '%s'.", pmlc.packageManager.String(), pmlc.repoName))
log.Output(fmt.Sprintf("Successfully configured %s to use JFrog Artifactory repository '%s'.", coreutils.PrintBoldTitle(pmlc.packageManager.String()), coreutils.PrintBoldTitle(pmlc.repoName)))
return nil
}

Expand Down Expand Up @@ -239,3 +279,36 @@ func (pmlc *PackageManagerLoginCommand) configureDotnetNuget() error {
// Add the repository as a source in the NuGet configuration with credentials for authentication.
return dotnet.AddSourceToNugetConfig(toolchainType, sourceUrl, user, password)
}

// configureContainer configures container managers like Docker or Podman to authenticate with JFrog Artifactory.
// It performs a login using the container manager's CLI command.
//
// For Docker:
//
// docker login <artifactory-url-without-scheme> -u <username> -p <password>
//
// For Podman:
//
// podman login <artifactory-url-without-scheme> -u <username> -p <password>
sverdlov93 marked this conversation as resolved.
Show resolved Hide resolved
func (pmlc *PackageManagerLoginCommand) configureContainer() error {
var containerManagerType container.ContainerManagerType
switch pmlc.packageManager {
case project.Docker:
containerManagerType = container.DockerClient
case project.Podman:
containerManagerType = container.Podman
default:
return errorutils.CheckErrorf("unsupported container manager: %s", pmlc.packageManager)
}
// Parse the URL to remove the scheme (https:// or http://)
parsedURL, err := url.Parse(pmlc.serverDetails.GetUrl())
sverdlov93 marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return err
}
urlWithoutScheme := parsedURL.Host + parsedURL.Path
return container.ContainerManagerLogin(
urlWithoutScheme,
&container.ContainerManagerLoginConfig{ServerDetails: pmlc.serverDetails},
containerManagerType,
)
}
8 changes: 2 additions & 6 deletions artifactory/utils/container/containermanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,7 @@ func (loginCmd *LoginCmd) RunCmd() error {

// First we'll try to log in assuming a proxy-less tag (e.g. "registry-address/docker-repo/image:ver").
// If fails, we will try assuming a reverse proxy tag (e.g. "registry-address-docker-repo/image:ver").
func ContainerManagerLogin(image *Image, config *ContainerManagerLoginConfig, containerManager ContainerManagerType) error {
imageRegistry, err := image.GetRegistry()
if err != nil {
return err
}
func ContainerManagerLogin(imageRegistry string, config *ContainerManagerLoginConfig, containerManager ContainerManagerType) error {
username := config.ServerDetails.User
password := config.ServerDetails.Password
// If access-token exists, perform login with it.
Expand All @@ -206,7 +202,7 @@ func ContainerManagerLogin(image *Image, config *ContainerManagerLoginConfig, co
}
// Perform login.
cmd := &LoginCmd{DockerRegistry: imageRegistry, Username: username, Password: password, containerManager: containerManager}
err = cmd.RunCmd()
err := cmd.RunCmd()
if exitCode := coreutils.GetExitCode(err, 0, 0, false); exitCode == coreutils.ExitCodeNoError {
// Login succeeded
return nil
Expand Down
3 changes: 2 additions & 1 deletion artifactory/utils/repositoryutils.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package utils

import (
"fmt"
"github.com/jfrog/gofrog/datastructures"
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
"github.com/jfrog/jfrog-cli-core/v2/utils/ioutils"
Expand Down Expand Up @@ -101,7 +102,7 @@ func SelectRepositoryInteractively(serverDetails *config.ServerDetails, repoFilt
return filteredRepos[0], nil
}
// Prompt the user to select a repository.
return ioutils.AskFromListWithMismatchConfirmation("Please select a repository to login to:", "Repository not found.", ioutils.ConvertToSuggests(filteredRepos)), nil
return ioutils.AskFromListWithMismatchConfirmation(fmt.Sprintf("Please select a %s %s repository to configure:", repoFilterParams.RepoType, repoFilterParams.PackageType), "Repository not found.", ioutils.ConvertToSuggests(filteredRepos)), nil
}

// GetFilteredRepositoriesWithFilterParams returns the names of local, remote, virtual, and federated repositories filtered by their names and type.
Expand Down
15 changes: 15 additions & 0 deletions common/project/projectconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const (
type ProjectType int

const (
// When adding new ProjectType here, Must also add it as a string to the ProjectTypes slice
Go ProjectType = iota
Pip
Pipenv
Expand All @@ -41,6 +42,8 @@ const (
Terraform
Cocoapods
Swift
Docker
Podman
)

type ConfigType string
Expand All @@ -66,12 +69,24 @@ var ProjectTypes = []string{
"terraform",
"cocoapods",
"swift",
"docker",
"podman",
}

func (projectType ProjectType) String() string {
return ProjectTypes[projectType]
}

// FromString converts a string to its corresponding ProjectType
func FromString(value string) ProjectType {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this function used?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jem @yahavi

for i, v := range ProjectTypes {
sverdlov93 marked this conversation as resolved.
Show resolved Hide resolved
if v == value {
return ProjectType(i)
}
}
return -1
}

type MissingResolverErr struct {
message string
}
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,14 @@ require (
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
golang.org/x/crypto v0.31.0 // indirect
golang.org/x/net v0.31.0 // indirect
golang.org/x/net v0.33.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/tools v0.27.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
)

replace github.com/jfrog/jfrog-client-go => github.com/eyalbe4/jfrog-client-go v1.28.1-0.20241223165051-2717483395bc
replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20241223175448-88f1089d0694

// replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go v1.8.9-0.20241121100855-e7a75ceee2bd

Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcej
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/eyalbe4/jfrog-client-go v1.28.1-0.20241223165051-2717483395bc h1:VLvI2P75Fc8iJVrydKEMcmeBCcKeUHmB7lLEm5P8aYU=
github.com/eyalbe4/jfrog-client-go v1.28.1-0.20241223165051-2717483395bc/go.mod h1:2ySOMva54L3EYYIlCBYBTcTgqfrrQ19gtpA/MWfA/ec=
github.com/forPelevin/gomoji v1.2.0 h1:9k4WVSSkE1ARO/BWywxgEUBvR/jMnao6EZzrql5nxJ8=
github.com/forPelevin/gomoji v1.2.0/go.mod h1:8+Z3KNGkdslmeGZBC3tCrwMrcPy5GRzAD+gL9NAwMXg=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
Expand Down Expand Up @@ -95,6 +93,8 @@ github.com/jfrog/build-info-go v1.10.7 h1:10NVHYg0193gJpQft+S4WQfvYMtj5jlwwhJRvk
github.com/jfrog/build-info-go v1.10.7/go.mod h1:JcISnovFXKx3wWf3p1fcMmlPdt6adxScXvoJN4WXqIE=
github.com/jfrog/gofrog v1.7.6 h1:QmfAiRzVyaI7JYGsB7cxfAJePAZTzFz0gRWZSE27c6s=
github.com/jfrog/gofrog v1.7.6/go.mod h1:ntr1txqNOZtHplmaNd7rS4f8jpA5Apx8em70oYEe7+4=
github.com/jfrog/jfrog-client-go v1.28.1-0.20241223175448-88f1089d0694 h1:1EP8yAhB+SGTXhfGa/w4S748S12qJKXU4u/yiAJxnX0=
github.com/jfrog/jfrog-client-go v1.28.1-0.20241223175448-88f1089d0694/go.mod h1:2ySOMva54L3EYYIlCBYBTcTgqfrrQ19gtpA/MWfA/ec=
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
Expand Down Expand Up @@ -229,8 +229,8 @@ golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
Expand Down
8 changes: 6 additions & 2 deletions utils/ioutils/questionnaire.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package ioutils

import (
"fmt"
"os"
"regexp"
"strconv"
"strings"
Expand Down Expand Up @@ -82,7 +84,9 @@ func interruptKeyBind() prompt.Option {
interrupt := prompt.KeyBind{
Key: prompt.ControlC,
Fn: func(buf *prompt.Buffer) {
panic("Interrupted")
// Gracefully exit the program
fmt.Println("\nOperation interrupted. Exiting...")
os.Exit(0)
sverdlov93 marked this conversation as resolved.
Show resolved Hide resolved
},
}
return prompt.OptionAddKeyBind(interrupt)
Expand Down Expand Up @@ -177,7 +181,7 @@ func validateAnswer(answer string, options []prompt.Suggest, allowVars bool) boo
// If the provided answer does not appear in list, confirm the choice.
func AskFromListWithMismatchConfirmation(promptPrefix, misMatchMsg string, options []prompt.Suggest) string {
for {
answer := prompt.Input(promptPrefix+" ", prefixCompleter(options), interruptKeyBind())
answer := prompt.Input(promptPrefix+" ", prefixCompleter(options), interruptKeyBind(), prompt.OptionShowCompletionAtStart(), prompt.OptionCompletionOnDown())
if answer == "" {
log.Output(EmptyValueMsg)
}
Expand Down
Loading