Skip to content

Ship LICENSE and README.md in the packaged gem #7

Description

@agrberg

s.files in array_proc.gemspec lists only lib/array_proc.rb, so the built .gem contains exactly one file. LICENSE and README.md are in the repository but never travel with the package.

Verified by building the gem and listing the payload:

$ gem build array_proc.gemspec -o out.gem
$ tar -xOf out.gem data.tar.gz | tar -tzf -
lib/array_proc.rb

Two consequences.

s.licenses = ['MIT'] declares the license in the gemspec metadata, but the MIT terms ask that the copyright notice and permission text accompany all copies of the software. Someone who installs the gem and never visits GitHub has the declaration without the text.

Anyone reading the gem offline, through gem contents array_proc or by unpacking it, gets no usage documentation. The README.md is the only place the &[:method, :other] shorthand is explained.

Fix is a one-line gemspec change:

s.files = ['lib/array_proc.rb', 'LICENSE', 'README.md']

This changes the packaged contents, so it needs a version bump and a release rather than riding along with a repo-only commit.

Same gap exists in the sibling gems (string_proc, hash_of, object_pick, cacheable, unique_permutation); worth fixing across all of them at once.

Found while auditing the gemspec during the Ruby 4.0.6 and lockfile cleanup in a874e98.


Release checklist

Every item here changes what a user receives, so they should land together in one release rather than spending a version bump on each. Ruby 3.3 goes EOL 2027-03-31, and the floor bump is the natural release to attach the rest to.

  • s.files gains LICENSE and README.md (see above)
  • required_ruby_version to >= 3.4 once 3.3 is EOL
  • Drop '3.3' from the CI test matrix and from the lint job's ruby-version
  • Add s.metadata['homepage_uri'] for consistency; hash_of sets it and the other four do not
  • Version bump, then gem push

Two things explicitly need no action. RuboCop's TargetRubyVersion is now inferred from required_ruby_version (the duplicated setting was removed in 69fa796), so raising the gemspec floor moves the lint target on its own. And changelog_uri is left off deliberately: only hash_of has a CHANGELOG.md, so setting it here would point at a file that does not exist.


Cross-repo uniformity backlog

Places where the five gems still differ and we want them the same. Nothing here is required for the release above; it is recorded so each item gets decided once instead of being rediscovered per repo.

Adopt from hash_of

  • bundler/gem_tasks in every Rakefile. Only hash_of requires it, so it is the only gem with rake build and rake release. Five releases are coming when 3.3 drops, so this is worth having in place first.
  • Version constant in lib/<gem>/version.rb. hash_of does this; the other four inline the version string in the gemspec. A constant is reachable at runtime and is what bundler/gem_tasks expects, so it pairs with the item above. Changes packaged files, so it rides along with a release.
  • CHANGELOG.md. Only hash_of has one. Adding them is what unlocks s.metadata['changelog_uri'], which the release checklists currently skip for exactly this reason.
  • sig/<gem>.rbs type signatures. Only hash_of ships them. Stretch goal, but these gems are ten lines each.
  • RSpec.configure block in spec_helper.rb with disable_monkey_patching!, .rspec_status persistence, and c.syntax = :expect. More than cosmetic here: these gems patch core classes, so turning RSpec's own global monkey-patching off is directly relevant. Cost to check before starting: the other four use bare describe at the top level, which stops working under disable_monkey_patching!. Every spec file needs describe changed to RSpec.describe.

Adopt from unique_permutation

  • ruby-head and jruby-head CI jobs with continue-on-error. Only unique_permutation runs them. For gems that patch Array, String, Hash, and Object, free early warning on upstream Ruby changes is worth two extra jobs.

Pick a direction

  • Rakefile default task order. Three gems run %i[spec rubocop]; unique_permutation runs %i[rubocop spec] and its desc states that ordering as deliberate. Genuinely a coin flip. Suggest standardizing on %i[spec rubocop] to match the majority, unless the faster-lint-feedback argument wins.

Considered, deliberately not unified

hash_of's gemspec uses spec as the block variable, double-quoted strings, spec.license singular rather than s.licenses as an array, and an array for spec.email. All valid, and the quote style is enforced by that repo's own Style/StringLiterals config, so unifying would mean churning the RuboCop config too. Recorded here so it is not rediscovered as drift.

object_pick's Gemfile carries gem 'ostruct' and the others do not. That is a real dependency, not drift: spec/object_pick_spec.rb:70 uses OpenStruct, and ostruct is no longer a default gem.

unique_permutation's .rubocop.yml disables RSpec/DescribedClass and RSpec/SpecFilePathFormat and excludes Style/NumericPredicate for its lib file. Each carries an inline comment explaining why ("Monkey-patching Array — not testing Array itself"). Self-documenting and correct for a gem that patches a core class; the other gems that patch core classes could arguably adopt the same two RSpec exclusions, but none of them currently trip those cops.

spec/spec_helper.rb differs in all five repos. Four of those differences are just the require_relative path to that gem's own lib and are not drift at all. The fifth, hash_of's RSpec.configure block, is the real difference and is already listed as an adopt-from item above.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions