Skip to content

Make optional plugin gems truly optional with require_optional - #145

Merged
id774 merged 1 commit into
masterfrom
claude/automatic-ruby-dependency-refactor-juudff
Aug 14, 2026
Merged

Make optional plugin gems truly optional with require_optional#145
id774 merged 1 commit into
masterfrom
claude/automatic-ruby-dependency-refactor-juudff

Conversation

@id774

@id774 id774 commented Aug 14, 2026

Copy link
Copy Markdown
Owner

Summary

This change restructures how Automatic Ruby handles optional plugin dependencies, making them genuinely optional by introducing a new Automatic.require_optional method and reorganizing the Gemfile to use fine-grained optional groups instead of a monolithic :plugins group.

Key Changes

  • New Automatic.require_optional method in lib/automatic.rb: Replaces bare require statements for optional gems with a method that provides helpful error messages naming the gem, the plugin that needs it, and installation instructions when a gem is missing.

  • Reorganized Gemfile: Replaced the single optional :plugins group with multiple fine-grained groups (store, html, sanitize, nkf, autodiscovery) so operators can install only what they need. The plugins group still exists as a convenience that includes all of them.

  • Updated plugin files to use Automatic.require_optional:

    • FilterSanitize, FilterDescriptionLink, FilterFullFeed, FilterImageSource, SubscriptionTwitter now use the new method
    • PublishMarkdown made truly optional by implementing HTML-to-text conversion without nokogiri as a fallback
  • PublishMarkdown enhancement: Added built-in HTML entity decoding and markup reduction without requiring nokogiri, allowing the Quick Start to run on a plain gem install automatic. When nokogiri is installed, it uses the parser for better handling of malformed markup.

  • Documentation updates across DEPLOYMENT.md, PLUGINS.md, POLICY.md, README.md, and QUICKSTART.md to explain the new optional dependency model and how to install gems for specific plugins.

  • New CI workflow (.github/workflows/plugins.yml): Tests that the optional plugins group resolves and that plugin specs pass when optional gems are installed.

  • Updated test infrastructure: Modified spec helpers and individual plugin specs to properly guard optional dependency tests and clarify the distinction between the default suite and optional plugin coverage.

Notable Implementation Details

  • Automatic.require_optional accepts gem_name parameter for gems where the require path differs from the gem name (e.g., xml-simple gem vs xmlsimple require path)
  • The Quick Start example (feed2markdown.yml) was simplified to not require StorePermalink by default, with instructions to add it as an optional step
  • Error handling in CLI now catches LoadError separately to provide user-friendly messages for missing optional gems rather than backtraces
  • The store plugins' dependencies (activerecord, sqlite3) are now properly declared as optional rather than runtime dependencies

https://claude.ai/code/session_019J9jKyHkYSFzPY7xiXLwSc

Installing the framework installed a database, an HTML parser and a feed
autodiscovery client, because the store plugins, the plugins that read
HTML and two CLI subcommands had their gems in the gemspec's runtime
dependencies. A Recipe that stores nothing and parses no HTML paid for
all of it, which is not what "small core plus independent plugins" means.

The runtime dependencies are now what lib/ requires and nothing else:
activesupport, hashie, rexml and rss. activerecord, sqlite3, nokogiri and
feedbag are optional plugin dependencies, declared in the Gemfile's
optional groups and required inside the plugin that uses them.

An optional gem is required through Automatic.require_optional, which
names the gem, what needed it and how to install it when it is absent;
the CLI reports that as a message and exit status 1 rather than a
backtrace. PublishMarkdown, which the Quick Start publishes with, now
reduces an HTML body to text with nokogiri where it is installed and with
its own substitution where it is not, so the documented first workflow
runs on a plain `gem install automatic`; the specs hold the two to the
same output. The shipped Quick Start Recipe drops StorePermalink, which
is now the documented next step, taken together with its gems.

Each optional gem is in two groups: `plugins`, which is all of them, and
one named for what it is for, which selects it alone. That gives the
three documented ways to set up a checkout -- minimal, all supported
plugins, and one dependency at a time -- and DEPLOYMENT.md carries the
single table of which plugin needs which gem. The plugins whose specs
need a running service stay outside `plugins`, so installing that group
leaves the suite runnable.

The default suite passes with no optional gem installed and the required
workflow installs none, which is what keeps the split honest; a separate
non-required workflow installs the `plugins` group and runs the same
suite.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019J9jKyHkYSFzPY7xiXLwSc
@id774
id774 merged commit 0734d2e into master Aug 14, 2026
8 checks passed
@id774
id774 deleted the claude/automatic-ruby-dependency-refactor-juudff branch August 14, 2026 19:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants