Skip to content

Commit

Permalink
Merge pull request #77 from block/myron/dependabot-fixes/step3
Browse files Browse the repository at this point in the history
Validate our gemspecs using an RSpec test.
  • Loading branch information
myronmarston authored Dec 30, 2024
2 parents dac76f1 + 634eae7 commit 16ea0b5
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 61 deletions.
11 changes: 11 additions & 0 deletions elasticgraph/spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright 2024 Block, Inc.
#
# Use of this source code is governed by an MIT-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT.
#
# frozen_string_literal: true

# This file is contains RSpec configuration and common support code for `elasticgraph`.
# Note that it gets loaded by `spec_support/spec_helper.rb` which contains common spec support
# code for all ElasticGraph test suites.
70 changes: 70 additions & 0 deletions elasticgraph/spec/unit/elastic_graph/gem_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Copyright 2024 Block, Inc.
#
# Use of this source code is governed by an MIT-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT.
#
# frozen_string_literal: true

require_relative "../../../../script/list_eg_gems"

module ElasticGraph
RSpec.describe "ElasticGraph gems" do
gemspecs_by_gem_name = ::Hash.new do |hash, gem_name|
hash[gem_name] = begin
gemspec_file = ::File.join(CommonSpecHelpers::REPO_ROOT, gem_name, "#{gem_name}.gemspec")
eval(::File.read(gemspec_file), ::TOPLEVEL_BINDING.dup, gemspec_file) # standard:disable Security/Eval
end
end

shared_examples_for "an ElasticGraph gem" do |gem_name|
around do |ex|
::Dir.chdir(::File.join(CommonSpecHelpers::REPO_ROOT, gem_name), &ex)
end

let(:gemspec) { gemspecs_by_gem_name[gem_name] }

it "has the correct name" do
expect(gemspec.name).to eq gem_name
end

it "has no symlinked files included in the gem since they do not work correctly when the gem is packaged packaged" do
symlink_files = gemspec.files.select { |f| ::File.exist?(f) && ::File.ftype(f) == "link" }
expect(symlink_files).to be_empty
end

%w[.yardopts Gemfile .rspec].each do |file|
it "has a symlinked `#{file}` file" do
expect(::File.exist?(file)).to be true
expect(::File.ftype(file)).to eq "link"
end
end

it "has a non-symlinked `LICENSE.txt` file" do
expect(::File.exist?("LICENSE.txt")).to be true
expect(::File.ftype("LICENSE.txt")).to eq "file"
expect(::File.read("LICENSE.txt")).to include("MIT License", "Copyright (c) 2024 Block, Inc.")
end
end

::ElasticGraphGems.list.each do |gem_name|
describe gem_name do
include_examples "an ElasticGraph gem", gem_name
end
end

# We don't expect any variation in these gemspec attributes.
%i[authors email homepage license required_ruby_version version].each do |gemspec_attribute|
it "has the same value for `#{gemspec_attribute}` in all ElasticGraph gemspecs" do
all_gemspec_values = ::ElasticGraphGems.list.to_h do |gem_name|
[gem_name, gemspecs_by_gem_name[gem_name].public_send(gemspec_attribute)]
end

most_common_value = all_gemspec_values.values.tally.max_by { |_, count| count }.first
nonstandard_gemspec_values = all_gemspec_values.select { |_, value| value != most_common_value }

expect(nonstandard_gemspec_values).to be_empty
end
end
end
end
61 changes: 0 additions & 61 deletions gemspec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ module ElasticGraphGemspecHelper
# Helper methor for defining a gemspec for an elasticgraph gem.
def self.define_elasticgraph_gem(gemspec_file:, category:)
gem_dir = ::File.expand_path(::File.dirname(gemspec_file))
validate_gem(gem_dir)

::Gem::Specification.new do |spec|
spec.name = ::File.basename(gemspec_file, ".gemspec")
Expand Down Expand Up @@ -48,66 +47,6 @@ def self.define_elasticgraph_gem(gemspec_file:, category:)
spec.required_ruby_version = "~> 3.2"

yield spec, ElasticGraph::VERSION

if (symlink_files = spec.files.select { |f| ::File.exist?(f) && ::File.ftype(f) == "link" }).any?
raise "#{symlink_files.size} file(s) of the `#{spec.name}` gem are symlinks, but " \
"symlinks do not work correctly when the gem is packaged. Symlink files: #{symlink_files.inspect}"
end
end
end

def self.validate_gem(gem_dir)
gem_warnings = validate_symlinked_file(::File.join(gem_dir, ".yardopts"))

gem_issues = []
gem_issues.concat(validate_symlinked_file(::File.join(gem_dir, "Gemfile")))
gem_issues.concat(validate_symlinked_file(::File.join(gem_dir, ".rspec")))
gem_issues.concat(validate_license(gem_dir))

unless gem_warnings.empty?
warn "WARNING: Gem #{::File.basename(gem_dir)} has the following issues:\n\n" + gem_warnings.join("\n")
end

return if gem_issues.empty?

abort "Gem #{::File.basename(gem_dir)} has the following issues:\n\n" + gem_issues.join("\n")
end

def self.validate_symlinked_file(file)
gem_issues = []

if ::File.exist?(file)
if ::File.ftype(file) != "link"
gem_issues << "`#{file}` must be a symlink."
end
else
gem_issues << "`#{file}` is missing."
end

gem_issues
end

def self.validate_license(gem_dir)
gem_issues = []

file = ::File.join(gem_dir, "LICENSE.txt")
if ::File.exist?(file)
if ::File.ftype(file) == "link"
gem_issues << "`#{file}` must not be a symlink."
end

contents = ::File.read(file)
unless contents.include?("MIT License")
gem_issues << "`#{file}` must contain 'MIT License'."
end

unless contents.include?("Copyright (c) 2024 Block, Inc.")
gem_issues << "`#{file}` must contain Block copyright notice."
end
else
gem_issues << "`#{file}` is missing."
end

gem_issues
end
end

0 comments on commit 16ea0b5

Please sign in to comment.