package gitea import ( "bufio" "fmt" "os" "path/filepath" "strings" "syscall" "code.gitea.io/sdk/gitea" "github.com/pkg/errors" "golang.org/x/crypto/ssh/terminal" ) type Options struct { gitea.CreateReleaseOption Attachments []string Token string Username string Password string BaseURL string } type OptionFunc func(*Options) func WithAttachments(attachments ...string) OptionFunc { return func(opts *Options) { opts.Attachments = attachments } } func WithAttachmentPatterns(patterns ...string) OptionFunc { attachments := make([]string, 0) for _, p := range patterns { files, err := filepath.Glob(p) if err != nil { panic(errors.Wrapf(err, "error while searching files matching '%s' pattern", p)) } attachments = append(attachments, files...) } return WithAttachments(attachments...) } func WithBaseURL(baseURL string) OptionFunc { return func(opts *Options) { opts.BaseURL = baseURL } } func WithInteractivePassword() OptionFunc { return func(opts *Options) { fmt.Print("Enter Password: ") password, err := terminal.ReadPassword(syscall.Stdin) fmt.Print("\n") if err != nil { panic(errors.Wrap(err, "error while asking password")) } opts.Password = strings.TrimSpace(string(password)) } } func WithInteractiveUsername() OptionFunc { return func(opts *Options) { username, err := ask("Enter Username:", "") if err != nil { panic(errors.Wrap(err, "error while asking username")) } opts.Username = username } } func WithEnvUsername() OptionFunc { return func(opts *Options) { opts.Username = os.Getenv("GITEA_USERNAME") } } func WithEnvPassword() OptionFunc { return func(opts *Options) { opts.Password = os.Getenv("GITEA_PASSWORD") } } func WithAutoUsername() OptionFunc { envUsername := WithEnvUsername() interactiveUsername := WithInteractiveUsername() return func(opts *Options) { envUsername(opts) if opts.Username != "" { return } interactiveUsername(opts) } } func WithAutoPassword() OptionFunc { envPassword := WithEnvPassword() interactivePassword := WithInteractivePassword() return func(opts *Options) { envPassword(opts) if opts.Password != "" { return } interactivePassword(opts) } } func WithInteractiveTarget() OptionFunc { return func(opts *Options) { target, err := ask("Enter Target:", CurrentRevision()) if err != nil { panic(errors.Wrap(err, "error while asking target")) } opts.Target = target } } func WithInteractiveTag() OptionFunc { return func(opts *Options) { tagName, err := ask("Enter Tag:", LatestTag()) if err != nil { panic(errors.Wrap(err, "error while asking tag")) } opts.TagName = tagName } } func WithInteractiveTitle() OptionFunc { return func(opts *Options) { defaultTitle := fmt.Sprintf("Release %s", LatestTag()) title, err := ask("Enter Title:", defaultTitle) if err != nil { panic(errors.Wrap(err, "error while asking title")) } opts.Title = title } } func ask(question, defaultValue string) (string, error) { reader := bufio.NewReader(os.Stdin) if defaultValue != "" { fmt.Printf("%s (default: %s) ", question, defaultValue) } else { fmt.Printf("%s ", question) } res, err := reader.ReadString('\n') if err != nil { return "", err } result := strings.TrimSpace(res) if result == "" { return defaultValue, nil } return result, nil } func defaultOptions() *Options { return &Options{ CreateReleaseOption: gitea.CreateReleaseOption{ IsDraft: false, IsPrerelease: true, Note: "", Target: "master", Title: "test", TagName: "test", }, Attachments: make([]string, 0), } }