From 0ee6465e2e73032905abe83a91f341fc580c69df Mon Sep 17 00:00:00 2001 From: Michael Hashizume Date: Tue, 23 Jan 2024 09:52:52 -0800 Subject: [PATCH 1/3] Drop Ruby 2.5 support Ruby 2.5 hit end-of-life on 2021-04-05, nearly three years ago. Additionally one of Facter's dependencies, Thor, dropped Ruby 2.5 support with Thor 1.3.0 in October 2023. This commit sets Facter's minimum Ruby version to 2.6 and updates tests and Rubocop configuration accordingly. --- .github/workflows/unit_tests.yaml | 2 +- .rubocop.yml | 5 +---- README.md | 11 ++++++++--- ext/project_data.yaml | 2 +- facter.gemspec | 8 ++++---- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/.github/workflows/unit_tests.yaml b/.github/workflows/unit_tests.yaml index e07d237ea0..257057cb91 100644 --- a/.github/workflows/unit_tests.yaml +++ b/.github/workflows/unit_tests.yaml @@ -18,7 +18,7 @@ jobs: strategy: matrix: ruby: - - '2.5' + - '2.6' - '2.7' - '3.0' - '3.2' diff --git a/.rubocop.yml b/.rubocop.yml index 20dac8c1d3..e0e7501620 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -2,7 +2,7 @@ inherit_from: .rubocop_todo.yml AllCops: - TargetRubyVersion: 2.5 + TargetRubyVersion: 2.6 Exclude: - acceptance/**/* - vendor/**/* @@ -88,9 +88,6 @@ RSpec/MessageSpies: RSpec/MultipleExpectations: Max: 3 -RSpec/MultipleMemoizedHelpers: - Enabled: false - RSpec/NestedGroups: Enabled: 6 diff --git a/README.md b/README.md index 86741e9358..ab563b7bb6 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,6 @@ [![Test Coverage](https://api.codeclimate.com/v1/badges/3bd4be86f4b0b49bc0ca/test_coverage)](https://codeclimate.com/github/puppetlabs/facter/test_coverage) [![Maintainability](https://api.codeclimate.com/v1/badges/3bd4be86f4b0b49bc0ca/maintainability)](https://codeclimate.com/github/puppetlabs/facter/maintainability) - Facter is a command-line tool that gathers basic facts about nodes (systems) such as hardware details, network settings, OS type and version, and more. These facts are made available as variables in your Puppet manifests and can be @@ -21,6 +20,7 @@ Documentation for the Facter project can be found on the [Puppet Docs site](https://puppet.com/docs/puppet/latest/facter.html). ## Supported platforms + * Linux * macOS * Windows @@ -28,10 +28,12 @@ site](https://puppet.com/docs/puppet/latest/facter.html). * AIX ## Requirements -* Ruby 2.5+ + +* Ruby 2.6+ * FFI (for facts like `mountpoints` which are resolved using C API calls) ## Basic concepts + The project has three main parts, the framework, facts and resolvers. In the framework we implement functionality that is agnostic of specific facts like parsing user input, formatting output, etc. @@ -52,9 +54,10 @@ sequenceDiagram resolver->>fact: system information fact->>framework: fact value framework->>user: formatted user output -```` +``` ## Getting started + After cloning the project, run `bundle install` to install all dependencies. You can run facter by executing `./bin/facter`. @@ -63,6 +66,7 @@ The command will output all the facts that facter detected for the current OS. The implementation can be validated locally by running `bundle exec rake check`. ## Goals - fast, easy, compatible + * Gain performance similar to the C++ version of Facter. We plan to achieve this goal by gathering multiple facts with only one call and by using the faster Win32 API rather than WMI for the Windows implementation. * Facilitate community contribution. At the moment, C++ presents a possible impediment for community contributions. * Enable native integration with other Ruby-based projects such as Bolt and puppet. @@ -70,4 +74,5 @@ The implementation can be validated locally by running `bundle exec rake check`. * Provide 100% compatibility with C++ Facter (drop-in replacement). ## Licensing + See [LICENSE](https://github.com/puppetlabs/facter/blob/main/LICENSE) file. Puppet is licensed by Puppet, Inc. under the Apache license. Puppet, Inc. can be contacted at: info@puppet.com diff --git a/ext/project_data.yaml b/ext/project_data.yaml index 6d7f99fd1d..6b1e0ea379 100644 --- a/ext/project_data.yaml +++ b/ext/project_data.yaml @@ -12,7 +12,7 @@ gem_require_path: 'lib' gem_executables: 'facter' gem_license: 'Apache-2.0' gem_default_executables: 'facter' -gem_required_ruby_version: ['>= 2.5', '< 4.0'] +gem_required_ruby_version: ['>= 2.6', '< 4.0'] gem_runtime_dependencies: hocon: ~> 1.3 thor: ['>= 1.0.1', '< 2.0'] diff --git a/facter.gemspec b/facter.gemspec index e7a079bbb5..0b2a0ca040 100644 --- a/facter.gemspec +++ b/facter.gemspec @@ -24,7 +24,7 @@ Gem::Specification.new do |spec| base = "#{__dir__}#{File::SEPARATOR}" spec.files = dirs.map { |path| path.sub(base, '') } - spec.required_ruby_version = '>= 2.5', '< 4.0' + spec.required_ruby_version = '>= 2.6', '< 4.0' spec.bindir = 'bin' spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.require_paths = ['lib'] @@ -37,9 +37,9 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'ffi', '1.15.5' spec.add_development_dependency 'rake', '~> 13.0', '>= 13.0.6' spec.add_development_dependency 'rspec', '~> 3.0' - spec.add_development_dependency 'rubocop', '~> 1.28' # last version to support 2.5 - spec.add_development_dependency 'rubocop-performance', '~> 1.5.2' - spec.add_development_dependency 'rubocop-rspec', '~> 2.10' # last version to support 2.5 + spec.add_development_dependency 'rubocop', '~> 1.50' # last version to support 2.6 + spec.add_development_dependency 'rubocop-performance', '~> 1.17' + spec.add_development_dependency 'rubocop-rspec', '~> 2.20' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'sys-filesystem', '~> 1.4' spec.add_development_dependency 'webmock', '~> 3.12' From 8b9bd6a6df8d27e038111ea9cdd978e99e43270b Mon Sep 17 00:00:00 2001 From: Michael Hashizume Date: Tue, 23 Jan 2024 09:58:24 -0800 Subject: [PATCH 2/3] Style/SlicingWithRange This commit addresses all offenses triggered by the Rubocop Style/SlicingWithRange cop. --- install.rb | 4 ++++ lib/facter/facts/solaris/ldom.rb | 2 +- lib/facter/framework/cli/cli.rb | 4 ++-- lib/facter/resolvers/aix/serialnumber.rb | 2 +- lib/facter/resolvers/freebsd/swap_memory.rb | 2 +- lib/facter/resolvers/networking.rb | 2 +- lib/facter/resolvers/partitions.rb | 4 ++-- lib/facter/util/api_debugger.rb | 4 ++-- 8 files changed, 14 insertions(+), 10 deletions(-) diff --git a/install.rb b/install.rb index 730b17e1b0..fefe441a5d 100755 --- a/install.rb +++ b/install.rb @@ -208,11 +208,15 @@ def prepare_installation # Join two paths. On Windows, dir must be converted to a relative path, # by stripping the drive letter, but only if the basedir is not empty. # + # We can't use endless ranges here because we still use older Rubies when building puppet-agent on older platforms + # (such as Solaris 10). + # rubocop:disable Style/SlicingWithRange def join(basedir, dir) return "#{basedir}#{dir[2..-1]}" if windows? && !basedir.empty? && (dir.length > 2) "#{basedir}#{dir}" end + # rubocop:enable Style/SlicingWithRange ## # Install file(s) from ./bin to RbConfig::CONFIG['bindir']. Patch it on the way diff --git a/lib/facter/facts/solaris/ldom.rb b/lib/facter/facts/solaris/ldom.rb index c24368134d..40f990a1ec 100644 --- a/lib/facter/facts/solaris/ldom.rb +++ b/lib/facter/facts/solaris/ldom.rb @@ -54,7 +54,7 @@ def resolve(key) def create_resolved_facts_list(fact_value) resolved_facts = [Facter::ResolvedFact.new(FACT_NAME, fact_value)] ALIASES.each do |fact_alias| - key = fact_alias.split('_')[1..-1].map!(&:to_sym) + key = fact_alias.split('_')[1..].map!(&:to_sym) resolved_facts << Facter::ResolvedFact.new(fact_alias, fact_value.dig(*key), :legacy) end diff --git a/lib/facter/framework/cli/cli.rb b/lib/facter/framework/cli/cli.rb index 55d9c13c19..6ef90ebe61 100755 --- a/lib/facter/framework/cli/cli.rb +++ b/lib/facter/framework/cli/cli.rb @@ -148,7 +148,7 @@ def list_block_groups options = @options.map { |(k, v)| [k.to_sym, v] }.to_h Facter::Options.init_from_cli(options) - block_groups = Facter::FactGroups.new.groups.to_yaml.lines[1..-1].join + block_groups = Facter::FactGroups.new.groups.to_yaml.lines[1..].join block_groups.gsub!(/:\s*\n/, "\n") puts block_groups @@ -160,7 +160,7 @@ def list_cache_groups options = @options.map { |(k, v)| [k.to_sym, v] }.to_h Facter::Options.init_from_cli(options) - cache_groups = Facter::FactGroups.new.groups.to_yaml.lines[1..-1].join + cache_groups = Facter::FactGroups.new.groups.to_yaml.lines[1..].join cache_groups.gsub!(/:\s*\n/, "\n") puts cache_groups diff --git a/lib/facter/resolvers/aix/serialnumber.rb b/lib/facter/resolvers/aix/serialnumber.rb index 49e23fadb8..3322917d25 100644 --- a/lib/facter/resolvers/aix/serialnumber.rb +++ b/lib/facter/resolvers/aix/serialnumber.rb @@ -22,7 +22,7 @@ def read_serialnumber(fact_name) result.each_line do |line| if line.include?('value') - @fact_list[:serialnumber] = line.split('=')[1].strip.delete('\"')[6..-1] + @fact_list[:serialnumber] = line.split('=')[1].strip.delete('\"')[6..] break end end diff --git a/lib/facter/resolvers/freebsd/swap_memory.rb b/lib/facter/resolvers/freebsd/swap_memory.rb index 299249fc10..4dbfb1a85c 100644 --- a/lib/facter/resolvers/freebsd/swap_memory.rb +++ b/lib/facter/resolvers/freebsd/swap_memory.rb @@ -15,7 +15,7 @@ def post_resolve(fact_name, _options) def read_swap_memory(fact_name) output = Facter::Core::Execution.execute('swapinfo -k', logger: log) - data = output.split("\n")[1..-1].map { |line| line.split(/\s+/) } + data = output.split("\n")[1..].map { |line| line.split(/\s+/) } unless data.empty? @fact_list[:total_bytes] = kilobytes_to_bytes(data.map { |line| line[1].to_i }.inject(:+)) diff --git a/lib/facter/resolvers/networking.rb b/lib/facter/resolvers/networking.rb index 9fbd9edc2a..26cdba246a 100644 --- a/lib/facter/resolvers/networking.rb +++ b/lib/facter/resolvers/networking.rb @@ -44,7 +44,7 @@ def clean_up_interfaces_response(response) def parse_interfaces_response(response) parsed_interfaces_data = {} - interfaces_data = Hash[*response.split(/^([A-Za-z0-9_.]+): /)[1..-1]] + interfaces_data = Hash[*response.split(/^([A-Za-z0-9_.]+): /)[1..]] interfaces_data.each do |interface_name, raw_data| parsed_interface_data = {} diff --git a/lib/facter/resolvers/partitions.rb b/lib/facter/resolvers/partitions.rb index 7faaf14656..b04861a98a 100644 --- a/lib/facter/resolvers/partitions.rb +++ b/lib/facter/resolvers/partitions.rb @@ -112,9 +112,9 @@ def available?(command, blkid_and_lsblk) def execute_and_extract_blkid_info stdout = Facter::Core::Execution.execute('blkid', logger: log) - output_hash = Hash[*stdout.split(/^([^:]+):/)[1..-1]] + output_hash = Hash[*stdout.split(/^([^:]+):/)[1..]] output_hash.each do |key, value| - output_hash[key] = Hash[*value.delete('"').chomp.rstrip.split(/ ([^= ]+)=/)[1..-1]] + output_hash[key] = Hash[*value.delete('"').chomp.rstrip.split(/ ([^= ]+)=/)[1..]] end end diff --git a/lib/facter/util/api_debugger.rb b/lib/facter/util/api_debugger.rb index 0921f6c852..db0c28a3b7 100644 --- a/lib/facter/util/api_debugger.rb +++ b/lib/facter/util/api_debugger.rb @@ -34,9 +34,9 @@ def self.parse_options(options) options.split(',').each do |option| if option.start_with?('-') - exclude << option[1..-1].to_sym + exclude << option[1..].to_sym elsif option.start_with?('+') - print_caller << option[1..-1].to_sym + print_caller << option[1..].to_sym end end From c30fd7b8b67240d7fff9e512e65697c424282e35 Mon Sep 17 00:00:00 2001 From: Michael Hashizume Date: Tue, 23 Jan 2024 11:04:55 -0800 Subject: [PATCH 3/3] Lint/ErbNewArguments In Ruby 2.6 and greater, passing trim_mode as the third argument of ERB.new is deprecated. This commit updates all instances of ERB.new to instead use trim_mode as a keyword argument. --- lib/docs/generate.rb | 7 +------ lib/facter/framework/cli/cli.rb | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/lib/docs/generate.rb b/lib/docs/generate.rb index 9ed92a0112..081e40573f 100755 --- a/lib/docs/generate.rb +++ b/lib/docs/generate.rb @@ -17,12 +17,7 @@ def format_facts(fact_hash) scope = OpenStruct.new({ facts: fact_hash }) - - erb = if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+ - ERB.new(File.read(PATH_TO_TEMPLATE), trim_mode: '-') - else - ERB.new(File.read(PATH_TO_TEMPLATE), nil, '-') - end + erb = ERB.new(File.read(PATH_TO_TEMPLATE), trim_mode: '-') erb.result(scope.instance_eval { binding }) end diff --git a/lib/facter/framework/cli/cli.rb b/lib/facter/framework/cli/cli.rb index 6ef90ebe61..2734035c7c 100755 --- a/lib/facter/framework/cli/cli.rb +++ b/lib/facter/framework/cli/cli.rb @@ -113,7 +113,7 @@ def man(*args) negate_options = %w[block cache custom_facts external_facts] template = File.join(File.dirname(__FILE__), '..', '..', 'templates', 'man.erb') - erb = ERB.new(File.read(template), nil, '-') + erb = ERB.new(File.read(template), trim_mode: '-') erb.filename = template puts erb.result(binding) end