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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ for this cycle.
`com.demcha.compose.testing.layout` / `com.demcha.compose.testing.visual`
packages are unchanged, so imports stay the same; add `graph-compose-testing`
at test scope to keep using them.
- `graph-compose-bundle` is the batteries-included aggregate for the split layout:
one dependency pulls the default PDF stack (`graph-compose` = core + render-pdf),
the built-in templates (`graph-compose-templates`), the bundled Google fonts, and
the colour-emoji set at compatible pinned versions. The office backends
(`graph-compose-render-docx` / `graph-compose-render-pptx`) stay opt-in and are not
bundled.

## v1.9.0 — 2026-06-29

Expand Down
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,9 @@ dependencies { implementation("io.github.demchaav:graph-compose:2.0.0") }
>
> Prefer a single "batteries-included" coordinate? Depend on
> `io.github.demchaav:graph-compose-bundle` (same version as `graph-compose`
> above) to pull the engine + fonts together. Full details and upgrade steps:
> the [v1.8.0 fonts migration note](./docs/migration/v1.8.0-fonts.md).
> above) to pull the default PDF engine, the built-in templates, the fonts, and
> the colour emoji together. Full details and upgrade steps: the
> [v1.8.0 fonts migration note](./docs/migration/v1.8.0-fonts.md).

