Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: Make dist directory
run: mkdir -p dist/bin/ dist/packages/ dist/tarballs/
- name: Build cows
run: docker run -v ${PWD}:/usr/local/src -v ${PWD}/build/cows:/tmp/cows -v ${PWD}/build/pokesprite:/tmp/original/pokesprite -u root --platform linux/amd64 ghcr.io/tmck-code/pokesay:latest ./build/scripts/build_cowfiles.sh
run: docker run -v ${PWD}:/usr/local/src -v ${PWD}/build/cows:/tmp/cows -v ${PWD}/build/pokesprite-ansi:/tmp/original/cows -u root --platform linux/amd64 ghcr.io/tmck-code/pokesay:latest ./build/scripts/build_cowfiles.sh
- name: Build go binary assets
run: docker run -v ${PWD}:/usr/local/src -v ${PWD}/build/cows:/tmp/cows -u root --platform linux/amd64 -e VERSION=0.1 ghcr.io/tmck-code/pokesay:latest ./build/scripts/build_assets.sh
- name: Run unit tests
Expand Down
7 changes: 4 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[submodule "build/pokesprite"]
path = build/pokesprite
url = git@github.com:msikma/pokesprite
[submodule "build/pokesprite-ansi"]
path = build/pokesprite-ansi
url = git@github.com:tmck-code/pokesprite-ansi
shallow = true
17 changes: 4 additions & 13 deletions build/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,15 @@ FROM golang:1.24
WORKDIR /usr/local/src

