diff --git a/.github/workflows/unit_tests.yaml b/.github/workflows/unit_tests.yaml index 257057cb91..e07d237ea0 100644 --- a/.github/workflows/unit_tests.yaml +++ b/.github/workflows/unit_tests.yaml @@ -18,7 +18,7 @@ jobs: strategy: matrix: ruby: - - '2.6' + - '2.5' - '2.7' - '3.0' - '3.2' diff --git a/.rubocop.yml b/.rubocop.yml index e0e7501620..20dac8c1d3 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -2,7 +2,7 @@ inherit_from: .rubocop_todo.yml AllCops: - TargetRubyVersion: 2.6 + TargetRubyVersion: 2.5 Exclude: - acceptance/**/* - vendor/**/* @@ -88,6 +88,9 @@ RSpec/MessageSpies: RSpec/MultipleExpectations: Max: 3 +RSpec/MultipleMemoizedHelpers: + Enabled: false + RSpec/NestedGroups: Enabled: 6 diff --git a/README.md b/README.md index ab563b7bb6..86741e9358 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ [![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 @@ -20,7 +21,6 @@ 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,12 +28,10 @@ site](https://puppet.com/docs/puppet/latest/facter.html). * AIX ## Requirements - -* Ruby 2.6+ +* Ruby 2.5+ * 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. @@ -54,10 +52,9 @@ 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`. @@ -66,7 +63,6 @@ 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. @@ -74,5 +70,4 @@ 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 6b1e0ea379..bbd94f2875 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.6', '< 4.0'] +gem_required_ruby_version: ['>= 2.5', '< 4.0'] gem_runtime_dependencies: hocon: ~> 1.3 - thor: ['>= 1.0.1', '< 2.0'] + thor: ['>= 1.0.1', '< 1.3'] diff --git a/facter.gemspec b/facter.gemspec index fa01f038ab..458f91b8b4 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.6', '< 4.0' + spec.required_ruby_version = '>= 2.5', '< 4.0' spec.bindir = 'bin' spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.require_paths = ['lib'] @@ -37,14 +37,14 @@ 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.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 '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 'simplecov', '~> 0.17.1' spec.add_development_dependency 'sys-filesystem', '~> 1.4' spec.add_development_dependency 'webmock', '~> 3.12' spec.add_development_dependency 'yard', '~> 0.9' spec.add_runtime_dependency 'hocon', '~> 1.3' - spec.add_runtime_dependency 'thor', ['>= 1.0.1', '< 2.0'] + spec.add_runtime_dependency 'thor', ['>= 1.0.1', '< 1.3'] # Thor 1.3.0 drops support for Ruby 2.5 end diff --git a/install.rb b/install.rb index fefe441a5d..730b17e1b0 100755 --- a/install.rb +++ b/install.rb @@ -208,15 +208,11 @@ 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/docs/generate.rb b/lib/docs/generate.rb index 081e40573f..9ed92a0112 100755 --- a/lib/docs/generate.rb +++ b/lib/docs/generate.rb @@ -17,7 +17,12 @@ def format_facts(fact_hash) scope = OpenStruct.new({ facts: fact_hash }) - erb = ERB.new(File.read(PATH_TO_TEMPLATE), trim_mode: '-') + + 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.result(scope.instance_eval { binding }) end diff --git a/lib/facter/facts/solaris/ldom.rb b/lib/facter/facts/solaris/ldom.rb index 40f990a1ec..c24368134d 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..].map!(&:to_sym) + key = fact_alias.split('_')[1..-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 2734035c7c..55d9c13c19 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), trim_mode: '-') + erb = ERB.new(File.read(template), nil, '-') erb.filename = template puts erb.result(binding) end @@ -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..].join + block_groups = Facter::FactGroups.new.groups.to_yaml.lines[1..-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..].join + cache_groups = Facter::FactGroups.new.groups.to_yaml.lines[1..-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 3322917d25..49e23fadb8 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..] + @fact_list[:serialnumber] = line.split('=')[1].strip.delete('\"')[6..-1] break end end diff --git a/lib/facter/resolvers/freebsd/swap_memory.rb b/lib/facter/resolvers/freebsd/swap_memory.rb index 4dbfb1a85c..299249fc10 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..].map { |line| line.split(/\s+/) } + data = output.split("\n")[1..-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 26cdba246a..9fbd9edc2a 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..]] + interfaces_data = Hash[*response.split(/^([A-Za-z0-9_.]+): /)[1..-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 b04861a98a..7faaf14656 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..]] + output_hash = Hash[*stdout.split(/^([^:]+):/)[1..-1]] output_hash.each do |key, value| - output_hash[key] = Hash[*value.delete('"').chomp.rstrip.split(/ ([^= ]+)=/)[1..]] + output_hash[key] = Hash[*value.delete('"').chomp.rstrip.split(/ ([^= ]+)=/)[1..-1]] end end diff --git a/lib/facter/util/api_debugger.rb b/lib/facter/util/api_debugger.rb index db0c28a3b7..0921f6c852 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..].to_sym + exclude << option[1..-1].to_sym elsif option.start_with?('+') - print_caller << option[1..].to_sym + print_caller << option[1..-1].to_sym end end