Skip to content

Commit

Permalink
Merge pull request #4 from digitalghost-dev/0.1.0
Browse files Browse the repository at this point in the history
0.1.0
  • Loading branch information
digitalghost-dev committed Jun 2, 2024
2 parents b8bf89b + bfe0c86 commit bb2a7d4
Show file tree
Hide file tree
Showing 16 changed files with 586 additions and 1 deletion.
25 changes: 25 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
*.DS_Store
*.idea

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/

# Go workspace file
go.work
go.work.sum

# env file
.env
dist/
27 changes: 27 additions & 0 deletions .github/workflows/go_lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Lint

on:
pull_request:
types: [opened, reopened]

permissions:
contents: read
pull-requests: read

jobs:
linter:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.21

- name: Lint
uses: golangci/golangci-lint-action@v4
with:
version: v1.56
skip-cache: true
24 changes: 24 additions & 0 deletions .github/workflows/go_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Test

on:
pull_request:
types: [opened, reopened]

jobs:
tests:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.21

- name: Install dependencies
run: |
go get .
- name: Run tests
run: go test -v ./...
25 changes: 25 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
*.DS_Store
*.idea

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/

# Go workspace file
go.work
go.work.sum

# env file
.env
dist/
14 changes: 14 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM golang:1.21-alpine3.19

WORKDIR /app

ENV TERM xterm-256color
ENV COLOR_OUTPUT true

COPY . /app

RUN PATH="$PATH:~/go/bin:/usr/local/go/bin:$GOPATH/bin"

RUN go install

ENTRYPOINT ["poke-cli"]
55 changes: 54 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,54 @@
# poke-cli
<p align="center">
<img height="250" width="350" src="https://cdn.simpleicons.org/pokemon/FFCC00" alt="pokemon-logo"/>
</p>

<div align="center">
<h1>Pokémon CLI</h1>
<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">
<img src="https://img.shields.io/docker/image-size/digitalghostdev/poke-cli/v1.0.0?arch=arm64&style=flat-square&logo=docker&logoColor=FFCC00&labelColor=EEE&color=FFCC00" alt="docker-image-size">
</div>

<div align="center">
<img src="https://img.shields.io/github/actions/workflow/status/digitalghost-dev/poke-cli/go_tests.yml?style=flat-square&logo=go&logoColor=00ADD8&label=Tests&labelColor=EEE&color=00ADD8" alt="tests-label">
<img src="https://img.shields.io/github/go-mod/go-version/digitalghost-dev/poke-cli?style=flat-square&logo=Go&labelColor=EEE&color=00ADD8" alt="go-version">
</div>

## Overview
A CLI tool for viewing data about Pokémon from your terminal!

## Install

