You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

profile_loader.rb 4.1 kB

2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. # frozen_string_literal: true
  2. require 'yaml'
  3. module Cucumber
  4. module Cli
  5. class ProfileLoader
  6. def initialize
  7. @cucumber_yml = nil
  8. end
  9. def args_from(profile)
  10. unless cucumber_yml.key?(profile)
  11. raise(ProfileNotFound, <<-END_OF_ERROR)
  12. Could not find profile: '#{profile}'
  13. Defined profiles in cucumber.yml:
  14. * #{cucumber_yml.keys.sort.join("\n * ")}
  15. END_OF_ERROR
  16. end
  17. args_from_yml = cucumber_yml[profile] || ''
  18. case args_from_yml
  19. when String
  20. if args_from_yml =~ /^\s*$/
  21. raise YmlLoadError, "The '#{profile}' profile in cucumber.yml was blank." \
  22. " Please define the command line arguments for the '#{profile}' profile in cucumber.yml.\n"
  23. end
  24. args_from_yml = processed_shellwords(args_from_yml)
  25. when Array
  26. raise YmlLoadError, "The '#{profile}' profile in cucumber.yml was empty. Please define the command line arguments for the '#{profile}' profile in cucumber.yml.\n" if args_from_yml.empty?
  27. else
  28. raise YmlLoadError, "The '#{profile}' profile in cucumber.yml was a #{args_from_yml.class}. It must be a String or Array"
  29. end
  30. args_from_yml
  31. end
  32. def profile?(profile)
  33. cucumber_yml.key?(profile)
  34. end
  35. def cucumber_yml_defined?
  36. cucumber_file && File.exist?(cucumber_file)
  37. end
  38. private
  39. # Loads the profile, processing it through ERB and YAML, and returns it as a hash.
  40. def cucumber_yml
  41. return @cucumber_yml if @cucumber_yml
  42. ensure_configuration_file_exists
  43. process_configuration_file_with_erb
  44. load_configuration
  45. if @cucumber_yml.nil? || !@cucumber_yml.is_a?(Hash)
  46. raise(YmlLoadError, 'cucumber.yml was found, but was blank or malformed. ' \
  47. "Please refer to cucumber's documentation on correct profile usage.\n")
  48. end
  49. @cucumber_yml
  50. end
  51. def ensure_configuration_file_exists
  52. return if cucumber_yml_defined?
  53. raise(ProfilesNotDefinedError, "cucumber.yml was not found. Current directory is #{Dir.pwd}." \
  54. "Please refer to cucumber's documentation on defining profiles in cucumber.yml. You must define" \
  55. "a 'default' profile to use the cucumber command without any arguments.\nType 'cucumber --help' for usage.\n")
  56. end
  57. def process_configuration_file_with_erb
  58. require 'erb'
  59. begin
  60. @cucumber_erb = ERB.new(IO.read(cucumber_file), trim_mode: '%').result(binding)
  61. rescue StandardError
  62. raise(YmlLoadError, "cucumber.yml was found, but could not be parsed with ERB. Please refer to cucumber's documentation on correct profile usage.\n#{$ERROR_INFO.inspect}")
  63. end
  64. end
  65. def load_configuration
  66. require 'yaml'
  67. begin
  68. @cucumber_yml = YAML.load(@cucumber_erb) # rubocop:disable Security/YAMLLoad
  69. rescue StandardError
  70. raise(YmlLoadError, "cucumber.yml was found, but could not be parsed. Please refer to cucumber's documentation on correct profile usage.\n")
  71. end
  72. end
  73. # Locates cucumber.yml file. The file can end in .yml or .yaml,
  74. # and be located in the current directory (eg. project root) or
  75. # in a .config/ or config/ subdirectory of the current directory.
  76. def cucumber_file
  77. @cucumber_file ||= Dir.glob('{,.config/,config/}cucumber{.yml,.yaml}').first
  78. end
  79. def processed_shellwords(args_from_yml)
  80. require 'shellwords'
  81. return Shellwords.shellwords(args_from_yml) unless Cucumber::WINDOWS
  82. # Shellwords treats backslash as an escape character so we have to mask it out temporarily
  83. placeholder = 'pseudo_unique_backslash_placeholder'
  84. sanitized_line = args_from_yml.gsub('\\', placeholder)
  85. Shellwords.shellwords(sanitized_line).collect { |argument| argument.gsub(placeholder, '\\') }
  86. end
  87. end
  88. end
  89. end

No Description

Contributors (1)