Skip to content

Commit 9447d7e

Browse files
committed
testrun
1 parent 9bf7a96 commit 9447d7e

3 files changed

Lines changed: 109 additions & 26 deletions

File tree

.github/workflows/ci.yml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
name: Test (Elixir ${{ matrix.elixir }} / OTP ${{ matrix.otp }}${{ matrix.unlock && ' / unlock' || '' }})
12+
runs-on: ubuntu-latest
13+
14+
strategy:
15+
matrix:
16+
include:
17+
- elixir: "1.19"
18+
otp: "27"
19+
unlock: false
20+
- elixir: "1.19"
21+
otp: "28"
22+
unlock: false
23+
- elixir: "1.19"
24+
otp: "28"
25+
unlock: true
26+
27+
env:
28+
MIX_ENV: test
29+
30+
steps:
31+
- uses: actions/checkout@v4
32+
33+
- uses: erlef/setup-beam@v1
34+
with:
35+
elixir-version: ${{ matrix.elixir }}
36+
otp-version: ${{ matrix.otp }}
37+
38+
- uses: actions/cache@v4
39+
with:
40+
path: |
41+
deps
42+
_build
43+
key: ${{ runner.os }}-mix-${{ matrix.elixir }}-${{ matrix.otp }}-${{ hashFiles('**/mix.lock') }}
44+
restore-keys: |
45+
${{ runner.os }}-mix-${{ matrix.elixir }}-${{ matrix.otp }}-
46+
47+
- name: Unlock deps
48+
if: matrix.unlock
49+
run: mix deps.unlock --all
50+
51+
- name: Install dependencies
52+
run: mix deps.get
53+
54+
- name: Check formatting
55+
run: mix format --check-formatted
56+
57+
- name: Compile with warnings as errors
58+
run: mix compile --warnings-as-errors
59+
60+
- name: Run Credo
61+
run: mix credo --strict
62+
63+
- name: Run tests
64+
run: mix test

.github/workflows/dependabot.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
version: 2
2+
3+
updates:
4+
- package-ecosystem: "mix"
5+
directory: "/"
6+
schedule:
7+
interval: "weekly"
8+
cooldown:
9+
default-days: 7
10+
11+
- package-ecosystem: "github-actions"
12+
directory: "/"
13+
schedule:
14+
interval: "weekly"
15+
cooldown:
16+
default-days: 7

lib/og_mate.ex

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ defmodule OGMate do
33
Compile-time OG image generation for Elixir content sites.
44
55
A NimblePublisher-style library that bakes PNG images at compile time.
6-
Always returns `{:ok, bytes}` — unknown slugs resolve to the default image.
6+
Always returns `{:ok, bytes}` — unknown keys resolve to the default image.
77
88
## Example
99
@@ -43,41 +43,41 @@ defmodule OGMate do
4343
# ── Callbacks ────────────────────────────────────────────────────
4444

4545
@doc """
46-
Returns a list of all slugs that should have images.
46+
Returns a list of all keys that should have images.
4747
4848
These are enumerated and baked at compile time.
4949
"""
5050
@callback all_keys() :: [String.t()]
5151

5252
@doc """
53-
Given a slug, return `{title, description}`, or `:error` if the slug
53+
Given a key, return `{title, description}`, or `:error` if the key
5454
shouldn't produce an image.
5555
56-
Slugs that return `:error` are listed by `all_keys/0` but are skipped
56+
keys that return `:error` are listed by `all_keys/0` but are skipped
5757
during baking (they resolve to the default image at runtime).
5858
"""
59-
@callback content_for(slug :: String.t()) :: {String.t(), String.t()} | :error
59+
@callback content_for(key :: String.t()) :: {String.t(), String.t()} | :error
6060

6161
@doc """
6262
Custom rendering escape hatch.
6363
6464
Override this function to take full control. Receives the title and
65-
description for the current slug, plus the theme map. Must return a
65+
description for the current key, plus the theme map. Must return a
6666
PNG binary wrapped in `{:ok, ...}` or `{:error, reason}`.
6767
68-
If rendering fails (`{:error, _}`), the slug is skipped during baking.
68+
If rendering fails (`{:error, _}`), the key is skipped during baking.
6969
If not implemented, the default renderer is used.
7070
"""
7171
@callback render(title :: String.t(), desc :: String.t(), theme()) ::
7272
{:ok, binary()} | {:error, term()}
7373

