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
1 change: 1 addition & 0 deletions .github/build-tags
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
noasm
41 changes: 28 additions & 13 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ jobs:
shell: bash

- name: vet
run: go vet ./...
run: go vet -tags "$(cat .github/build-tags)" ./...

- name: the dependency list has not grown by accident
# Every dependency is a licence question and a byte stability
Expand Down Expand Up @@ -133,6 +133,7 @@ jobs:
github.com/fyne-io/glfw-js \
github.com/fyne-io/image \
github.com/fyne-io/oksvg \
github.com/gen2brain/gav1d \
github.com/go-gl/gl \
github.com/go-gl/glfw/v3.4/glfw \
github.com/go-ole/go-ole \
Expand Down Expand Up @@ -198,8 +199,8 @@ jobs:
fi
echo "dependencies unchanged, $(echo "$expected" | wc -l) modules"

linked=$(go list -deps -f '{{if .Module}}{{.Module.Path}}{{end}}' ./cmd/tfg | LC_ALL=C sort -u | grep -v '^github.com/donislawdev/TestingFilesGenerator$' | grep .)
wanted=$(printf '%s\n' github.com/goccy/go-yaml golang.org/x/text)
linked=$(go list -deps -tags "$(cat .github/build-tags)" -f '{{if .Module}}{{.Module.Path}}{{end}}' ./cmd/tfg | LC_ALL=C sort -u | grep -v '^github.com/donislawdev/TestingFilesGenerator$' | grep .)
wanted=$(printf '%s\n' github.com/gen2brain/gav1d github.com/goccy/go-yaml golang.org/x/text)
if [ "$linked" != "$wanted" ]; then
echo "the command line binary links a different set of modules."
echo "expected: $wanted"
Expand All @@ -210,10 +211,10 @@ jobs:
shell: bash

- name: test
run: go test ./... -count=1
run: go test -tags "$(cat .github/build-tags)" ./... -count=1

- name: build the command line binary
run: go build ./cmd/tfg
run: go build -tags "$(cat .github/build-tags)" ./cmd/tfg

- name: build the window binary
# The toolkit arrived on 2026-08-05 and this step still passes, which
Expand Down Expand Up @@ -247,9 +248,9 @@ jobs:
run: |
set -euo pipefail
if [ "$RUNNER_OS" = "Windows" ]; then
go build -ldflags="$(cat .github/gui-ldflags)" ./cmd/tfg-gui
go build -tags "$(cat .github/build-tags)" -ldflags="$(cat .github/gui-ldflags)" ./cmd/tfg-gui
else
go build ./cmd/tfg-gui
go build -tags "$(cat .github/build-tags)" ./cmd/tfg-gui
fi
shell: bash

Expand Down Expand Up @@ -477,8 +478,8 @@ jobs:
run: |
set -euo pipefail
mkdir -p dist
CGO_ENABLED=0 go build -trimpath -o dist/tfg ./cmd/tfg
CGO_ENABLED=1 go build -trimpath -o dist/tfg-gui ./cmd/tfg-gui
CGO_ENABLED=0 go build -tags "$(cat .github/build-tags)" -trimpath -o dist/tfg ./cmd/tfg
CGO_ENABLED=1 go build -tags "$(cat .github/build-tags)" -trimpath -o dist/tfg-gui ./cmd/tfg-gui
ls -l dist

- name: the document we would publish
Expand Down Expand Up @@ -645,7 +646,7 @@ jobs:
# Race instrumentation costs five to twenty times the wall clock, and
# this package renders twenty five screens and builds two binaries. The
# job's own thirty minutes is the ceiling that means something.
run: go test ./... -count=1 -race -timeout 25m
run: go test -tags "$(cat .github/build-tags)" ./... -count=1 -race -timeout 25m

coverage:
name: coverage gate
Expand All @@ -670,7 +671,7 @@ jobs:
# under test - which reports 0.0% and makes the gate meaningless.
# Measured, not assumed.
run: >
go test ./... -count=1 -covermode=atomic
go test -tags "$(cat .github/build-tags)" ./... -count=1 -covermode=atomic
-coverpkg=./internal/...,./cmd/...
-coverprofile=coverage.out

Expand Down Expand Up @@ -723,13 +724,27 @@ jobs:
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
p7zip-full ffmpeg poppler-utils inkscape python3-pil

# The distribution's Pillow cannot open an AVIF - measured on this
# runner, PIL.UnidentifiedImageError on a file the structural checker
# had just called sound. Installed for the SAME interpreter the oracle
# reaches for, then asked whether it can actually read one. No version
# is named: the question is what this Pillow can do, not when the
# support landed.
python -m pip install --break-system-packages --upgrade pillow
python - <<'PY'
from PIL import Image, features
print("pillow", Image.__version__, "avif:", features.check("avif"))
if not features.check("avif"):
raise SystemExit("this Pillow cannot read AVIF, so the oracle would fail on a good file")
PY
shell: bash

