Skip to content

Commit 27ff7c9

Browse files
Merge pull request #129 from digitalghost-dev/1.2.0
1.2.0
2 parents cf8fe8d + 7622993 commit 27ff7c9

File tree

18 files changed

+311
-27
lines changed

18 files changed

+311
-27
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ on:
2626
- main
2727

2828
env:
29-
VERSION_NUMBER: 'v1.1.0'
29+
VERSION_NUMBER: 'v1.2.0'
3030
DOCKERHUB_REGISTRY_NAME: 'digitalghostdev/poke-cli'
3131
AWS_REGION: 'us-west-2'
3232

.goreleaser.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ builds:
1414
- windows
1515
- darwin
1616
ldflags:
17-
- -s -w -X main.version=v1.1.0
17+
- -s -w -X main.version=v1.2.0
1818

1919
archives:
2020
- format: tar.gz

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ RUN go mod download
88

99
COPY . .
1010

11-
RUN go build -ldflags "-X main.version=v1.1.0" -o poke-cli .
11+
RUN go build -ldflags "-X main.version=v1.2.0" -o poke-cli .
1212

1313
# build 2
1414
FROM --platform=$BUILDPLATFORM alpine:latest

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<img height="250" width="350" src="pokemon.svg" alt="pokemon-logo"/>
33
<h1>Pokémon CLI</h1>
44
<img src="https://img.shields.io/github/v/release/digitalghost-dev/poke-cli?style=flat-square&logo=git&logoColor=FFCC00&label=Release%20Version&labelColor=EEE&color=FFCC00" alt="version-label">
5-
<img src="https://img.shields.io/docker/image-size/digitalghostdev/poke-cli/v1.1.0?arch=arm64&style=flat-square&logo=docker&logoColor=FFCC00&labelColor=EEE&color=FFCC00" alt="docker-image-size">
5+
<img src="https://img.shields.io/docker/image-size/digitalghostdev/poke-cli/v1.2.0?arch=arm64&style=flat-square&logo=docker&logoColor=FFCC00&labelColor=EEE&color=FFCC00" alt="docker-image-size">
66
<img src="https://img.shields.io/github/actions/workflow/status/digitalghost-dev/poke-cli/ci.yml?branch=main&style=flat-square&logo=github&logoColor=FFCC00&label=CI&labelColor=EEE&color=FFCC00" alt="ci-status-badge">
77
</div>
88
<div align="center">
@@ -76,11 +76,11 @@ View future plans in the [Roadmap](#roadmap) section.
7676
3. Choose how to interact with the container:
7777
* Run a single command and exit:
7878
```bash
79-
docker run --rm -it digitalghostdev/poke-cli:v1.1.0 <command> [subcommand] flag]
79+
docker run --rm -it digitalghostdev/poke-cli:v1.2.0 <command> [subcommand] flag]
8080
```
8181
* Enter the container and use its shell:
8282
```bash
83-
docker run --rm -it --name poke-cli --entrypoint /bin/sh digitalghostdev/poke-cli:v1.1.0 -c "cd /app && exec sh"
83+
docker run --rm -it --name poke-cli --entrypoint /bin/sh digitalghostdev/poke-cli:v1.2.0 -c "cd /app && exec sh"
8484
# placed into the /app directory, run the program with './poke-cli'
8585
# example: ./poke-cli ability swift-swim
8686
```
@@ -121,6 +121,7 @@ By running `poke-cli [-h | --help]`, it'll display information on how to use the
121121
│ │
122122
│ COMMANDS: │
123123
│ ability Get details about an ability │
124+
│ move Get details about a move │
124125
│ natures Get details about all natures │
125126
│ pokemon Get details about a Pokémon │
126127
│ search Search for a resource │
@@ -141,7 +142,7 @@ Below is a list of the planned/completed commands and flags:
141142
- [x] `-p | --pokemon`: display Pokémon that learn this ability.
142143
- [ ] `berry`: get data about a specific berry.
143144
- [ ] `item`: get data about a specific item.
144-
- [ ] `move`: get data about a specific move.
145+
- [x] `move`: get data about a specific move.
145146
- [ ] `-p | --pokemon`: display Pokémon that learn this move.
146147
- [x] `natures`: get data about natures.
147148
- [ ] `pokemon`: get data about a specific Pokémon.

cli.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"flag"
55
"fmt"
66
"github.com/digitalghost-dev/poke-cli/cmd"
7+
"github.com/digitalghost-dev/poke-cli/cmd/move"
78
"github.com/digitalghost-dev/poke-cli/cmd/search"
89
"github.com/digitalghost-dev/poke-cli/flags"
910
"github.com/digitalghost-dev/poke-cli/styling"
@@ -58,6 +59,7 @@ func runCLI(args []string) int {
5859
fmt.Sprintf("\n\t%-15s %s", "-v, --version", "Prints the current version"),
5960
"\n\n", styling.StyleBold.Render("COMMANDS:"),
6061
fmt.Sprintf("\n\t%-15s %s", "ability", "Get details about an ability"),
62+
fmt.Sprintf("\n\t%-15s %s", "move", "Get details about a move"),
6163
fmt.Sprintf("\n\t%-15s %s", "natures", "Get details about all natures"),
6264
fmt.Sprintf("\n\t%-15s %s", "pokemon", "Get details about a Pokémon"),
6365
fmt.Sprintf("\n\t%-15s %s", "search", "Search for a resource"),
@@ -87,6 +89,7 @@ func runCLI(args []string) int {
8789

8890
commands := map[string]func(){
8991
"ability": cmd.AbilityCommand,
92+
"move": move.MoveCommand,
9093
"natures": cmd.NaturesCommand,
9194
"pokemon": cmd.PokemonCommand,
9295
"types": cmd.TypesCommand,
@@ -112,6 +115,7 @@ func runCLI(args []string) int {
112115
fmt.Sprintf("\n\t%-15s", fmt.Sprintf("'%s' is not a valid command.\n", command)),
113116
styling.StyleBold.Render("\nCommands:"),
114117
fmt.Sprintf("\n\t%-15s %s", "ability", "Get details about an ability"),
118+
fmt.Sprintf("\n\t%-15s %s", "move", "Get details about a move"),
115119
fmt.Sprintf("\n\t%-15s %s", "natures", "Get details about all natures"),
116120
fmt.Sprintf("\n\t%-15s %s", "pokemon", "Get details about a Pokémon"),
117121
fmt.Sprintf("\n\t%-15s %s", "search", "Search for a resource"),

cli_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ func TestRunCLI(t *testing.T) {
110110
"│ │\n" +
111111
"│ COMMANDS: │\n" +
112112
"│ ability Get details about an ability │\n" +
113+
"│ move Get details about a move │\n" +
113114
"│ natures Get details about all natures │\n" +
114115
"│ pokemon Get details about a Pokémon │\n" +
115116
"│ search Search for a resource │\n" +
@@ -139,6 +140,7 @@ func TestRunCLI(t *testing.T) {
139140
"│ │\n" +
140141
"│ COMMANDS: │\n" +
141142
"│ ability Get details about an ability │\n" +
143+
"│ move Get details about a move │\n" +
142144
"│ natures Get details about all natures │\n" +
143145
"│ pokemon Get details about a Pokémon │\n" +
144146
"│ search Search for a resource │\n" +
@@ -168,6 +170,7 @@ func TestRunCLI(t *testing.T) {
168170
"│ │\n" +
169171
"│ COMMANDS: │\n" +
170172
"│ ability Get details about an ability │\n" +
173+
"│ move Get details about a move │\n" +
171174
"│ natures Get details about all natures │\n" +
172175
"│ pokemon Get details about a Pokémon │\n" +
173176
"│ search Search for a resource │\n" +

cmd/ability.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func AbilityCommand() {
9898
}
9999

100100
if *pokemonFlag || *shortPokemonFlag {
101-
if err := flags.PokemonFlag(endpoint, abilityName); err != nil {
101+
if err := flags.PokemonAbilitiesFlag(endpoint, abilityName); err != nil {
102102
fmt.Printf("error parsing flags: %v\n", err)
103103
os.Exit(1)
104104
}

cmd/ability_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,25 +51,25 @@ func TestAbilityCommand(t *testing.T) {
5151
name string
5252
args []string
5353
expectedOutput string
54-
expectError bool
54+
expectedError bool
5555
}{
5656
{
5757
name: "Help flag",
5858
args: []string{"ability", "-h"},
5959
expectedOutput: "Get details about a specific ability.",
60-
expectError: false,
60+
expectedError: false,
6161
},
6262
{
6363
name: "Valid Execution",
6464
args: []string{"ability", "stench"},
6565
expectedOutput: styling.StripANSI("Stench\nEffect: Has a 10% chance of making target Pokémon flinch with each hit.\nGeneration: III"),
66-
expectError: false,
66+
expectedError: false,
6767
},
6868
{
6969
name: "Valid Execution",
7070
args: []string{"ability", "poison-puppeteer", "--pokemon"},
7171
expectedOutput: styling.StripANSI("Poison Puppeteer\nEffect: Pokémon poisoned by Pecharunt's moves will also become confused.\nGeneration: IX\n\nPokemon with Poison Puppeteer\n\n 1. Pecharunt"),
72-
expectError: false,
72+
expectedError: false,
7373
},
7474
{
7575
name: "Valid Execution",
@@ -81,7 +81,7 @@ func TestAbilityCommand(t *testing.T) {
8181
1, "Salandit", 2, "Salazzle", 3, "Glimmet",
8282
4, "Glimmora", 5, "Salazzle-Totem",
8383
)),
84-
expectError: false,
84+
expectedError: false,
8585
},
8686
}
8787

@@ -95,7 +95,7 @@ func TestAbilityCommand(t *testing.T) {
9595
output := captureAbilityOutput(func() {
9696
defer func() {
9797
if r := recover(); r != nil {
98-
if !tt.expectError {
98+
if !tt.expectedError {
9999
t.Fatalf("Unexpected error: %v", r)
100100
}
101101
}

cmd/move/move.go

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package move
2+
3+
import (
4+
"flag"
5+
"fmt"
6+
"github.com/charmbracelet/lipgloss"
7+
"github.com/digitalghost-dev/poke-cli/cmd"
8+
"github.com/digitalghost-dev/poke-cli/connections"
9+
"github.com/digitalghost-dev/poke-cli/structs"
10+
"github.com/digitalghost-dev/poke-cli/styling"
11+
"golang.org/x/text/cases"
12+
"golang.org/x/text/language"
13+
"os"
14+
"strconv"
15+
"strings"
16+
)
17+
18+
func MoveCommand() {
19+
flag.Usage = func() {
20+
helpMessage := styling.HelpBorder.Render(
21+
"Get details about a specific move.\n\n",
22+
styling.StyleBold.Render("USAGE:"),
23+
fmt.Sprintf("\n\t%s %s %s %s", "poke-cli", styling.StyleBold.Render("move"), "<move-name>", "[flag]"),
24+
fmt.Sprintf("\n\t%-20s", styling.StyleItalic.Render("Use a hyphen when typing a name with a space.")),
25+
"\n\n",
26+
styling.StyleBold.Render("FLAGS:"),
27+
fmt.Sprintf("\n\t%-20s %s", "-h, --help", "Prints the help menu."),
28+
)
29+
fmt.Println(helpMessage)
30+
}
31+
32+
flag.Parse()
33+
34+
if err := cmd.ValidateMoveArgs(os.Args); err != nil {
35+
fmt.Println(err.Error())
36+
os.Exit(1)
37+
}
38+
39+
args := flag.Args()
40+
41+
endpoint := strings.ToLower(args[0])
42+
moveName := strings.ToLower(args[1])
43+
44+
moveStruct, moveName, err := connections.MoveApiCall(endpoint, moveName, connections.APIURL)
45+
if err != nil {
46+
fmt.Println(err)
47+
if os.Getenv("GO_TESTING") != "1" {
48+
os.Exit(1)
49+
}
50+
}
51+
52+
moveInfoContainer(moveStruct, moveName)
53+
moveEffectContainer(moveStruct)
54+
}
55+
56+
func moveInfoContainer(moveStruct structs.MoveJSONStruct, moveName string) {
57+
capitalizedMove := cases.Title(language.English).String(strings.ReplaceAll(moveName, "-", " "))
58+
59+
docStyle := lipgloss.NewStyle().
60+
Padding(1, 2).
61+
BorderStyle(lipgloss.ThickBorder()).
62+
BorderForeground(lipgloss.Color(styling.GetTypeColor(moveStruct.Type.Name))).
63+
Width(32)
64+
65+
headerStyle := lipgloss.NewStyle().
66+
Bold(true).
67+
Foreground(lipgloss.Color(styling.GetTypeColor(moveStruct.Type.Name))).
68+
PaddingBottom(1)
69+
70+
labelStyle := lipgloss.NewStyle().Bold(true).Width(15)
71+
valueStyle := lipgloss.NewStyle().Faint(true)
72+
73+
header := headerStyle.Render(capitalizedMove)
74+
75+
infoRows := []string{
76+
lipgloss.JoinHorizontal(lipgloss.Top, labelStyle.Render("Type"), "|", valueStyle.Render(cases.Title(language.English).String(moveStruct.Type.Name))),
77+
lipgloss.JoinHorizontal(lipgloss.Top, labelStyle.Render("Power"), "|", valueStyle.Render(strconv.Itoa(moveStruct.Power))),
78+
lipgloss.JoinHorizontal(lipgloss.Top, labelStyle.Render("PP"), "|", valueStyle.Render(strconv.Itoa(moveStruct.PowerPoints))),
79+
lipgloss.JoinHorizontal(lipgloss.Top, labelStyle.Render("Accuracy"), "|", valueStyle.Render(strconv.Itoa(moveStruct.Accuracy))),
80+
lipgloss.JoinHorizontal(lipgloss.Top, labelStyle.Render("Category"), "|", valueStyle.Render(cases.Title(language.English).String(moveStruct.DamageClass.Name))),
81+
lipgloss.JoinHorizontal(lipgloss.Top, labelStyle.Render("Effect Chance"), "|", valueStyle.Render(fmt.Sprintf("%d%%", moveStruct.EffectChance))),
82+
lipgloss.JoinHorizontal(lipgloss.Top, labelStyle.Render("Priority"), "|", valueStyle.Render(strconv.Itoa(moveStruct.Priority))),
83+
}
84+
85+
infoBlock := lipgloss.JoinVertical(lipgloss.Left, infoRows...)
86+
87+
fullDoc := lipgloss.JoinVertical(lipgloss.Top, header, infoBlock)
88+
89+
fmt.Println(docStyle.Render(fullDoc))
90+
}
91+
92+
func moveEffectContainer(moveStruct structs.MoveJSONStruct) {
93+
docStyle := lipgloss.NewStyle().
94+
Padding(1, 2).
95+
BorderStyle(lipgloss.ThickBorder()).
96+
BorderForeground(lipgloss.Color(styling.GetTypeColor(moveStruct.Type.Name))).
97+
Width(32)
98+
99+
var flavorTextEntry string
100+
for _, entry := range moveStruct.FlavorTextEntries {
101+
if entry.Language.Name == "en" && entry.VersionGroup.Name == "scarlet-violet" {
102+
flavorTextEntry = entry.FlavorText
103+
break
104+
}
105+
}
106+
107+
effectBold := styling.StyleBold.Render("Effect:")
108+
109+
fullDoc := lipgloss.JoinVertical(lipgloss.Top, effectBold, flavorTextEntry)
110+
111+
fmt.Println(docStyle.Render(fullDoc))
112+
}

cmd/move/move_test.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package move
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"github.com/digitalghost-dev/poke-cli/styling"
7+
"log"
8+
"os"
9+
"strings"
10+
"testing"
11+
)
12+
13+
func captureMoveOutput(f func()) string {
14+
r, w, _ := os.Pipe()
15+
defer func(r *os.File) {
16+
err := r.Close()
17+
if err != nil {
18+
log.Fatal(err)
19+
}
20+
}(r)
21+
22+
oldStdout := os.Stdout
23+
os.Stdout = w
24+
defer func() { os.Stdout = oldStdout }()
25+
26+
f()
27+
28+
err := w.Close()
29+
if err != nil {
30+
log.Fatal(err)
31+
}
32+
33+
var buf bytes.Buffer
34+
_, _ = buf.ReadFrom(r)
35+
return buf.String()
36+
}
37+
38+
func TestMoveCommand(t *testing.T) {
39+
err := os.Setenv("GO_TESTING", "1")
40+
if err != nil {
41+
log.Fatal(err)
42+
}
43+
defer func() {
44+
err := os.Unsetenv("GO_TESTING")
45+
if err != nil {
46+
fmt.Println(err)
47+
}
48+
}()
49+
50+
tests := []struct {
51+
name string
52+
args []string
53+
expectedOutput string
54+
expectedError bool
55+
}{
56+
{
57+
name: "Help flag",
58+
args: []string{"move", "--help"},
59+
expectedOutput: "Get details about a specific move.",
60+
expectedError: false,
61+
},
62+
}
63+
64+
for _, tt := range tests {
65+
t.Run(tt.name, func(t *testing.T) {
66+
originalArgs := os.Args
67+
defer func() { os.Args = originalArgs }()
68+
69+
os.Args = append([]string{"poke-cli"}, tt.args...)
70+
71+
output := captureMoveOutput(func() {
72+
defer func() {
73+
if r := recover(); r != nil {
74+
if !tt.expectedError {
75+
t.Fatalf("Unexpected error: %v", r)
76+
}
77+
}
78+
}()
79+
MoveCommand()
80+
})
81+
82+
cleanOutput := styling.StripANSI(output)
83+
84+
if !strings.Contains(cleanOutput, tt.expectedOutput) {
85+
t.Errorf("Output mismatch. Expected to contain:\n%s\nGot:\n%s", tt.expectedOutput, output)
86+
}
87+
})
88+
}
89+
}

0 commit comments

Comments
 (0)