7474
@doc """
75-
Returns the PNG bytes for `slug`.
75+
Returns the PNG bytes for `key`.
7676
77-
Always returns `{:ok, png_binary}`. Unknown slugs fall through to the
77+
Always returns `{:ok, png_binary}`. Unknown keys fall through to the
7878
pre-baked default image — never an error at the public API.
7979
"""
80-
@callback image_for(slug :: String.t()) :: {:ok, binary()}
80+
@callback image_for(key :: String.t()) :: {:ok, binary()}
8181

8282
@optional_callbacks render: 3
8383

@@ -117,11 +117,11 @@ defmodule OGMate do
117117

118118
# ── Content images (baked in prod, lazy in dev) ──────────────
119119
@og_images if(not @og_dev_mode) do
120-
Map.new(all_keys(), fn slug ->
121-
case content_for(slug) do
122-
{t, d} ->
123-
case OGMate.__bake__(__MODULE__, t, d, @og_theme) do
124-
{:ok, bytes} -> {slug, bytes}
120+
Map.new(all_keys(), fn key ->
121+
case content_for(key) do
122+
{title, description} ->
123+
case OGMate.__bake__(__MODULE__, title, description, @og_theme) do
124+
{:ok, bytes} -> {key, bytes}
125125
{:error, _} -> :skip
126126
end
127127

@@ -132,31 +132,34 @@ defmodule OGMate do
132132
end
133133

134134
# ── Public API: total, never errors ──────────────────────────
135-
@doc "Returns the PNG bytes for `slug`. Unknown slugs resolve to the default."
135+
@doc "Returns the PNG bytes for `key`. Unknown keys resolve to the default."
136136
@spec image_for(String.t()) :: {:ok, binary()}
137-
def image_for(slug) do
137+
def image_for(key) do
138138
case @og_images do
139139
nil ->
140140
# Dev mode: render on demand
141-
{t, d} = content_for(slug)
141+
{title, description} = content_for(key)
142142

143-
case OGMate.__bake__(__MODULE__, t, d, @og_theme) do
143+
case OGMate.__bake__(__MODULE__, title, description, @og_theme) do
144144
{:ok, bytes} ->
145145
{:ok, bytes}
146146

147147
{:error, reason} ->
148-
IO.warn("render failed for #{inspect(slug)}: #{inspect(reason)}, using default")
148+
IO.warn("render failed for #{inspect(key)}: #{inspect(reason)}, using default")
149149
{:ok, @og_default}
150150
end
151151

152152
map ->
153-
case Map.fetch(map, slug) do
153+
case Map.fetch(map, key) do
154154
{:ok, bytes} -> {:ok, bytes}
155155
:error -> {:ok, @og_default}
156156
end
157157
end
158158
end
159159

160+
@doc "Returns the pre-baked default PNG binary."
161+
def default_image(), do: @og_default
162+
160163
# ── Recompile hook ───────────────────────────────────────────
161164
def __mix_recompile__(), do: all_keys()
162165
end
@@ -171,8 +174,8 @@ defmodule OGMate do
171174
"""
172175
@spec __bake__(module(), String.t(), String.t(), map()) ::
173176
{:ok, binary()} | {:error, term()}
174-
def __bake__(module, title, desc, theme) do
175-
case render(module, title, desc, theme) do
177+
def __bake__(module, title, description, theme) do
178+
case render(module, title, description, theme) do
176179
{:ok, bytes} -> {:ok, bytes}
177180
{:error, reason} -> {:error, reason}
178181
end
@@ -181,11 +184,11 @@ defmodule OGMate do
181184
# Internal dispatch: user render or default renderer.
182185
@spec render(module(), String.t(), String.t(), map()) ::
183186
{:ok, binary()} | {:error, term()}
184-
defp render(module, title, desc, theme) do
187+
defp render(module, title, description, theme) do
185188
if function_exported?(module, :render, 3) do
186-
module.render(title, desc, theme)
189+
module.render(title, description, theme)
187190
else
188-
OGMate.Renderer.render(title, desc, theme)
191+
OGMate.Renderer.render(title, description, theme)
189192
end
190193
end
191194
end

0 commit comments

Comments
 (0)