- name: every format past its reference tool
# -v so that a skip is visible in the log. A tool that failed to install
# would otherwise turn this job back into the green nothing it exists
# to replace.
run: go test ./internal/guard/ -count=1 -run 'ReferenceTool' -v
run: go test -tags "$(cat .github/build-tags)" ./internal/guard/ -count=1 -run 'ReferenceTool' -v
shell: bash

fuzz:
Expand Down Expand Up @@ -770,7 +785,7 @@ jobs:
set -euo pipefail
for target in FuzzParseSize FuzzParseRecipe FuzzNameTemplate FuzzCanonicalRecipe; do
echo "=== $target ==="
go test ./internal/guard/ -run "^$" -fuzz "^${target}$" -fuzztime 5m
go test -tags "$(cat .github/build-tags)" ./internal/guard/ -run "^$" -fuzz "^${target}$" -fuzztime 5m
done
shell: bash

Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
# A release built from a red tree is the one kind of release that
# cannot be taken back, because the binaries are already on somebody's
# disk. This is the same command CI runs.
run: go test ./... -count=1
run: go test -tags "$(cat .github/build-tags)" ./... -count=1

- name: what version the code says
id: version
Expand Down Expand Up @@ -188,7 +188,7 @@ jobs:
# -trimpath keeps the build machine's directory names out of the
# binary. On a public release that is a privacy line as much as a
# reproducibility one.
GOOS="$os" GOARCH="$arch" go build -trimpath -o "${work}/${binary}" ./cmd/tfg
GOOS="$os" GOARCH="$arch" go build -tags "$(cat .github/build-tags)" -trimpath -o "${work}/${binary}" ./cmd/tfg

# The notices travel with the binary because their licences require
# it - see THIRD-PARTY-NOTICES.md, which says so itself. The licence
Expand Down Expand Up @@ -295,10 +295,10 @@ jobs:
# release and a local build cannot drift. Without them Windows
# hangs a black console window behind the program. Windows only:
# the flag names a Windows subsystem and means nothing elsewhere.
go build -trimpath -ldflags="$(cat .github/gui-ldflags)" \
go build -tags "$(cat .github/build-tags)" -trimpath -ldflags="$(cat .github/gui-ldflags)" \
-o "${work}/tfg-gui.exe" ./cmd/tfg-gui
else
go build -trimpath -o "${work}/tfg-gui" ./cmd/tfg-gui
go build -tags "$(cat .github/build-tags)" -trimpath -o "${work}/tfg-gui" ./cmd/tfg-gui
fi

# Same reason as the command line archives: on macOS the ticket has
Expand Down
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,24 @@ because it turns other people's test suites red.

### Added

- **AVIF, the twenty third format.** One frame, 8 bit, 4:2:0.
`tfg generate --format avif --size 300kb` writes an AV1 picture in an ISO base
media container. `width`, `height` and `quality` can be set, and the picture
goes up to 40 megapixels, so Full HD and 4K are both in reach. Left alone, the
picture is the largest of a fixed set that fits the size asked for, up to
640x480 - the same as JPG.

**Every size from its minimum of 311 B upwards is reachable, with no gaps.**
The padding travels in a `free` box, which is the box the format sets aside
for space that means nothing, and it takes any length at all.

This is the first format here whose pixels are coded by somebody else's
encoder rather than by code in this repository. AV1 is too large to write by
hand for one format - the coefficient tables alone in the nearest
implementation are fourteen times the size of this project's whole WebP
encoder. The encoder is pinned, so raising it is a breaking change like any
other, and it is pure Go: no C compiler, no shared library and no socket.

- **WEBP, the twenty second format.** Lossless, one frame, no alpha.
`tfg generate --format webp --size 300kb` writes a picture worth 300 kB rather
than a thumbnail followed by filler, because the encoder measures out three
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

**Testing Files Generator** is a tool for QA engineers and developers who need real
files to test against - an upload form, a parser, anything that takes a file and
has an opinion about it. You pick one of its 22 formats and the size you want,
has an opinion about it. You pick one of its 23 formats and the size you want,
and you get **exactly that**: ask for a 10 MB PDF and you get a PDF that a reader
will open, at 10 MB to the byte. Every run also leaves a manifest saying **what
your system should do with each file**, which is the part other generators leave
Expand All @@ -23,7 +23,7 @@ needs it finds out it exists.

- **Hit an exact size, to the byte** - ask for 10485761 bytes and get exactly
that, never a silently rounded file.
- **Write 22 real formats** - a generated PNG opens in an image viewer, a DOCX
- **Write 23 real formats** - a generated PNG opens in an image viewer, a DOCX
opens in Word, a ZIP extracts. Not padded zeros with an extension.
- **Say what should happen to each file** - the manifest carries an expected
outcome, so your test reads the assertion instead of you writing it out.
Expand Down Expand Up @@ -82,7 +82,7 @@ software that owns it, at the exact size you asked for:
| group | formats |
|---|---|
| 📄 **Documents** | `pdf`, `docx` (Word), `xlsx` (Excel), `pptx` (PowerPoint) |
| 🖼️ **Images** | `png`, `jpg`, `bmp`, `gif`, `ico`, `svg`, `tiff`, `webp` |
| 🖼️ **Images** | `png`, `jpg`, `bmp`, `gif`, `ico`, `svg`, `tiff`, `webp`, `avif` |
| 📝 **Text and markup** | `txt`, `md`, `csv`, `json`, `xml`, `html`, `log` |
| 🗜️ **Archives** | `zip`, `targz` (`.tar.gz`) |
| 🔊 **Audio** | `wav` |
Expand Down
46 changes: 44 additions & 2 deletions THIRD-PARTY-NOTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ first, so the difference is worth stating rather than leaving to be assumed.

