diff --git a/CHANGELOG.md b/CHANGELOG.md index 482547dc7c..e91d427479 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,10 @@ Please visit [cucumber/CONTRIBUTING.md](https://github.com/cucumber/cucumber/blo ### Changed +- Replace dependency [cucumber-create-meta](https://rubygems.org/gems/cucumber-create-meta) + with the new [cucumber-ci-environment](https://rubygems.org/gems/cucumber-ci-environment) + ([PR#1601](https://github.com/cucumber/cucumber-ruby/pull/1601)) + - In `DataTable#map_column`, Changed the `strict` argument into a keyword argument. See [UPGRADING.md](./UPGRADING.md#upgrading-to-800). ([PR#1594](https://github.com/cucumber/cucumber-ruby/pull/1594) diff --git a/cucumber.gemspec b/cucumber.gemspec index 024d2d966f..82164ac89f 100644 --- a/cucumber.gemspec +++ b/cucumber.gemspec @@ -20,8 +20,8 @@ Gem::Specification.new do |s| # Keep in sync with .circleci/config.yml & .rubocop.yml s.required_ruby_version = '>= 2.5' s.add_dependency 'builder', '~> 3.2', '>= 3.2.4' + s.add_dependency 'cucumber-ci-environment', '~> 8.0', '>= 8.0.1' s.add_dependency 'cucumber-core', '~> 10.1', '>= 10.1.0' - s.add_dependency 'cucumber-create-meta', '~> 6.0', '>= 6.0.2' s.add_dependency 'cucumber-cucumber-expressions', '~> 14.0', '>= 14.0.0' s.add_dependency 'cucumber-gherkin', '~> 22.0', '>= 22.0.0' s.add_dependency 'cucumber-html-formatter', '~> 17.0', '>= 17.0.0' diff --git a/lib/cucumber/runtime.rb b/lib/cucumber/runtime.rb index 97e56f7ef1..ba245074b0 100644 --- a/lib/cucumber/runtime.rb +++ b/lib/cucumber/runtime.rb @@ -2,7 +2,6 @@ require 'fileutils' require 'cucumber/configuration' -require 'cucumber/create_meta' require 'cucumber/deprecate' require 'cucumber/load_path' require 'cucumber/formatter/duration' @@ -13,6 +12,7 @@ require 'cucumber/glue/registry_wrapper' require 'cucumber/step_match_search' require 'cucumber/messages' +require 'cucumber/runtime/meta_message_builder' require 'sys/uname' module Cucumber @@ -68,7 +68,7 @@ def configure(new_configuration) def run! @configuration.notify :envelope, Cucumber::Messages::Envelope.new( - meta: Cucumber::CreateMeta.create_meta('cucumber-ruby', Cucumber::VERSION) + meta: MetaMessageBuilder.build_meta_message ) load_step_definitions diff --git a/lib/cucumber/runtime/meta_message_builder.rb b/lib/cucumber/runtime/meta_message_builder.rb new file mode 100644 index 0000000000..0d0e6cef49 --- /dev/null +++ b/lib/cucumber/runtime/meta_message_builder.rb @@ -0,0 +1,106 @@ +require 'cucumber/messages' +require 'cucumber/ci_environment' + +module Cucumber + class Runtime + # Builder to instanciate a Cucumber::Messages::Meta message filled-in with + # the runtime meta-data: + # - protocol version: the version of the Cucumber::Messages protocol + # - implementation: the name and version of the implementation (e.g. cucumber-ruby 8.0.0) + # - runtime: the name and version of the runtime (e.g. ruby 3.0.1) + # - os: the name and version of the operating system (e.g. linux 3.13.0-45-generic) + # - cpu: the name of the CPU (e.g. x86_64) + # - ci: informtion about the CI environment if any, including: + # - name: the name of the CI environment (e.g. Jenkins) + # - url: the URL of the CI environment (e.g. https://ci.example.com) + # - build_number: the build number of the CI environment (e.g. 123) + # - git: the git information of the CI environment if any + # - remote: the remote of the git repository (e.g. git@github.com:cucumber/cucumber-ruby.git) + # - revision: the revision of the git repository (e.g. abcdef) + # - branch: the name of the git branch (e.g. main) + # - tag: the name of the git tag (e.g. v1.0.0) + class MetaMessageBuilder + class << self + # Builds a Cucumber::Messages::Meta filled-in with the runtime meta-data + # + # @param [env] environment data from which the CI information will be + # retrieved (default ENV). Can be used to mock the environment for + # testing purpose. + # + # @return [Cucumber::Messages::Meta] the meta message + # + # @see Cucumber::Runtime::MetaMessageBuilder + # + # @example + # Cucumber::Runtime::MetaMessageBuilder.build_meta_message + # + def build_meta_message(env = ENV) + Cucumber::Messages::Meta.new( + protocol_version: protocol_version, + implementation: implementation, + runtime: runtime, + os: os, + cpu: cpu, + ci: ci(env) + ) + end + + private + + def protocol_version + Cucumber::Messages::VERSION + end + + def implementation + Cucumber::Messages::Product.new( + name: 'cucumber-ruby', + version: Cucumber::VERSION + ) + end + + def runtime + Cucumber::Messages::Product.new( + name: RUBY_ENGINE, + version: RUBY_VERSION + ) + end + + def os + Cucumber::Messages::Product.new( + name: RbConfig::CONFIG['target_os'], + version: Sys::Uname.uname.version + ) + end + + def cpu + Cucumber::Messages::Product.new( + name: RbConfig::CONFIG['target_cpu'] + ) + end + + def ci(env) + ci_data = Cucumber::CiEnvironment.detect_ci_environment(env) + return nil unless ci_data + + Cucumber::Messages::Ci.new( + name: ci_data[:name], + url: ci_data[:url], + build_number: ci_data[:buildNumber], + git: git_info(ci_data) + ) + end + + def git_info(ci_data) + return nil unless ci_data[:git] + + Cucumber::Messages::Git.new( + remote: ci_data[:git][:remote], + revision: ci_data[:git][:revision], + branch: ci_data[:git][:branch], + tag: ci_data[:git][:tag] + ) + end + end + end + end +end diff --git a/spec/cucumber/runtime/meta_message_builder_spec.rb b/spec/cucumber/runtime/meta_message_builder_spec.rb new file mode 100644 index 0000000000..106b58b2cb --- /dev/null +++ b/spec/cucumber/runtime/meta_message_builder_spec.rb @@ -0,0 +1,93 @@ +require 'spec_helper' +require 'cucumber/runtime/meta_message_builder' + +describe Cucumber::Runtime::MetaMessageBuilder do + describe 'self#build_meta_message' do + subject { Cucumber::Runtime::MetaMessageBuilder.build_meta_message } + + it { is_expected.to be_a(Cucumber::Messages::Meta) } + + it 'fills system info in the meta message' do + expect(subject.protocol_version).to eq(Cucumber::Messages::VERSION) + expect(subject.implementation.name).to eq('cucumber-ruby') + expect(subject.implementation.version).to eq(Cucumber::VERSION) + expect(subject.runtime.name).to eq(RUBY_ENGINE) + expect(subject.runtime.version).to eq(RUBY_VERSION) + expect(subject.os.name).to eq(RbConfig::CONFIG['target_os']) + expect(subject.os.version).to eq(Sys::Uname.uname.version) + expect(subject.cpu.name).to eq(RbConfig::CONFIG['target_cpu']) + end + + context 'with overriden ENV' do + subject { Cucumber::Runtime::MetaMessageBuilder.build_meta_message(env) } + let(:env) { {} } + + it 'detects CI environment using the given env' do + expect(Cucumber::CiEnvironment).to receive(:detect_ci_environment).with(env) + subject + end + end + + describe ':ci' do + subject { Cucumber::Runtime::MetaMessageBuilder.build_meta_message.ci } + + before do + expect(Cucumber::CiEnvironment).to receive(:detect_ci_environment).and_return(ci_data) + end + + context 'when running on a CI system' do + let(:ci_data) do + { + name: 'Jenkins', + url: 'http://localhost:8080', + buildNumber: '123' + } + end + + it { is_expected.to be_a(Cucumber::Messages::Ci) } + + it 'fills ci data in the :ci field' do + expect(subject.name).to eq(ci_data[:name]) + expect(subject.url).to eq(ci_data[:url]) + expect(subject.build_number).to eq(ci_data[:buildNumber]) + end + + describe ':git field' do + subject { Cucumber::Runtime::MetaMessageBuilder.build_meta_message.ci.git } + + context 'with some git data' do + let(:ci_data) do + { + git: { + remote: 'origin', + revision: '1234567890', + branch: 'main', + tag: 'v1.0.0' + } + } + end + + it { is_expected.to be_a(Cucumber::Messages::Git) } + + it 'fills the git data in the :git field' do + expect(subject.remote).to eq(ci_data[:git][:remote]) + expect(subject.revision).to eq(ci_data[:git][:revision]) + expect(subject.branch).to eq(ci_data[:git][:branch]) + expect(subject.tag).to eq(ci_data[:git][:tag]) + end + end + + context 'without git data' do + it { is_expected.to be_nil } + end + end + end + + context 'when not running on a CI system' do + let(:ci_data) { nil } + + it { is_expected.to be_nil } + end + end + end +end