### Go Build
1. Make sure [Go is installed](https://go.dev/dl/) on your machine. This project uses `v1.21`.
2. Clone the repository in a root directory: `git clone https://github.com/digitalghost-dev/poke-cli.git`
3. Change directories into the `poke-cli` directory.
4. Run `go build -o poke-cli`
5. A binary will be created then the tool can be used! It can also be added to your path to run the binary from anywhere.

### Docker
Use a Docker Image instead:
```bash
docker run --rm -it digitalghostdev/poke-cli:1.0.0 [command] [flag]
```

> [!NOTE]
> Currently working on more ways to distribute the binary.
## Usage
By running `poke-cli --help`, it'll display information on how to use the tool.
```
Welcome! This tool displays data about a selected Pokémon in the terminal!
USAGE:
poke-cli [flag]
poke-cli [pokemon name] [flag]
----------
Example: poke-cli bulbasaur or poke-cli flutter-mane --types
GLOBAL FLAGS:
-h, --help Shows the help menu
POKEMON NAME FLAGS:
Add a flag after declaring a Pokémon's name for more details!
--types
```
43 changes: 43 additions & 0 deletions cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package main

import (
"flag"
"fmt"
"github.com/charmbracelet/lipgloss"
"github.com/digitalghost-dev/poke-cli/subcommands"
"os"
)

var styleBold = lipgloss.NewStyle().Bold(true)
var styleItalic = lipgloss.NewStyle().Italic(true)

func main() {

flag.Usage = func() {
fmt.Println("Welcome! This tool displays data about a selected Pokémon in the terminal!")

fmt.Println(styleBold.Render("\nUSAGE:"))
fmt.Println("\t", "poke-cli [flag]")
fmt.Println("\t", "poke-cli [pokemon name] [flag]")
fmt.Println("\t", "----------")
fmt.Println("\t", styleItalic.Render("Example:"), "poke-cli bulbasaur", styleItalic.Render("or"), "poke-cli flutter-mane --types")

fmt.Println(styleBold.Render("\nGLOBAL FLAGS:"))
fmt.Println("\t", "-h, --help", "\t", "Shows the help menu")
fmt.Print("\n")

fmt.Println(styleBold.Render("POKEMON NAME FLAGS:"))
fmt.Println("\t", "Add a flag after declaring a Pokémon's name for more details!")
fmt.Print("\t", "--types", "\t\t", "Prints out the Pokémon's typing.\n\n")
}

flag.Parse()

if len(os.Args) < 2 {
fmt.Println("Please declare a Pokémon's name after the CLI name")
fmt.Println("Run 'poke-cli --help' for more details")
os.Exit(1)
}

subcommands.PokemonCommand()
}
66 changes: 66 additions & 0 deletions cli_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package main

import (
"bytes"
"os/exec"
"testing"
)

func TestCLI(t *testing.T) {

tests := []struct {
args []string
expectedOutput string
expectedExit int
}{
{
args: []string{},
expectedOutput: "Please declare a Pokémon's name after the CLI name\nRun 'poke-cli --help' for more details\n",
expectedExit: 1,
},
{
args: []string{"bulbasaur"},
expectedOutput: "Selected Pokémon: Bulbasaur\n",
expectedExit: 0,
},
{
args: []string{"mew", "--types"},
expectedOutput: "Selected Pokémon: Mew\nType 1: psychic\n",
expectedExit: 0,
},
{
args: []string{"cacturne", "--types"},
expectedOutput: "Selected Pokémon: Cacturne\nType 1: grass\nType 2: dark\n",
expectedExit: 0,
},
{
args: []string{"chimchar", "types"},
expectedOutput: "error: only flags are allowed after declaring a Pokémon's name\n",
expectedExit: 1,
},
{
args: []string{"flutter-mane", "types"},
expectedOutput: "Selected Pokémon: Flutter-Mane\nType 1: ghost\nType 2: fairy\n",
expectedExit: 0,
},
}

for _, test := range tests {
cmd := exec.Command("poke-cli", test.args...)
var out bytes.Buffer
cmd.Stdout = &out

err := cmd.Run()
if err != nil {
return
}

if out.String() != test.expectedOutput {
t.Errorf("Expected output: %s, Got: %s", test.expectedOutput, out.String())
}

if cmd.ProcessState.ExitCode() != test.expectedExit {
t.Errorf("Expected exit code: %d, Got: %d", test.expectedExit, cmd.ProcessState.ExitCode())
}
}
}
76 changes: 76 additions & 0 deletions connections/connection.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package connections

import (
"encoding/json"
"fmt"
"github.com/charmbracelet/lipgloss"
"io"
"log"
"net/http"
)

var httpGet = http.Get
var red = lipgloss.Color("#F2055C")
var errorColor = lipgloss.NewStyle().Foreground(red)

// Helper function to handle API calls and JSON unmarshalling
func baseApiCall(url string, target interface{}) {
res, err := httpGet(url)
if err != nil {
log.Fatalf("Error making GET request: %v", err)
}
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
log.Printf("Failed to close body: %v", err)
}
}(res.Body)

if res.StatusCode == http.StatusNotFound {
fmt.Println(errorColor.Render("Couldn't find that Pokémon... perhaps its named was misspelled?"))
}

body, err := io.ReadAll(res.Body)
if err != nil {
log.Fatalf("Error reading response body: %v", err)
}

err = json.Unmarshal(body, target)
if err != nil {
log.Fatalf("Error unmarshalling JSON: %v", err)
}
}

func PokemonNameApiCall(pokemonName string, baseURL string) string {
type Pokemon struct {
Name string `json:"name"`
}

url := baseURL + pokemonName
var pokemon Pokemon

baseApiCall(url, &pokemon)

return pokemon.Name
}

func PokemonTypeApiCall(pokemonName string, baseURL string) {
type Pokemon struct {
Types []struct {
Slot int `json:"slot"`
Type struct {
Name string `json:"name"`
URL string `json:"url"`
} `json:"type"`
} `json:"types"`
}

url := baseURL + pokemonName
var pokemon Pokemon

baseApiCall(url, &pokemon)

for _, pokeType := range pokemon.Types {
fmt.Printf("Type %d: %s\n", pokeType.Slot, pokeType.Type.Name)
}
}
26 changes: 26 additions & 0 deletions connections/connection_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package connections

import (
"encoding/json"
"github.com/stretchr/testify/assert"
"net/http"
"net/http/httptest"
"testing"
)

func TestBaseApiCallSuccess(t *testing.T) {
expectedData := map[string]string{"key": "value"}

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
err := json.NewEncoder(w).Encode(expectedData)
assert.Nil(t, err)
}))
defer ts.Close()

var target map[string]string

baseApiCall(ts.URL, &target)

assert.Equal(t, expectedData, target)
}
Loading

0 comments on commit bb2a7d4

Please sign in to comment.