| binary | what it is | third party code in it |
|---|---|---|
| `tfg` | the command line | the Go runtime, and **two** modules: `github.com/goccy/go-yaml` and `golang.org/x/text` |
| `tfg` | the command line | the Go runtime, and **three** modules: `github.com/goccy/go-yaml`, `github.com/gen2brain/gav1d` and `golang.org/x/text` |
| `tfg-gui` | the desktop window | the same, plus **27** more for the graphics toolkit, one of them on Linux only |

The window is a separate binary because its toolkit needs a C compiler and
OpenGL, neither of which the command line uses. A server or a build agent
running `tfg` therefore carries none of the 27, and that is checked rather than
asserted: a guard in the source compares what the command line binary actually
links against that list of two.
links against that list of three.

---

Expand Down Expand Up @@ -117,6 +117,48 @@ Source: <https://go.googlesource.com/text>

---

## github.com/gen2brain/gav1d

Version 0.2.5. Codes and reads AV1, which is what the picture inside an
AVIF is. It is written in Go and assembly with no C in it and no module
of its own behind it, so it brings nothing else along.

```
Copyright (c) 2018-2025, VideoLAN and dav1d authors
Copyright (c) 2016, Alliance for Open Media
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
```

It also ships a `PATENTS` file carrying the **Alliance for Open Media
Patent License 1.0**, which grants a patent licence for AV1 and withdraws
it from anybody who sues over the codec. The full text is in the module,
at `PATENTS`, and at <https://aomedia.org/license/patent-license/>.

Source: <https://github.com/gen2brain/gav1d>

---

## The window binary only

These 26 modules are the graphics toolkit and what it brings with it. They are
Expand Down
7 changes: 5 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ toolchain go1.26.7

require github.com/goccy/go-yaml v1.19.2

require golang.org/x/text v0.41.0
require (
github.com/gen2brain/gav1d v0.2.5
golang.org/x/text v0.41.0
)

require github.com/FyshOS/fancyfs v0.0.1 // indirect

Expand Down Expand Up @@ -66,7 +69,7 @@ require (
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect
github.com/stretchr/testify v1.11.1 // indirect
github.com/yuin/goldmark v1.8.2 // indirect
golang.org/x/image v0.43.0 // indirect
golang.org/x/image v0.43.0
golang.org/x/net v0.57.0 // indirect
golang.org/x/sys v0.47.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ github.com/fyne-io/image v0.1.1 h1:WH0z4H7qfvNUw5l4p3bC1q70sa5+YWVt6HCj7y4VNyA=
github.com/fyne-io/image v0.1.1/go.mod h1:xrfYBh6yspc+KjkgdZU/ifUC9sPA5Iv7WYUBzQKK7JM=
github.com/fyne-io/oksvg v0.2.0 h1:mxcGU2dx6nwjJsSA9PCYZDuoAcsZ/OuJlvg/Q9Njfo8=
github.com/fyne-io/oksvg v0.2.0/go.mod h1:dJ9oEkPiWhnTFNCmRgEze+YNprJF7YRbpjgpWS4kzoI=
github.com/gen2brain/gav1d v0.2.5 h1:Zg5/DE1JBdf8kxZqIvNo2ZEizF9DVF9jdPTAKJQZbOY=
github.com/gen2brain/gav1d v0.2.5/go.mod h1:ReFKjHq7pvRhEk+pgRPAo9gOlcrf51sdzVcAbbX7e0E=
github.com/go-gl/gl v0.0.0-20260331235117-4566fea9a276 h1:IO5P06Pcj9K04d+l4nrf3c2U56+dAotIFG6u4P1wAHI=
github.com/go-gl/gl v0.0.0-20260331235117-4566fea9a276/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw=
github.com/go-gl/glfw/v3.4/glfw v0.1.0-pre.1.0.20260707082822-2a407d02d01a h1:HWK0MBggT/T6YH7VffE10xBIhqeTq8JzIUPJXrRy87g=
Expand Down
1 change: 1 addition & 0 deletions internal/format/all/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package all

import (
// Each format registers itself when its package is loaded.
_ "github.com/donislawdev/TestingFilesGenerator/internal/format/avif"
_ "github.com/donislawdev/TestingFilesGenerator/internal/format/bmp"
_ "github.com/donislawdev/TestingFilesGenerator/internal/format/csvfile"
_ "github.com/donislawdev/TestingFilesGenerator/internal/format/docx"
Expand Down
Loading
Loading