mirror of
https://github.com/onyx-and-iris/lottery-cli.git
synced 2026-08-17 08:44:25 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1310447664 | |||
| 3f0af6e5ec |
30
README.md
30
README.md
@@ -20,6 +20,7 @@ go install github.com/onyx-and-iris/lottery-cli/cmd/lottery@latest
|
|||||||
|
|
||||||
*flags*
|
*flags*
|
||||||
|
|
||||||
|
- --kind/-k: The kind of lottery.
|
||||||
- --count/-c: Number of draws to generate.
|
- --count/-c: Number of draws to generate.
|
||||||
- --count-prompt/-C: Prompt for the number of draws to generate.
|
- --count-prompt/-C: Prompt for the number of draws to generate.
|
||||||
> Note. If both --count and --count-prompt are passed the count prompt will win.
|
> Note. If both --count and --count-prompt are passed the count prompt will win.
|
||||||
@@ -29,19 +30,42 @@ go install github.com/onyx-and-iris/lottery-cli/cmd/lottery@latest
|
|||||||
```bash
|
```bash
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
export LOTTERY_KIND=lotto
|
||||||
export LOTTERY_COUNT=3
|
export LOTTERY_COUNT=3
|
||||||
export LOTTERY_COUNT_PROMPT=false
|
export LOTTERY_COUNT_PROMPT=false
|
||||||
```
|
```
|
||||||
|
|
||||||
## Use
|
## Use
|
||||||
|
|
||||||
There are no subcommands, just run the CLI directly passing any desired flags:
|
Run with the selection prompt without prompting for a count:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
lottery --count=3
|
lottery
|
||||||
```
|
```
|
||||||
|
|
||||||
You will then be entered into the selection prompt.
|
Run with the selection prompt but also prompt for a count:
|
||||||
|
|
||||||
|
```console
|
||||||
|
lottery --count-prompt
|
||||||
|
```
|
||||||
|
|
||||||
|
Run with the selection prompt but pass in the count directly:
|
||||||
|
|
||||||
|
```console
|
||||||
|
lottery --count=4
|
||||||
|
```
|
||||||
|
|
||||||
|
Run a single draw directly:
|
||||||
|
|
||||||
|
```console
|
||||||
|
lottery -k=euromillions
|
||||||
|
```
|
||||||
|
|
||||||
|
Run multiple draws directly:
|
||||||
|
|
||||||
|
```console
|
||||||
|
lottery -k=euromillions -c=3
|
||||||
|
```
|
||||||
|
|
||||||
## Special Thanks
|
## Special Thanks
|
||||||
|
|
||||||
|
|||||||
@@ -32,9 +32,19 @@ func versionFromBuild() string {
|
|||||||
var cmd = &cobra.Command{
|
var cmd = &cobra.Command{
|
||||||
Use: "lottery",
|
Use: "lottery",
|
||||||
Short: "A CLI for National Lottery games.",
|
Short: "A CLI for National Lottery games.",
|
||||||
|
PreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
kindStr := viper.GetString("kind")
|
||||||
|
if kindStr != "" {
|
||||||
|
_, err := lottery.ParseKind(kindStr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
var selected string
|
kindStr := viper.GetString("kind")
|
||||||
|
if kindStr == "" {
|
||||||
form := huh.NewForm(
|
form := huh.NewForm(
|
||||||
huh.NewGroup(
|
huh.NewGroup(
|
||||||
huh.NewSelect[string]().
|
huh.NewSelect[string]().
|
||||||
@@ -46,15 +56,16 @@ var cmd = &cobra.Command{
|
|||||||
huh.NewOption("Thunderball", "thunderball"),
|
huh.NewOption("Thunderball", "thunderball"),
|
||||||
huh.NewOption("Powerball", "powerball"),
|
huh.NewOption("Powerball", "powerball"),
|
||||||
).
|
).
|
||||||
Value(&selected),
|
Value(&kindStr),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
err := form.Run()
|
err := form.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
kind, err := lottery.ParseKind(selected)
|
kind, err := lottery.ParseKind(kindStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -81,10 +92,19 @@ var cmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
count := viper.GetInt("count")
|
count := viper.GetInt("count")
|
||||||
|
includeDrawHeading := count > 1
|
||||||
|
renders := make([]string, 0, count)
|
||||||
|
drawTitle := "Lottery"
|
||||||
|
|
||||||
for range count {
|
for i := range count {
|
||||||
l.Draw()
|
l.Draw()
|
||||||
fmt.Println(renderDraw(l))
|
title, entry := renderDrawEntry(l, i+1, includeDrawHeading)
|
||||||
|
drawTitle = title
|
||||||
|
renders = append(renders, entry)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(renders) > 0 {
|
||||||
|
fmt.Println(renderDrawCollection(drawTitle, renders))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -92,6 +112,7 @@ var cmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
cmd.Flags().StringP("kind", "k", "", "Lottery kind to generate draws for.")
|
||||||
cmd.Flags().IntP("count", "c", 1, "Number of draws to generate.")
|
cmd.Flags().IntP("count", "c", 1, "Number of draws to generate.")
|
||||||
cmd.Flags().BoolP("count-prompt", "C", false, "Prompt for the number of draws to generate.")
|
cmd.Flags().BoolP("count-prompt", "C", false, "Prompt for the number of draws to generate.")
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,24 @@ import (
|
|||||||
"github.com/onyx-and-iris/lottery-cli"
|
"github.com/onyx-and-iris/lottery-cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// nolint:misspell
|
||||||
|
var (
|
||||||
|
titleStyle = lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("12"))
|
||||||
|
drawHeadingStyle = lipgloss.NewStyle().
|
||||||
|
Bold(true).
|
||||||
|
Underline(true).
|
||||||
|
Foreground(lipgloss.Color("14"))
|
||||||
|
labelStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("8"))
|
||||||
|
numbersStyle = lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("10"))
|
||||||
|
specialStyle = lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("11"))
|
||||||
|
separatorStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("8"))
|
||||||
|
cardStyle = lipgloss.NewStyle().
|
||||||
|
BorderStyle(lipgloss.RoundedBorder()).
|
||||||
|
BorderForeground(lipgloss.Color("8")).
|
||||||
|
Padding(0, 1).
|
||||||
|
MarginTop(1)
|
||||||
|
)
|
||||||
|
|
||||||
func formatNumberList(numbers []int) string {
|
func formatNumberList(numbers []int) string {
|
||||||
parts := make([]string, len(numbers))
|
parts := make([]string, len(numbers))
|
||||||
for i, n := range numbers {
|
for i, n := range numbers {
|
||||||
@@ -17,13 +35,7 @@ func formatNumberList(numbers []int) string {
|
|||||||
return strings.Join(parts, " ")
|
return strings.Join(parts, " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint:misspell
|
func drawTitleAndLines(l lottery.Lottery) (string, []string) {
|
||||||
func renderDraw(l lottery.Lottery) string {
|
|
||||||
titleStyle := lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("12"))
|
|
||||||
labelStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("8"))
|
|
||||||
numbersStyle := lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("10"))
|
|
||||||
specialStyle := lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("11"))
|
|
||||||
|
|
||||||
var title string
|
var title string
|
||||||
var lines []string
|
var lines []string
|
||||||
|
|
||||||
@@ -91,12 +103,44 @@ func renderDraw(l lottery.Lottery) string {
|
|||||||
lines = append(lines, "Unknown lottery type")
|
lines = append(lines, "Unknown lottery type")
|
||||||
}
|
}
|
||||||
|
|
||||||
body := strings.Join(lines, "\n")
|
return title, lines
|
||||||
card := lipgloss.NewStyle().
|
}
|
||||||
BorderStyle(lipgloss.RoundedBorder()).
|
|
||||||
BorderForeground(lipgloss.Color("8")).
|
func renderDrawEntry(l lottery.Lottery, drawNumber int, includeHeading bool) (string, string) {
|
||||||
Padding(0, 1).
|
title, lines := drawTitleAndLines(l)
|
||||||
MarginTop(1)
|
|
||||||
|
entry := make([]string, 0, len(lines)+1)
|
||||||
return card.Render(titleStyle.Render(title+" draw") + "\n" + body)
|
if includeHeading {
|
||||||
|
entry = append(entry, drawHeadingStyle.Render("Draw "+strconv.Itoa(drawNumber)))
|
||||||
|
}
|
||||||
|
entry = append(entry, lines...)
|
||||||
|
|
||||||
|
return title, strings.Join(entry, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func maxLineWidth(blocks []string) int {
|
||||||
|
maxWidth := 0
|
||||||
|
for _, block := range blocks {
|
||||||
|
for line := range strings.SplitSeq(block, "\n") {
|
||||||
|
width := lipgloss.Width(line)
|
||||||
|
if width > maxWidth {
|
||||||
|
maxWidth = width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if maxWidth < 12 {
|
||||||
|
return 12
|
||||||
|
}
|
||||||
|
return maxWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
func renderDrawCollection(title string, entries []string) string {
|
||||||
|
if len(entries) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
separator := separatorStyle.Render(strings.Repeat("─", maxLineWidth(entries)))
|
||||||
|
body := strings.Join(entries, "\n"+separator+"\n")
|
||||||
|
|
||||||
|
return cardStyle.Render(titleStyle.Render(title+" draws") + "\n" + body)
|
||||||
}
|
}
|
||||||
|
|||||||
5
kinds.go
5
kinds.go
@@ -25,6 +25,9 @@ func ParseKind(kind string) (Kind, error) {
|
|||||||
case "powerball":
|
case "powerball":
|
||||||
return KindPowerball, nil
|
return KindPowerball, nil
|
||||||
default:
|
default:
|
||||||
return "", fmt.Errorf("invalid lottery kind: %s", kind)
|
return "", fmt.Errorf(
|
||||||
|
"invalid lottery kind: %s, must be one of: lotto, euromillions, setforlife, thunderball, powerball",
|
||||||
|
kind,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
4
util.go
4
util.go
@@ -8,8 +8,8 @@ import (
|
|||||||
// drawUnique returns count unique numbers in the range [1, max].
|
// drawUnique returns count unique numbers in the range [1, max].
|
||||||
// It uses the rand.Perm function to generate a random permutation of numbers and selects the first count numbers from it.
|
// It uses the rand.Perm function to generate a random permutation of numbers and selects the first count numbers from it.
|
||||||
// The result is sorted before being returned.
|
// The result is sorted before being returned.
|
||||||
func drawUnique(count, max int) []int {
|
func drawUnique(count, maxNum int) []int {
|
||||||
perm := rand.Perm(max)
|
perm := rand.Perm(maxNum)
|
||||||
result := make([]int, count)
|
result := make([]int, count)
|
||||||
for i := range result {
|
for i := range result {
|
||||||
result[i] = perm[i] + 1
|
result[i] = perm[i] + 1
|
||||||
|
|||||||
Reference in New Issue
Block a user