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 .claude/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
79 changes: 79 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# AGENTS.md

Instructions for AI coding agents (Claude Code, Cursor, Codex, etc.) working in this repository.

## Project overview

`gephi-plugins` is the scaffold and Maven build harness contributors fork to develop and submit
plugins for [Gephi](https://gephi.org), the graph visualization platform. A plugin is a NetBeans
module that implements one of Gephi's extension points (SPIs) — this repo does not contain Gephi
itself or, on `master`, any plugin source by default. See `README.md` for the day-to-day
getting-started flow (create/build/run/submit a plugin) and `ARCHITECTURE.md` for how the repository
(including its unusual three-branch model), the `gephi-maven-plugin` build lifecycle, and Gephi's
SPI/Lookup extension mechanism fit together.

Read `ARCHITECTURE.md` before assuming something is broken: an empty `<modules>` list in `pom.xml`,
or the absence of `modules/pom.xml`, is expected on `master` — see its "Repository / branch model"
section.

## Build and test

Requires JDK 17 and Maven.

- Scaffold a new plugin (interactive prompts): `mvn org.gephi:gephi-maven-plugin:generate`
- Build and validate every plugin currently listed in `pom.xml`: `mvn clean package`
- Build/test a single plugin module: `mvn -pl modules/<ModuleName> clean package`
- Run a single module's unit tests only: `mvn -pl modules/<ModuleName> test`
- Run Gephi with the module(s) installed (build first): `mvn org.gephi:gephi-maven-plugin:run`
- IDE run/debug configs are defined in `nbactions.xml`; the IntelliJ debug setup (remote debugger +
`-Drun.params.debug` VM option) is documented in `README.md`.

`mvn package` always runs `gephi-maven-plugin:validate` at the `validate` phase — if a build fails
there, the error names the specific manifest/pom problem; fix that rather than working around it.

## Adding or changing a plugin

- One plugin (or one suite of related modules) per folder under `modules/`, added to the root
`pom.xml`'s `<modules>` list — `generate` does both steps for you; do it manually the same way if
extending an existing plugin's suite.
- A plugin's `pom.xml` inherits from `org.gephi:gephi-plugin-parent` (published from this repo's
`parent-pom` branch — not present in a normal `master` checkout). Add dependencies without a
`<version>`; the parent's `dependencyManagement` supplies the version matching the target Gephi
release. See `ARCHITECTURE.md`.
- Register SPI implementations with `@ServiceProvider(service = ...)`; see `ARCHITECTURE.md`'s
"How Gephi can be extended" section for which SPI fits a given feature, and the
[core Gephi ARCHITECTURE.md](https://github.com/gephi/gephi/blob/master/ARCHITECTURE.md) for the
full API/SPI/Lookup design.
- Bump the plugin's own `<version>` in its `pom.xml` on every update — the autoupdate site keys off
it, and reviewers check for it.
- Only list packages meant for other modules to use under `<publicPackages>` in the plugin's
`pom.xml`.

## Code style

See `CONTRIBUTING.md`'s "Code quality" section rather than duplicating it here.

## PR / commit guidelines

- Plugin submissions (new plugin or update) target the `master-forge` branch, not `master` — see
README's "Submit a plugin" / "Update a plugin" sections. Changes to the scaffold itself (root
`pom.xml`, `.github/workflows`, this file, `ARCHITECTURE.md`) target `master`.
- Use `.github/issue_template.md`'s structure when filing or triaging bug reports.
- Keep commits scoped to one plugin or one logical change — a PR touching unrelated plugins in the
same suite stands out during review.

### Reviewing a third-party plugin PR

Most activity in this repo is reviewing plugin submissions rather than writing plugin code. When
asked to review one, work through `CONTRIBUTING.md`'s "Reviewing a plugin submission PR" checklist
(build, `pom.xml` config, manifest/branding, SPI registration, licensing, file hygiene, tests, PR
template completeness) and report findings against specific, named items from it rather than general
impressions — these PRs reliably have the same handful of holes, and the checklist exists to catch
them without re-deriving them each time.

## Security

- Never commit secrets, API keys, or tokens. `release-pom.yml` publishes to Maven Central using
repository secrets (GPG key, OSSRH credentials) — never hardcode credentials locally to bypass it.
- This is a public repository — don't add personal or employer-internal tooling references (private
registries, internal URLs, machine-specific paths) to any committed file.
152 changes: 152 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# gephi-plugins Architecture

