Skip to content

Commit c30394c

Browse files
Merge pull request #147 from digitalghost-dev/1.3.0
1.3.0
2 parents 083b9c6 + e1f9c70 commit c30394c

File tree

13 files changed

+193
-36
lines changed

13 files changed

+193
-36
lines changed

.dockerignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,7 @@ go.work.sum
2222

2323
# env file
2424
.env
25-
dist/
25+
dist/
26+
27+
# testdata
28+
testdata/

.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.2.4'
29+
VERSION_NUMBER: 'v1.3.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.2.4
17+
- -s -w -X main.version=v1.3.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.2.4" -o poke-cli .
11+
RUN go build -ldflags "-X main.version=v1.3.0" -o poke-cli .
1212

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

README.md

Lines changed: 4 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.2.4?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.3.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.2.4 <command> [subcommand] flag]
79+
docker run --rm -it digitalghostdev/poke-cli:v1.3.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.2.4 -c "cd /app && exec sh"
83+
docker run --rm -it --name poke-cli --entrypoint /bin/sh digitalghostdev/poke-cli:v1.3.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
```
@@ -150,7 +150,7 @@ Below is a list of the planned/completed commands and flags:
150150
- [x] `-i | --image`: display a pixel image of the Pokémon.
151151
- [x] `-s | --stats`: display the Pokémon's base stats.
152152
- [x] `-t | --types`: display the Pokémon's typing.
153-
- [ ] `-m | --moves`: display learnable moves.
153+
- [x] `-m | --moves`: display learnable moves.
154154
- [x] `search`: search for a resource (`ability`, `berry`, `pokemon`, `move`)
155155
- [ ] `speed`: compare speed stats between two Pokémon.
156156
- [x] `types`: get data about a specific typing.

cmd/pokemon/pokemon.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,15 @@ func PokemonCommand() (string, error) {
3131
fmt.Sprintf("\n\t%-30s %s", "-a, --abilities", "Prints the Pokémon's abilities."),
3232
fmt.Sprintf("\n\t%-30s %s", "-i=xx, --image=xx", "Prints out the Pokémon's default sprite."),
3333
fmt.Sprintf("\n\t%5s%-15s", "", hintMessage),
34+
fmt.Sprintf("\n\t%-30s %s", "-m, --moves", "Prints the Pokemon's learnable moves."),
3435
fmt.Sprintf("\n\t%-30s %s", "-s, --stats", "Prints the Pokémon's base stats."),
3536
fmt.Sprintf("\n\t%-30s %s", "-t, --types", "Prints the Pokémon's typing."),
3637
fmt.Sprintf("\n\t%-30s %s", "-h, --help", "Prints the help menu."),
3738
)
3839
output.WriteString(helpMessage)
3940
}
4041

41-
pokeFlags, abilitiesFlag, shortAbilitiesFlag, imageFlag, shortImageFlag, statsFlag, shortStatsFlag, typesFlag, shortTypesFlag := flags.SetupPokemonFlagSet()
42+
pokeFlags, abilitiesFlag, shortAbilitiesFlag, imageFlag, shortImageFlag, moveFlag, shortMoveFlag, statsFlag, shortStatsFlag, typesFlag, shortTypesFlag := flags.SetupPokemonFlagSet()
4243

4344
args := os.Args
4445

@@ -115,6 +116,13 @@ func PokemonCommand() (string, error) {
115116
}
116117
}
117118

119+
if *moveFlag || *shortMoveFlag {
120+
if err := flags.MovesFlag(&output, endpoint, pokemonName); err != nil {
121+
output.WriteString(fmt.Sprintf("error parsing flags: %v\n", err))
122+
return "", fmt.Errorf("error parsing flags: %w", err)
123+
}
124+
}
125+
118126
if *typesFlag || *shortTypesFlag {
119127
if err := flags.TypesFlag(&output, endpoint, pokemonName); err != nil {
120128
output.WriteString(fmt.Sprintf("error parsing flags: %v\n", err))

cmd/utils/validateargs.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func ValidatePokemonArgs(args []string) error {
7575
return fmt.Errorf("%s", errMessage)
7676
}
7777

78-
if err := checkLength(args, 7); err != nil {
78+
if err := checkLength(args, 8); err != nil {
7979
return err
8080
}
8181

cmd/utils/validateargs_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ func TestValidatePokemonArgs(t *testing.T) {
165165

166166
// Testing too many arguments
167167
tooManyArgs := [][]string{
168-
{"poke-cli", "pokemon", "hypo", "--abilities", "-s", "--types", "--image=sm", "-m"},
168+
{"poke-cli", "pokemon", "hypo", "--abilities", "-s", "--types", "--image=sm", "-m", "-p"},
169169
}
170170

171171
expectedError := styling.StripANSI("╭──────────────────╮\n│Error! │\n│Too many arguments│\n╰──────────────────╯")

flags/pokemonflagset.go

Lines changed: 122 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,19 @@ import (
66
"flag"
77
"fmt"
88
"github.com/charmbracelet/lipgloss"
9+
"github.com/charmbracelet/lipgloss/table"
910
"github.com/digitalghost-dev/poke-cli/connections"
1011
"github.com/digitalghost-dev/poke-cli/styling"
1112
"github.com/disintegration/imaging"
1213
"golang.org/x/text/cases"
1314
"golang.org/x/text/language"
1415
"image"
1516
"io"
17+
"log"
1618
"net/http"
1719
"os"
20+
"sort"
21+
"strconv"
1822
"strings"
1923
)
2024

@@ -33,7 +37,7 @@ func header(header string) string {
3337
return output.String()
3438
}
3539

36-
func SetupPokemonFlagSet() (*flag.FlagSet, *bool, *bool, *string, *string, *bool, *bool, *bool, *bool) {
40+
func SetupPokemonFlagSet() (*flag.FlagSet, *bool, *bool, *string, *string, *bool, *bool, *bool, *bool, *bool, *bool) {
3741
pokeFlags := flag.NewFlagSet("pokeFlags", flag.ExitOnError)
3842

3943
abilitiesFlag := pokeFlags.Bool("abilities", false, "Print the Pokémon's abilities")
@@ -42,6 +46,9 @@ func SetupPokemonFlagSet() (*flag.FlagSet, *bool, *bool, *string, *string, *bool
4246
imageFlag := pokeFlags.String("image", "", "Print the Pokémon's default sprite")
4347
shortImageFlag := pokeFlags.String("i", "", "Print the Pokémon's default sprite")
4448

49+
moveFlag := pokeFlags.Bool("moves", false, "Print the Pokémon's learnable moves")
50+
shortMoveFlag := pokeFlags.Bool("m", false, "Print the Pokémon's learnable moves")
51+
4552
statsFlag := pokeFlags.Bool("stats", false, "Print the Pokémon's base stats")
4653
shortStatsFlag := pokeFlags.Bool("s", false, "Print the Pokémon's base stats")
4754

@@ -56,14 +63,15 @@ func SetupPokemonFlagSet() (*flag.FlagSet, *bool, *bool, *string, *string, *bool
5663
fmt.Sprintf("\n\t%-30s %s", "-a, --abilities", "Prints the Pokémon's abilities."),
5764
fmt.Sprintf("\n\t%-30s %s", "-i=xx, --image=xx", "Prints out the Pokémon's default sprite."),
5865
fmt.Sprintf("\n\t%5s%-15s", "", hintMessage),
66+
fmt.Sprintf("\n\t%-30s %s", "-m, --moves", "Prints the Pokemon's learnable moves."),
5967
fmt.Sprintf("\n\t%-30s %s", "-s, --stats", "Prints the Pokémon's base stats."),
6068
fmt.Sprintf("\n\t%-30s %s", "-t, --types", "Prints the Pokémon's typing."),
6169
fmt.Sprintf("\n\t%-30s %s", "-h, --help", "Prints the help menu."),
6270
)
6371
fmt.Println(helpMessage)
6472
}
6573

66-
return pokeFlags, abilitiesFlag, shortAbilitiesFlag, imageFlag, shortImageFlag, statsFlag, shortStatsFlag, typesFlag, shortTypesFlag
74+
return pokeFlags, abilitiesFlag, shortAbilitiesFlag, imageFlag, shortImageFlag, moveFlag, shortMoveFlag, statsFlag, shortStatsFlag, typesFlag, shortTypesFlag
6775
}
6876

6977
func AbilitiesFlag(w io.Writer, endpoint string, pokemonName string) error {
@@ -198,6 +206,117 @@ func ImageFlag(w io.Writer, endpoint string, pokemonName string, size string) er
198206
return nil
199207
}
200208

209+
func MovesFlag(w io.Writer, endpoint string, pokemonName string) error {
210+
baseURL := "https://pokeapi.co/api/v2/"
211+
pokemonStruct, _, _, _, _, _ := connections.PokemonApiCall(endpoint, pokemonName, baseURL)
212+
213+
_, err := fmt.Fprintln(w, header("Learnable Moves"))
214+
if err != nil {
215+
return err
216+
}
217+
218+
type MoveInfo struct {
219+
Accuracy int
220+
Level int
221+
Name string
222+
Power int
223+
Type string
224+
}
225+
226+
var moves []MoveInfo
227+
228+
for _, pokeMove := range pokemonStruct.Moves {
229+
for _, detail := range pokeMove.VersionGroupDetails {
230+
if detail.VersionGroup.Name != "scarlet-violet" || detail.MoveLearnedMethod.Name != "level-up" {
231+
continue
232+
}
233+
234+
moveName := pokeMove.Move.Name
235+
moveStruct, _, err := connections.MoveApiCall("move", moveName, baseURL)
236+
if err != nil {
237+
log.Printf("Error fetching move %s: %v", moveName, err)
238+
continue
239+
}
240+
241+
capitalizedMove := cases.Title(language.English).String(strings.ReplaceAll(moveName, "-", " "))
242+
capitalizedType := cases.Title(language.English).String(moveStruct.Type.Name)
243+
244+
moves = append(moves, MoveInfo{
245+
Accuracy: moveStruct.Accuracy,
246+
Level: detail.LevelLearnedAt,
247+
Name: capitalizedMove,
248+
Power: moveStruct.Power,
249+
Type: capitalizedType,
250+
})
251+
}
252+
}
253+
254+
if len(moves) == 0 {
255+
_, err := fmt.Fprintln(w, "No level-up moves found for Scarlet & Violet.")
256+
if err != nil {
257+
return err
258+
}
259+
return nil
260+
}
261+
262+
// Sort by level
263+
sort.Slice(moves, func(i, j int) bool {
264+
return moves[i].Level < moves[j].Level
265+
})
266+
267+
// Convert to table rows
268+
var rows [][]string
269+
for _, m := range moves {
270+
styledType := lipgloss.
271+
NewStyle().
272+
Bold(true).
273+
Foreground(lipgloss.Color(styling.ColorMap[strings.ToLower(m.Type)])).
274+
Render(m.Type)
275+
276+
rows = append(rows, []string{
277+
m.Name,
278+
strconv.Itoa(m.Level),
279+
styledType,
280+
strconv.Itoa(m.Accuracy),
281+
strconv.Itoa(m.Power),
282+
})
283+
}
284+
285+
// Build and print table
286+
color := lipgloss.AdaptiveColor{Light: "#4B4B4B", Dark: "#D3D3D3"}
287+
288+
t := table.New().
289+
Border(lipgloss.NormalBorder()).
290+
BorderStyle(lipgloss.NewStyle().Foreground(color)).
291+
StyleFunc(func(row, column int) lipgloss.Style {
292+
var style lipgloss.Style
293+
294+
switch column {
295+
case 0:
296+
style = style.Width(18)
297+
case 1:
298+
style = style.Width(8)
299+
case 2:
300+
style = style.Width(10)
301+
case 3:
302+
style = style.Width(10)
303+
case 4:
304+
style = style.Width(8)
305+
}
306+
307+
return style
308+
}).
309+
Headers("Name", "Level", "Type", "Accuracy", "Power").
310+
Rows(rows...)
311+
312+
_, err = fmt.Fprintln(w, t)
313+
if err != nil {
314+
return err
315+
}
316+
317+
return nil
318+
}
319+
201320
func StatsFlag(w io.Writer, endpoint string, pokemonName string) error {
202321
baseURL := "https://pokeapi.co/api/v2/"
203322
pokemonStruct, _, _, _, _, _ := connections.PokemonApiCall(endpoint, pokemonName, baseURL)
@@ -298,35 +417,14 @@ func TypesFlag(w io.Writer, endpoint string, pokemonName string) error {
298417
baseURL := "https://pokeapi.co/api/v2/"
299418
pokemonStruct, _, _, _, _, _ := connections.PokemonApiCall(endpoint, pokemonName, baseURL)
300419

301-
colorMap := map[string]string{
302-
"normal": "#B7B7A9",
303-
"fire": "#FF4422",
304-
"water": "#3499FF",
305-
"electric": "#FFCC33",
306-
"grass": "#77CC55",
307-
"ice": "#66CCFF",
308-
"fighting": "#BB5544",
309-
"poison": "#AA5699",
310-
"ground": "#DEBB55",
311-
"flying": "#889AFF",
312-
"psychic": "#FF5599",
313-
"bug": "#AABC22",
314-
"rock": "#BBAA66",
315-
"ghost": "#6666BB",
316-
"dragon": "#7766EE",
317-
"dark": "#775544",
318-
"steel": "#AAAABB",
319-
"fairy": "#EE99EE",
320-
}
321-
322420
// Print the header from header func
323421
_, err := fmt.Fprintln(w, header("Typing"))
324422
if err != nil {
325423
return err
326424
}
327425

328426
for _, pokeType := range pokemonStruct.Types {
329-
colorHex, exists := colorMap[pokeType.Type.Name]
427+
colorHex, exists := styling.ColorMap[pokeType.Type.Name]
330428
if exists {
331429
color := lipgloss.Color(colorHex)
332430
style := lipgloss.NewStyle().Bold(true).Foreground(color)

flags/pokemonflagset_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313

1414
func TestSetupPokemonFlagSet(t *testing.T) {
1515
// Call the function to get the flag set and flags
16-
pokeFlags, abilitiesFlag, shortAbilitiesFlag, imageFlag, shortImageFlag, statsFlag, shortStatsFlag, typesFlag, shortTypesFlag := SetupPokemonFlagSet()
16+
pokeFlags, abilitiesFlag, shortAbilitiesFlag, imageFlag, shortImageFlag, moveFlag, shortMoveFlag, statsFlag, shortStatsFlag, typesFlag, shortTypesFlag := SetupPokemonFlagSet()
1717

1818
// Check flag set properties
1919
assert.NotNil(t, pokeFlags, "Flag set should not be nil")
@@ -29,6 +29,8 @@ func TestSetupPokemonFlagSet(t *testing.T) {
2929
{shortAbilitiesFlag, false, "Short abilities flag should be 'a'"},
3030
{imageFlag, "", "Image flag default value should be 'md'"},
3131
{shortImageFlag, "", "Short image flag default value should be 'md'"},
32+
{moveFlag, false, "Move flag default value should be 'moves'"},
33+
{shortMoveFlag, false, "Short move flag default value should be 'm'"},
3234
{typesFlag, false, "Types flag should be 'types'"},
3335
{shortTypesFlag, false, "Short types flag should be 't'"},
3436
{statsFlag, false, "Stats flag should be 'stats'"},

0 commit comments

Comments
 (0)