> **Colour emoji (from v1.9.0).** `RichText.emoji(":star:", size)` resolves
> GitHub-style shortcodes to inline vector glyphs from an independently-versioned
Expand All @@ -114,8 +115,9 @@ dependencies { implementation("io.github.demchaav:graph-compose:2.0.0") }
> ```
>
> An unknown shortcode falls back to its literal text, so a document that uses no
> emoji — or runs without the artifact — renders unchanged. The
> `graph-compose-bundle` stays fonts-only; emoji is opt-in.
> emoji — or runs without the artifact — renders unchanged. Depending
> on `graph-compose` directly keeps emoji opt-in; the batteries-included
> `graph-compose-bundle` includes it.

> **Distribution** — Maven Central is the canonical channel from **v1.6.6** onwards
> (`io.github.demchaav:graph-compose:<version>`). Hosted Javadocs auto-publish to
Expand Down
49 changes: 34 additions & 15 deletions bundle/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,33 @@

<!--
"Batteries-included" convenience aggregate. Depending on this single
artifact pulls the lean engine plus the bundled Google fonts at a
compatible, pinned pair of versions — the one-line install for newcomers
who want the pre-split behaviour back. Power users instead depend on
graph-compose directly and pick their own graph-compose-fonts version.
artifact pulls the default PDF stack (graph-compose = graph-compose-core +
graph-compose-render-pdf), the built-in document templates, the bundled
Google fonts, and the colour-emoji set — the one-line install for newcomers
who want everything wired up. The office backends (render-docx / render-pptx)
stay opt-in and are NOT bundled. Power users instead depend on the individual
coordinates and pick their own font/emoji versions.

Versioning: this module tracks the ENGINE line (its version == the engine
version, bumped in lockstep), and pins a specific graph-compose-fonts
version. It is standalone (no Maven parent) and pom-packaged, so Maven
Central needs no sources/javadoc jars for it.
version, bumped in lockstep), and pins specific graph-compose-fonts and
graph-compose-emoji versions (those two release on their own tag lines). It
is standalone (no Maven parent) and pom-packaged, so Maven Central needs no
sources/javadoc jars for it.
-->
<groupId>io.github.demchaav</groupId>
<artifactId>graph-compose-bundle</artifactId>
<!--
Tracks the engine line. Currently 1.7.1 to match the engine version in
the repo; the release-cut `versions:set` bumps engine + bundle to the
release version in lockstep, while graph-compose-fonts stays on its own
line. The graph-compose dependency below uses ${project.version}, so it
follows automatically.
Tracks the engine line (== the engine version in the repo); the release-cut
`versions:set` bumps engine + bundle to the release version in lockstep, while
graph-compose-fonts / graph-compose-emoji stay on their own lines. The
graph-compose and graph-compose-templates dependencies below use
${project.version}, so they follow automatically.
-->
<version>2.0.0-SNAPSHOT</version>
<packaging>pom</packaging>

<name>GraphCompose Bundle</name>
<description>Batteries-included aggregate: the GraphCompose engine plus the bundled Google fonts at compatible versions.</description>
<description>Batteries-included aggregate: the default PDF stack (engine + PDF backend), the built-in document templates, the bundled Google fonts, and the colour-emoji set at compatible versions.</description>
<url>https://github.com/DemchaAV/GraphCompose</url>

<licenses>
Expand Down Expand Up @@ -63,8 +66,11 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<!-- Pinned bundled-fonts version this bundle ships with. -->
<!-- Pinned bundled-fonts / colour-emoji versions this bundle ships with.
Both release on their own tag lines (fonts-v* / emoji-v*), so they are
pinned here rather than tracking ${project.version}. -->
<graphcompose.fonts.version>1.0.0</graphcompose.fonts.version>
<graphcompose.emoji.version>1.0.0</graphcompose.emoji.version>

<maven.gpg.plugin.version>3.2.8</maven.gpg.plugin.version>
<central.publishing.plugin.version>0.11.0</central.publishing.plugin.version>
Expand All @@ -73,18 +79,31 @@
</properties>

<dependencies>
<!-- The engine, at this bundle's (== engine) version. -->
<!-- The default PDF stack: the graph-compose wrapper pulls graph-compose-core
+ graph-compose-render-pdf, so a bundle consumer renders PDF out of the box. -->
<dependency>
<groupId>io.github.demchaav</groupId>
<artifactId>graph-compose</artifactId>
<version>${project.version}</version>
</dependency>
<!-- The built-in CV / cover-letter / invoice / proposal templates. -->
<dependency>
<groupId>io.github.demchaav</groupId>
<artifactId>graph-compose-templates</artifactId>
<version>${project.version}</version>
</dependency>
<!-- The bundled fonts, at the pinned independent fonts version. -->
<dependency>
<groupId>io.github.demchaav</groupId>
<artifactId>graph-compose-fonts</artifactId>
<version>${graphcompose.fonts.version}</version>
</dependency>
<!-- The colour-emoji set, at the pinned independent emoji version. -->
<dependency>
<groupId>io.github.demchaav</groupId>
<artifactId>graph-compose-emoji</artifactId>
<version>${graphcompose.emoji.version}</version>
</dependency>
</dependencies>

<profiles>
Expand Down
15 changes: 9 additions & 6 deletions docs/contributing/release-process.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,9 @@ is a convenience aggregate `io.github.demchaav:graph-compose-bundle` (under

The colour-emoji glyphs ship as a **separate, independently-versioned**
artifact, `io.github.demchaav:graph-compose-emoji` (under `emoji/`), mirroring
the fonts arrangement above — with one difference: the **bundle does NOT
include emoji** (it stays opt-in), so a fonts-style consumer re-pin is not
needed.
the fonts arrangement above — including the `graph-compose-bundle`, which pins
`graph-compose-emoji` (via `${graphcompose.emoji.version}`) just as it pins the
fonts, so cutting an emoji release needs the same consumer re-pin.

- **NOT bumped by the engine release.** It carries its own version line
(started at `1.0.0`) and is bumped **only when the glyph set or shortcode
Expand All @@ -147,9 +147,12 @@ needed.
- **Cutting an emoji release** (only when the set changes): bump
`emoji/pom.xml` `<version>`, push an `emoji-vX.Y.Z` tag. That tag triggers
[`publish-emoji.yml`](../../.github/workflows/publish-emoji.yml), which deploys
only `graph-compose-emoji` to Central. The engine has no dependency on the
emoji artifact (its tests read the glyphs from the sibling module's source via
`<testResources>`), so nothing else needs re-pinning.
only `graph-compose-emoji` to Central. Then bump `<graphcompose.emoji.version>`
in `aggregator/pom.xml` (inherited by examples) and `bundle/pom.xml` to the new
emoji version so those consumers pin it — the `bundledEmojiVersionAgreesAcrossModules`
version guard enforces that the two stay in agreement. The engine `pom.xml` does
**not** carry this property — the engine has no dependency on the emoji artifact
(its tests read the glyphs from the sibling module's source via `<testResources>`).
- **Regenerating the set.** `emoji/tools/build-emoji-set.py` rebuilds
`emoji/svg/` + `emoji-index.properties` from fresh Noto Emoji + gemoji sources,
copying **only** the glyphs a shortcode resolves (see
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,26 @@ void bundledFontsVersionAgreesAcrossModules() throws Exception {
// it: the aggregator (inherited by examples + benchmarks) and the bundle.
// This guards the version-literal drift class: those must always agree, even
// though they differ from the engine version line.
String aggregator = fontsVersionProperty(PROJECT_ROOT.resolve("aggregator/pom.xml"));
String aggregator = pinnedVersionProperty(PROJECT_ROOT.resolve("aggregator/pom.xml"), "graphcompose.fonts.version");

assertThat(fontsVersionProperty(PROJECT_ROOT.resolve("bundle/pom.xml")))
assertThat(pinnedVersionProperty(PROJECT_ROOT.resolve("bundle/pom.xml"), "graphcompose.fonts.version"))
.describedAs("bundle graphcompose.fonts.version must match the aggregator's (%s)", aggregator)
.isEqualTo(aggregator);
}

@Test
void bundledEmojiVersionAgreesAcrossModules() throws Exception {
// graph-compose-emoji, like graph-compose-fonts, carries an independent
// version line (emoji-v* tag) and the ${graphcompose.emoji.version} property
// that pins it lives in the aggregator (inherited by examples) and the bundle
// (which now ships the colour-emoji set). Guard the same version-literal drift.
String aggregator = pinnedVersionProperty(PROJECT_ROOT.resolve("aggregator/pom.xml"), "graphcompose.emoji.version");

assertThat(pinnedVersionProperty(PROJECT_ROOT.resolve("bundle/pom.xml"), "graphcompose.emoji.version"))
.describedAs("bundle graphcompose.emoji.version must match the aggregator's (%s)", aggregator)
.isEqualTo(aggregator);
}

@Test
void childModulesInheritVersionInsteadOfDeclaringTheirOwn() throws Exception {
assertThat(declaresOwnVersion(PROJECT_ROOT.resolve("examples/pom.xml")))
Expand Down Expand Up @@ -288,11 +301,11 @@ private static boolean declaresOwnVersion(Path pom) throws Exception {
return directChild(parse(pom).getDocumentElement(), "version") != null;
}

private static String fontsVersionProperty(Path pom) throws IOException {
Matcher matcher = Pattern.compile("<graphcompose\\.fonts\\.version>([^<]+)</graphcompose\\.fonts\\.version>")
private static String pinnedVersionProperty(Path pom, String property) throws IOException {
Matcher matcher = Pattern.compile("<" + Pattern.quote(property) + ">([^<]+)</" + Pattern.quote(property) + ">")
.matcher(Files.readString(pom));
assertThat(matcher.find())
.describedAs("expected a <graphcompose.fonts.version> property in %s", pom)
.describedAs("expected a <%s> property in %s", property, pom)
.isTrue();
return matcher.group(1).trim();
}
Expand Down