## What this repository is

`gephi-plugins` is not a plugin, and (on the branch you're most likely looking at) it is not a
collection of plugins either. It is the scaffold and Maven build harness that contributors fork to
develop and submit plugins for [Gephi](https://gephi.org), the graph visualization platform built on
the Apache NetBeans Platform.

```text
Your plugin module(s) (modules/<PluginName>, added by you or by `generate`)
│ implements a Gephi SPI, declares Maven deps on Gephi/NetBeans API modules
Gephi (downloaded as a build dependency; see root pom.xml)
NetBeans Platform (module system, Lookup, `.nbm` packaging)
Java
```

A plugin is nothing more than another NetBeans module, built the same way Gephi's own modules are
built, that Gephi discovers at startup because it's on the classpath. This repository exists to make
that build set up correctly (manifest, packaging, dependency versions) without contributors needing
to hand-roll it.

## Repository / branch model

This is the part that isn't obvious from a single checkout: the same GitHub repository serves three
different purposes on three different branches. Confusion here (e.g. "why is `<modules>` empty?",
"where is `modules/pom.xml`?") almost always traces back to not knowing which branch does what.

| Branch | Purpose |
|---|---|
| `master` | The template. `pom.xml`'s `<modules>` list starts empty. Contributors fork this branch and add their own plugin(s) to it locally — this is what `mvn org.gephi:gephi-maven-plugin:generate` does. Most day-to-day plugin development happens against a `master`-based fork. |
| `master-forge` | Where plugin submissions land. It accumulates every community plugin in one big multi-module build, and is what generates the plugin listing at gephi.org. PRs submitting or updating a plugin target this branch, not `master` (see README's "Submit a plugin"). |
| `parent-pom` | Hosts `modules/pom.xml`, the actual `gephi-plugin-parent` Maven artifact (see below). Pushing to this branch triggers `release-pom.yml`, which deploys `org.gephi:gephi-plugin-parent` to Maven Central. |

`build.yml` (the main CI workflow) runs on every branch push *except* `master-forge`, `master`,
`parent-pom`, and `gh-pages` — i.e. on the feature/topic branches contributors actually push to.
`test-generation.yml` runs on `master` and is an integration test for the scaffold itself: it runs
`generate`, `package`, and the `release` profile's `build-metadata`/`create-autoupdate` goals against
a throwaway fixture plugin, so a `gephi-maven-plugin` version bump in `pom.xml` is caught before real
plugin repos pick it up.

## How Gephi can be extended

Gephi's extensibility model is what determines what a plugin *is*. This section summarizes the
mechanism; see the [core Gephi ARCHITECTURE.md](https://github.com/gephi/gephi/blob/master/ARCHITECTURE.md)
for the full treatment (API/SPI design philosophy, controllers/models, Lookup internals).

Gephi separates **APIs** (functionality a module offers to others, e.g. `ProjectController`) from
**SPIs** (Service Provider Interfaces — extension points meant to be implemented by core modules
*and* plugins alike, e.g. `Importer`, `Layout`, `Statistics`). A plugin always extends an SPI; it
never needs to modify Gephi core to add functionality.

| SPI | Extension point |
|---|---|
| Import SPI | File, database, and wizard importers |
| Layout SPI | Layout algorithms |
| Statistics SPI | Metrics and other graph algorithms |
| Tools SPI | Tools in the visualization toolbar |
| Export SPI | File exporters for graphs and graphics |
| Filters SPI | Filters |
| Preview SPI | Preview builders and renderers |
| Generator SPI | Graph generators |
| Data Laboratory SPI | Data Laboratory manipulators |
| Appearance SPI | Transformers for ranking and partitioning nodes/edges |
| Project SPI | Persistence providers for `.gephi` project files |
| Visualization SPI | Renderers for the newer `VisualizationEngine` module (work in progress) |

Implementations are discovered at runtime through **Lookup**, NetBeans's service-registry mechanism,
not through any Gephi-specific plugin registry:

```java
@ServiceProvider(service = Layout.class)
public class MyLayout implements Layout {
}
```

Annotating a class this way is what makes it show up in Gephi's layout list, exporter list, filter
list, etc. — implementing the interface alone is not enough; without `@ServiceProvider`, `Lookup`
will not find it. This is also the whole mechanism: there's no separate "plugin API" beyond the SPI
you're implementing and this annotation.

## Anatomy of a plugin module

`mvn org.gephi:gephi-maven-plugin:generate` produces this layout under `modules/<PluginName>/`:

```text
modules/<PluginName>/
├── src/
│ └── main/
│ ├── java/ # SPI implementation(s), e.g. org.foo.myplugin.MyLayout
│ ├── resources/ # Bundle.properties, icons
│ └── nbm/
│ └── manifest.mf # OpenIDE-Module-* branding/description/category entries
└── pom.xml # parent = org.gephi:gephi-plugin-parent, packaging = nbm
```

The generated `pom.xml` sets `<parent>` to `org.gephi:gephi-plugin-parent` (see below) and
configures `nbm-maven-plugin` with the plugin's author/license and a `<publicPackages>` list —
only packages listed there are visible to other modules/plugins, mirroring the public-package
convention used throughout core Gephi. `manifest.mf` carries the branding shown in Gephi's Plugin
Manager (`OpenIDE-Module-Name`, `-Short-Description`, `-Long-Description`, `-Display-Category`), or
alternatively an `OpenIDE-Module-Localizing-Bundle` pointer into `Bundle.properties` when the text is
too long for the manifest format.

A plugin can also be a **suite**: several modules in the same top-level folder that split API,
implementation, and UI concerns (the same four-role convention — `XxxAPI` / `XxxPlugin` /
`XxxPluginUI` / `DesktopXxx` — used across core Gephi's own modules). This is only worth doing for
plugins complex enough to need a shared API surface between multiple sub-modules; a single module is
enough for the vast majority of plugins.

## Dependency management: `gephi-plugin-parent`

Every plugin's `pom.xml` inherits from `org.gephi:gephi-plugin-parent` — an artifact built from this
repo's `parent-pom` branch, published to Maven Central, and versioned alongside Gephi itself (e.g.
`0.11.3`). It supplies:

- Java/compiler settings (JDK 17 target).
- A `<dependencyManagement>` entry for every Gephi and NetBeans Platform module a plugin might
depend on (`graph-api`, `layout-api`, `org-openide-util-lookup`, etc.), so a plugin's own `pom.xml`
can declare a dependency without a `<version>` and get the right one for the Gephi version it
targets.

This is why the root `pom.xml` on `master` and `master-forge` looks different from
`modules/pom.xml` on `parent-pom`: the former is the reactor POM that aggregates whichever plugin
modules exist in this checkout (`<packaging>pom</packaging>`, lists `<modules>`); the latter is the
plugin parent POM those modules inherit build configuration and dependency versions from.

## The `gephi-maven-plugin` build lifecycle

[`gephi-maven-plugin`](https://github.com/gephi/gephi-maven-plugin) is the Maven plugin that drives
everything above. Its goals, bound in this repo's root `pom.xml` or invoked directly:

| Goal | When it runs | What it does |
|---|---|---|
| `generate` | Invoked manually | Interactively scaffolds a new plugin module and adds it to `pom.xml`'s `<modules>` |
| `validate` | Bound to the `validate` phase (every `mvn package`) | Checks every listed module's manifest/pom configuration is well-formed; fails the build with a specific reason if not |
| `run` | Invoked manually | Downloads/builds the matching Gephi distribution and launches it with the current modules installed, for manual testing |
| `build-metadata` / `create-autoupdate` | Bound to the `package` phase under the `release` profile | Generates the autoupdate site (`updates.xml` + `.nbm` files) published to `metadataUrl` — this is what powers Gephi's in-app Plugin Manager and the gephi.org plugin listing |
| `migrate` | Invoked manually | Helps update an existing plugin's configuration when the target Gephi version changes |

## Root files

```text
.github/workflows/ # build.yml (feature branches), test-generation.yml (master), release-pom.yml (parent-pom)
modules/ # one folder per plugin/suite; empty <modules> list on master until you add one
plugins/ # static assets (images) used by the gephi.org plugin listing, not source code
pom.xml # reactor POM for this checkout's plugin modules — NOT the plugin parent POM
nbactions.xml # NetBeans IDE run/debug actions (`mvn package org.gephi:gephi-maven-plugin:run`)
```
Loading
Loading