ENV DEBIAN_FRONTEND=noninteractive
ENV BUILD_DEPS="make gcc"
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
$BUILD_DEPS libmagickwand-dev ncurses-dev jq imagemagick tree \
&& git clone -q --depth 1 https://github.com/denilsonsa/img2xterm \
&& (cd img2xterm && make && make install) \
&& rm -rf img2xterm \
&& apt-get purge -y $BUILD_DEPS \
&& apt-get autoremove --purge -y \
&& rm -rf /var/lib/apt/lists/* \
&& rm -rf /tmp/* /var/tmp/*

RUN apt update \
&& apt upgrade -y \
&& apt install -y --no-install-recommends jq tree

RUN useradd u -m

WORKDIR /usr/local/src/
ADD go.* /usr/local/src/
ADD src/ /usr/local/src/src/

RUN go mod tidy \
&& go get -v github.com/mitchellh/go-wordwrap \
&& go install gotest.tools/gotestsum@latest \
Expand Down
26 changes: 26 additions & 0 deletions build/Dockerfile.convert
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
FROM golang:1.24

WORKDIR /usr/local/src

ENV DEBIAN_FRONTEND=noninteractive
ENV BUILD_DEPS="make gcc"
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
$BUILD_DEPS libmagickwand-dev ncurses-dev imagemagick tree \
&& git clone -q --depth 1 https://github.com/denilsonsa/img2xterm \
&& (cd img2xterm && make && make install) \
&& rm -rf img2xterm \
&& apt-get purge -y $BUILD_DEPS \
&& apt-get autoremove --purge -y \
&& rm -rf /var/lib/apt/lists/* \
&& rm -rf /tmp/* /var/tmp/*

RUN useradd u -m

ADD go.* /usr/local/src/
ADD src /usr/local/src/src/

RUN go mod tidy \
&& chown -R u:u /go

ADD . .
33 changes: 19 additions & 14 deletions build/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,27 +26,32 @@ build/docker:
--build-arg DEBUG=$(DEBUG) \
..

build/docker-convert:
@$(echo) -e "\e[48;5;30m> Building docker image $(DOCKER_IMAGE)-convert\e[0m"
@docker build \
--platform linux/amd64 \
-f Dockerfile.convert \
-t $(DOCKER_REPO)/pokesay-convert:$(DOCKER_TAG) \
--build-arg DEBUG=$(DEBUG) \
..

build/cows:
@$(echo) -e "\e[48;5;30m> Building cows\e[0m"
@rm -rf cows.tar.gz cows/
@mkdir -p cows/
@rm -rf $(PWD)/cows && mkdir -p $(PWD)/cows
@docker run --rm \
--platform linux/amd64 \
-v $(PWD)/../:/usr/local/src \
-v $(PWD)/pokesprite:/tmp/original/pokesprite \
-v $(PWD)/pokesprite-ansi:/tmp/original/cows \
-v $(PWD)/cows:/tmp/cows \
-e DEBUG=$(DEBUG) \
-u u \
$(DOCKER_IMAGE) \
build/scripts/build_cowfiles.sh
@tar -czf cows.tar.gz ./cows
@du -sh cows.tar.gz

# generate embedded bin files for category/metadata/the actual pokemon
build/assets:
@$(echo) -e "\e[48;5;30m> Building assets\e[0m"
@$(echo) -e "\n\e[48;5;30m> Building assets\e[0m"
@mkdir -p $(PWD)/assets
@rm -rf $(PWD)/cows/
@tar -xzf cows.tar.gz
@docker run --rm \
-v $(PWD)/../:/usr/local/src \
-v $(PWD)/cows:/tmp/cows \
Expand All @@ -58,7 +63,7 @@ build/assets:
@tree -L 1 $(PWD)/assets/

build/bin:
@$(echo) -e "\e[48;5;30m> Building binaries\e[0m"
@$(echo) -e "\n\e[48;5;30m> Building binaries\e[0m"
@mkdir -p $(PWD)/../dist/bin/ $(PWD)/../dist/packages/ $(PWD)/../dist/tarballs/
@docker run --rm \
-v $(PWD)/../:/usr/local/src \
Expand All @@ -72,7 +77,7 @@ build/bin:
@tree $(PWD)/../dist/

build/deb:
@$(echo) -e "\e[48;5;30m> Building DEB packages\e[0m"
@$(echo) -e "\n\e[48;5;30m> Building DEB packages\e[0m"
@docker run --rm \
-v $(PWD)/../:/usr/local/src \
-e VERSION=$(VERSION) \
Expand All @@ -82,7 +87,7 @@ build/deb:
bash -c "/usr/local/src/build/scripts/build_packages.sh deb"

build/arch:
@$(echo) -e "\e[48;5;30m> Building ARCH packages\e[0m"
@$(echo) -e "\n\e[48;5;30m> Building ARCH packages\e[0m"
@docker run --rm\
-v $(PWD)/../:/usr/local/src \
-e VERSION=$(VERSION) \
Expand All @@ -92,11 +97,11 @@ build/arch:
bash -c "useradd u -m && VERSION=$(VERSION) /usr/local/src/build/scripts/build_packages.sh arch"

build/packages: build/deb build/arch
@$(echo) -e "\e[48;5;30m> Built packages:\e[0m"
@$(echo) -e "\n\e[48;5;30m> Built packages:\e[0m"
@tree $(PWD)/../dist/

test:
@$(echo) -e "\e[48;5;30m> Running tests\e[0m"
@$(echo) -e "\n\e[48;5;30m> Running tests\e[0m"
@docker run --rm \
-v $(PWD)/../:/usr/local/src \
--platform linux/amd64 \
Expand All @@ -105,5 +110,5 @@ test:
$(DOCKER_IMAGE) \
gotestsum --format dots

.PHONY: all clean build/docker build/cows build/assets build/bin test
.PHONY: all clean build/docker build/docker-convert build/cows build/assets build/bin test
.PHONY: build/deb build/arch build/packages
Binary file removed build/cows.tar.gz
Binary file not shown.
1 change: 0 additions & 1 deletion build/pokesprite
Submodule pokesprite deleted from c5aaa6
1 change: 1 addition & 0 deletions build/pokesprite-ansi
Submodule pokesprite-ansi added at a17818
46 changes: 35 additions & 11 deletions build/scripts/build_cowfiles.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,39 @@

set -euo pipefail

mkdir -p /tmp/convert/
skip=(resources/ misc/ icons/ items/ items-outline)
declare -A h

# Convert all of the pokesprite .pngs -> cowfiles for the terminal
go run /usr/local/src/src/bin/convert/png_convert.go \
-from /tmp/original/pokesprite/ \
-tmpDir /tmp/convert/ \
-to /tmp/cows/ \
-padding 4 \
-skip '["resources/", "misc/", "icons/", "items/", "items-outline/"]' \
&& mv -v /tmp/cows/pokemon-gen8 /tmp/cows/gen8 > /dev/null \
&& mv -v /tmp/cows/pokemon-gen7x /tmp/cows/gen7x > /dev/null \
&& cat /tmp/original/pokesprite/data/pokemon.json | jq -c .[] > /tmp/cows/pokemon.json
cd /tmp/original/cows/
fpaths=$(find . -iname '*.cow' -type f | sort -h)

nOldFpaths=$(echo "$fpaths" | wc -l | tr -d '\n')
i=1
echo "$fpaths" | while read f; do
progress=$(( ((i * 100)) / nOldFpaths))
for s in "${skip[@]}"; do
if [[ "$f" == *"$s"* ]]; then
echo -e "[$i/$nOldFpaths $progress%] \e[0;33m skipping: $f\e[0m"
((i++))
continue 2
fi
done

s=$(sha256sum "$f" | cut -d' ' -f1)
if [[ ${h[$s]:-} ]]; then
echo -e "[$i/$nOldFpaths $progress%] \e[0;31m duplicate: $f\e[0m"
else
echo -e "[$i/$nOldFpaths $progress%] \e[0;32m copying: $f > /tmp/cows/$f\e[0m"
cp --parents "$f" /tmp/cows/
h[$s]=1
fi
((i++))
done

# rename dirs & generate pokemon.json metadata file
mv -v /tmp/cows/pokemon-gen8 /tmp/cows/gen8
mv -v /tmp/cows/pokemon-gen7x /tmp/cows/gen7x
cat /tmp/original/cows/data/pokemon.json | jq -c .[] > /tmp/cows/pokemon.json

nNewFpaths=$(find /tmp/cows/ -iname '*.cow' | wc -l | tr -d '\n')
echo -e "\n\e[1;32m✔ all done, total files: $nNewFpaths / $nOldFpaths\e[0m"
48 changes: 31 additions & 17 deletions src/bin/convert/png_convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,26 @@ var (
)

type CowBuildArgs struct {
FromDir string
TmpDir string
ToDir string
SkipDirs []string
Padding int
Debug bool
FromDir string
TmpDir string
ToDir string
SkipDirs []string
SkipDuplicates bool
Padding int
Debug bool
}

func parseArgs() CowBuildArgs {
fromDir := flag.String("from", ".", "from dir")
tmpDir := flag.String("tmpDir", "/tmp/convert/", "temporary directory for intermediate files")
toDir := flag.String("to", ".", "to dir")
skipDirs := flag.String("skip", "'[\"resources\"]'", "JSON array of dir patterns to skip converting")
skipDuplicates := flag.Bool("skipDuplicates", false, "whether to skip duplicate images")
padding := flag.Int("padding", 2, "the number of spaces to pad from the left")

flag.Parse()

args := CowBuildArgs{FromDir: *fromDir, TmpDir: *tmpDir, ToDir: *toDir, Padding: *padding, Debug: DEBUG}
args := CowBuildArgs{FromDir: *fromDir, TmpDir: *tmpDir, ToDir: *toDir, SkipDuplicates: *skipDuplicates, Padding: *padding, Debug: DEBUG}
json.Unmarshal([]byte(*skipDirs), &args.SkipDirs)

if args.Debug {
Expand All @@ -53,24 +55,28 @@ func worker(args CowBuildArgs, jobs <-chan string, pbar *progressbar.ProgressBar

for f := range jobs {
data, err := pokedex.ConvertPngToCow(args.FromDir, f, args.TmpDir, args.ToDir, args.Padding)
pbar.Add(1)

if err != nil {
mu.Lock()
*nFailures++
mu.Unlock()
pbar.Add(1)
continue
}

// check if this cawfile is a duplicate of one that has already been written
mu.Lock()
if _, found := dataSet[data]; found {
if args.Debug {
fmt.Println("Skipping duplicate data for", f)
fmt.Print("\r\x1b[J") // clear the progress bar before printing debug log
fmt.Println("Detected duplicate:", f)
}
*nDuplicates++
mu.Unlock()
continue
if args.SkipDuplicates {
mu.Unlock()
pbar.Add(1)
continue
}
}
dataSet[data] = struct{}{}
mu.Unlock()
Expand All @@ -84,6 +90,7 @@ func worker(args CowBuildArgs, jobs <-chan string, pbar *progressbar.ProgressBar
destFpath := filepath.Join(destDirpath, strings.ReplaceAll(filepath.Base(f), ".png", ".cow"))

pokedex.WriteToCowfile(data, destDirpath, destFpath)
pbar.Add(1)
}
}

Expand Down Expand Up @@ -119,19 +126,26 @@ func main() {
wg.Add(1)
go worker(args, jobs, &pbar, dataSet, &nDuplicates, &nFailures, &mu, &wg)
}

// Wait for all workers to finish
wg.Wait()
fmt.Println("\nFinished converting", len(fpaths), "pokesprite PNGs -> cowfiles")
fmt.Println("(skipped", nDuplicates, "duplicates and", nFailures, "failures)")

// wait for progress bar to finish
time.Sleep(100 * time.Millisecond)
pbar.Finish()
time.Sleep(100 * time.Millisecond) // wait a moment to let the progress bar finish cleanly

if args.Debug && len(pokedex.Failures) > 0 {
fmt.Println("failures:")
for _, f := range pokedex.Failures {
fmt.Println(" -", f)
}
}

totalSucceeded := len(fpaths) - nFailures
if args.SkipDuplicates {
totalSucceeded -= nDuplicates
}
fmt.Printf("\n- converted %d/%d PNGs -> ANSI\n", totalSucceeded, len(fpaths))
if args.SkipDuplicates {
fmt.Printf("- skipped %d duplicates\n- noticed %d failures\n\n", nDuplicates, nFailures)
} else {
fmt.Printf("- ignored %d duplicates\n- noticed %d failures\n\n", nDuplicates, nFailures)
}
}
3 changes: 1 addition & 2 deletions src/pokedex/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ func autoCrop(sourceFpath string, tmpDirpath string) (string, error) {
rand.Read(randomBytes)
randomSuffix := hex.EncodeToString(randomBytes)

destFpath := fmt.Sprintf("%s/%s-%s", tmpDirpath, randomSuffix, filepath.Base(sourceFpath))
// fmt.Println("Auto-cropping", sourceFpath, "->", destFpath)
destFpath := filepath.Join(tmpDirpath, fmt.Sprintf("%s-%s", randomSuffix, filepath.Base(sourceFpath)))
output, err := exec.Command(
"bash", "-c", fmt.Sprintf("/usr/bin/convert %s -trim +repage %s 2>&1", sourceFpath, destFpath),
).Output()
Expand Down
Loading