aruba-2.4.0/0000755000004100000410000000000015177113220012636 5ustar www-datawww-dataaruba-2.4.0/exe/0000755000004100000410000000000015177113220013417 5ustar www-datawww-dataaruba-2.4.0/exe/aruba0000755000004100000410000000021415177113220014434 0ustar www-datawww-data#!/usr/bin/env ruby # frozen_string_literal: true $LOAD_PATH << File.expand_path('../lib', __dir__) require 'aruba/cli' Aruba::Cli.start aruba-2.4.0/CONTRIBUTING.md0000644000004100000410000001661315177113220015076 0ustar www-datawww-data# Contributing to the Cucumber Aruba Project ## Introduction We would love to get help from you as a **user** and a **contributor**. ### As a **User** * Tell us how "Aruba" works for you * Spread the word if you like our work and please tell us if something is (utterly) wrong * Encourage people in testing their code and keep communicating their needs ### As a **Contributor** * Send us bug fixes * Add new features to the code * Discuss changes * Add missing documentation * Improve our test coverage The rest of this document is a guide for those maintaining Aruba, and others who would like to submit patches. ## Contributing to the Aruba project It would be great if all people who want to contribute to the Aruba project — contributors and maintainers — follow the guidelines in this section. There are also "Getting started" sections both for [contributors](#getting-started-as-a-contributor) and [maintainers](#getting-started-as-a-maintainer). ### Issues About to create a new GitHub Issue? We appreciate that. But before you do, please learn our basic rules: * This is not a support forum. If you have a question, please go to [The Cukes Google Group](http://groups.google.com/group/cukes). * Do you have an idea for a new feature? Then don't expect it to be implemented unless you or someone else submits a [pull request](https://help.github.com/articles/using-pull-requests). It might be better to start a discussion on [the Google Group](http://groups.google.com/group/cukes). * Reporting a bug? Follow our comments in the Issue Template, which is pre-filled when you create the new GitHub Issue. * We love [pull requests](https://help.github.com/articles/using-pull-requests). The same here: Please consider our comments within the pull request template. ### Pull Requests #### Contributors Please... * Fork the project. Make a branch for your change. * Make your feature addition or bug fix — if you're unsure if your addition will be accepted, open a GitHub Issue for discussion first * Make sure your patch is well covered by tests. We don't accept changes that aren't tested. * Do not change the `Rakefile`, gem version number in `version.rb`, or [`CHANGELOG.md`][changelog]. (If you want to have your own version, that is fine but bump version in a separate commit, so that we can ignore that commit when we merge your change.) * Make sure your pull request complies with our development style guidelines. * Rebase your branch if needed. This reduces clutter in our git history. * Make sure you don't break other people's code. On major changes: First deprecate, then bump major version, then make breaking changes, * Split up your changes into reviewable git commits which combine all lines/files relevant for a single change. * Send us a pull request. #### Maintainers * Use pull requests for larger or controversial changes made by yourself or changes you might expected to break the build. * Commit smaller changes directly to `main`, e.g. fixing typos, adding tests or adding documentation. * Update [`CHANGELOG.md`][changelog] when a pull request is merged. * Make sure all tests are green before merging a pull request. ### Development style guidelines * We try to follow the recommendations in the [Ruby Community Style Guide][] and use [`rubocop`][] to "enforce" it. Please see [.rubocop.yml][] for exceptions. * There should be `action` methods and `getter` methods in Aruba. Only the latter should return values. Please expect the first ones to return `nil`. * Add documentation — aka acceptance tests — for new features using Aruba's Cucumber steps. Place them somewhere suitable in [features/]. * Add unit tests where needed to cover edge cases which are not (directly) relevant for users. * Add [YARD] developer documentation to all relevant methods added. * Format your commit messages following these seven rules — see the ["How to Write a Git Commit Message"] blog post for a well-written explanation about the why. 1. Separate subject from body with a blank line 2. Limit the subject line to 50 characters 3. Capitalize the subject line 4. Do not end the subject line with a period 5. Use the imperative mood in the subject line 6. Wrap the body at 72 characters 7. Use the body to explain what and why vs. how (optional if subject is self-explanatory) ## Getting started as a contributor ### Requirements To get started with Aruba, you only need [Bundler]. Install Aruba's dependencies: ```bash bundle install ``` ### Running tests Run the following command to run the test suite. ```bash # Run the whole test suite bundle exec rake # Run RSpec tests bundle exec rake spec # Run Cucumber features bundle exec rake cucumber # Run Cucumber features which are "WORK IN PROGRESS" and are allowed to fail bundle exec rake cucumber:wip ``` If you have problems because our assumptions about your local setup are wrong, perhaps you can use this Docker workflow. This requires [Docker] to be installed on your local system. ```bash # Build the docker container docker build -t test-aruba . # Open a bash shell inside the container with attached volume so changes to the # code will be picked up automatically. docker run -v $PWD:/aruba --rm -it test-aruba:latest bash # Run the test suite bundle exec rake ``` If you want to run the test suite against specific versions of Aruba's dependencies, you can use [appraisal](https://github.com/thoughtbot/appraisal): ```bash bundle exec appraisal cucumber_6 bundle install bundle exec appraisal cucumber_6 bundle exec rake ``` ### Installing your own gems used for development A `Gemfile.local` file can be used, to have your own gems installed to support your normal development workflow. Example `Gemfile.local`: ```ruby gem 'byebug' ``` ### Running a developer console The interactive Aruba console starts an IRB console with Aruba's API loaded: ```bash bin/console ``` ### Linting Aruba's Rakefile provides the following linting tasks ```bash bundle exec rake lint # Run all linters bundle exec rake lint:coding_guidelines # Lint our code with "rubocop" bundle exec rake lint:licenses # Check for relevant licenses in project ``` ### Building and installing your local Aruba version You can use the following Rake tasks to build and install your work-in-progress locally: ```bash # Build your copy bundle exec rake build # Build and install your copy bundle exec rake install # Build and install your copy without network access bundle exec rake install:local ``` ## Release Process * Bump the version number in `lib/aruba/version.rb` * Make sure [`CHANGELOG.md`][changelog] is updated with the upcoming version number, and has entries for all fixes. * Make sure [`README.md`][readme] is up-to-date. * No need to add a [`CHANGELOG.md`][changelog] header at this point - this should be done later, when a new change is made. See [the general Cucumber project release process](https://github.com/cucumber/.github/blob/main/RELEASING.md). [changelog]: CHANGELOG.md [readme]: README.md [`rubocop`]: https://github.com/bbatsov/rubocop [Ruby Community Style Guide]: https://github.com/bbatsov/ruby-style-guide [.rubocop.yml]: .rubocop.yml [features/]: features/ [Bundler]: https://bundler.io/ [Docker]: https://docs.docker.com/ [YARD]: http://yardoc.org/ ["How to Write a Git Commit Message"]: http://chris.beams.io/posts/git-commit/ [cucumber/website]: https://github.com/cucumber/website aruba-2.4.0/lib/0000755000004100000410000000000015177113220013404 5ustar www-datawww-dataaruba-2.4.0/lib/aruba.rb0000644000004100000410000000006315177113220015022 0ustar www-datawww-data# frozen_string_literal: true require 'aruba/api' aruba-2.4.0/lib/aruba/0000755000004100000410000000000015177113220014476 5ustar www-datawww-dataaruba-2.4.0/lib/aruba/generators/0000755000004100000410000000000015177113220016647 5ustar www-datawww-dataaruba-2.4.0/lib/aruba/generators/script_file.rb0000644000004100000410000000176315177113220021506 0ustar www-datawww-data# frozen_string_literal: true # Aruba module Aruba # Generate script files on command line class ScriptFile private attr_reader :path, :content, :interpreter public def initialize(opts = {}) @path = opts[:path] @content = opts[:content] @interpreter = opts[:interpreter] end def call Aruba.platform.write_file(path, "#{header}#{content}") Aruba.platform.chmod(0o755, path, {}) end private def header if script_starts_with_shebang? '' elsif interpreter_is_absolute_path? format("#!%s\n", interpreter) elsif interpreter_is_just_the_name_of_shell? format("#!/usr/bin/env %s\n", interpreter) end end def interpreter_is_absolute_path? Aruba.platform.absolute_path? interpreter end def interpreter_is_just_the_name_of_shell? interpreter =~ /^[-_a-zA-Z.]+$/ end def script_starts_with_shebang? content.start_with? '#!' end end end aruba-2.4.0/lib/aruba/platform.rb0000644000004100000410000000056115177113220016651 0ustar www-datawww-data# frozen_string_literal: true require 'aruba/platforms/unix_platform' require 'aruba/platforms/windows_platform' # Aruba module Aruba PLATFORM_MUTEX = Mutex.new PLATFORM = [Platforms::WindowsPlatform, Platforms::UnixPlatform].find(&:match?) PLATFORM_MUTEX.synchronize do @platform = PLATFORM.new end class << self attr_reader :platform end end aruba-2.4.0/lib/aruba/basic_configuration.rb0000644000004100000410000001116615177113220021040 0ustar www-datawww-data# frozen_string_literal: true require 'contracts' require 'aruba/basic_configuration/option' require 'aruba/in_config_wrapper' # Aruba module Aruba # Basic configuration for Aruba # # @private class BasicConfiguration include Contracts class << self def known_options @known_options ||= {} end # Define an option reader # # @param [Symbol] name # The name of the reader # # @option [Class, Module] type # The type contract for the option # # @option [Object] default # The default value def option_reader(name, type:, default: nil) raise ArgumentError, 'Either use block or default value' if block_given? && default add_option(name, block_given? ? yield(InConfigWrapper.new(known_options)) : default) Contract None => type define_method(name) { find_option(name).value } end # Define an option reader and writer # # @param [Symbol] name # The name of the reader # # @option [Class, Module] type # The type contract for the option # # @option [Object] default # The default value # def option_accessor(name, type:, default: nil) raise ArgumentError, 'Either use block or default value' if block_given? && default # Add writer add_option(name, block_given? ? yield(InConfigWrapper.new(known_options)) : default) Contract type => type define_method(:"#{name}=") { |v| find_option(name).value = v } # Add reader option_reader name, type: type end private def add_option(name, value = nil) return if known_options.key?(name) known_options[name] = Option.new(name: name, value: value) self end end protected attr_accessor :local_options attr_writer :hooks public # Create configuration def initialize initialize_configuration end # @yield [Configuration] # # Yields self def configure yield self if block_given? end # Reset configuration def reset initialize_configuration end # Make deep dup copy of configuration def make_copy obj = dup obj.local_options = Marshal.load(Marshal.dump(local_options)) obj.hooks = @hooks obj end # Define before-hook # # @param [Symbol, String] name # The name of the hook # # @yield # The code block which should be run. This is a configure time only option def before(name, &block) name = format('%s_%s', 'before_', name.to_s).to_sym raise ArgumentError, 'A block is required' unless block @hooks.append(name, block) self end # Run before-hook # # @param [Symbol, String] name # The name of the hook # # @param [Proc] context # The context a hook should run in # # @param [Array] args # Arguments for the run of hook def run_before_hook(name, context, *args) name = format('%s_%s', 'before_', name.to_s).to_sym @hooks.execute(name, context, *args) end # Define after-hook # # @param [Symbol, String] name # The name of the hook # # @yield # The code block which should be run. This is a configure time only option def after(name, &block) name = format('%s_%s', 'after_', name.to_s).to_sym raise ArgumentError, 'A block is required' unless block @hooks.append(name, block) self end # Run after-hook # # @param [Symbol, String] name # The name of the hook # # @param [Proc] context # The context a hook should run in # # @param [Array] args # Arguments for the run of hook def run_after_hook(name, context, *args) name = format('%s_%s', 'after_', name.to_s).to_sym @hooks.execute(name, context, *args) end # Check if is option # # @param [String, Symbol] name # The name of the option def option?(name) local_options.any? { |_, v| v.name == name.to_sym } end def ==(other) local_options.values.map(&:value) == other.local_options.values.map(&:value) end # Set if name is option def set_if_option(name, *args) public_send(:"#{name}=", *args) if option? name end private def initialize_configuration @local_options = Marshal.load(Marshal.dump(self.class.known_options)) @hooks = Hooks.new end def find_option(name) raise NotImplementedError, %(Unknown option "#{name}") unless option? name local_options[name] end end end aruba-2.4.0/lib/aruba/aruba_path.rb0000644000004100000410000000241015177113220017126 0ustar www-datawww-data# frozen_string_literal: true require 'pathname' # Aruba module Aruba # Pathname for aruba files and directories # # @private class ArubaPath def initialize(path) @obj = [path.to_s].flatten end def to_str to_pathname.to_s end def to_s to_str end # Add directory/file to path # # @param [String] p # The path to be added # # @example # path = ArubaPath.new 'path/to/dir.d' # path << 'subdir.d # # or path.push 'subdir.d # puts path # # => path/to/dir.d/subdir.d def push(p) @obj << p end alias << push # Remove last pushed component of path # # @example # path = ArubaPath.new 'path/to' # path.push 'dir' # path.pop # puts path # => path/to def pop @obj.pop end # Return string at index # # @param [Integer, Range] index def [](index) to_s[index] end private # Get path def to_pathname current_path = @obj.inject do |path, element| if element.start_with?('~') || Aruba.platform.absolute_path?(element) element else File.join(path, element) end end ::Pathname.new(current_path) end end end aruba-2.4.0/lib/aruba/configuration.rb0000644000004100000410000000642315177113220017677 0ustar www-datawww-data# frozen_string_literal: true require 'contracts' require 'aruba/version' require 'aruba/basic_configuration' require 'aruba/in_config_wrapper' require 'aruba/hooks' require 'aruba/contracts/relative_path' require 'aruba/contracts/absolute_path' require 'aruba/contracts/enum' require 'aruba/contracts/is_power_of_two' # Aruba module Aruba # Aruba Configuration # # This defines the configuration options of aruba class Configuration < BasicConfiguration option_reader :root_directory, type: String, default: Dir.getwd option_accessor :working_directory, type: Aruba::Contracts::RelativePath, default: 'tmp/aruba' option_reader :fixtures_path_prefix, type: String, default: '%' option_accessor :exit_timeout, type: Num, default: 15 option_accessor :stop_signal, type: Maybe[String], default: nil option_accessor :io_wait_timeout, type: Num, default: 0.1 option_accessor :startup_wait_time, type: Num, default: 0 option_accessor :fixtures_directories, type: ArrayOf[String], default: %w[features/fixtures spec/fixtures test/fixtures fixtures] option_accessor :command_runtime_environment, type: Hash, default: {} option_accessor :command_search_paths, type: ArrayOf[String] do |config| [File.join(config.root_directory.value, 'bin'), File.join(config.root_directory.value, 'exe')] end option_accessor :remove_ansi_escape_sequences, type: Bool, default: true option_accessor :command_launcher, type: Aruba::Contracts::Enum[:in_process, :spawn, :debug], default: :spawn option_accessor :main_class, type: Maybe[Class], default: nil option_accessor :home_directory, type: Or[Aruba::Contracts::AbsolutePath, Aruba::Contracts::RelativePath] do |config| File.join(config.root_directory.value, config.working_directory.value) end option_accessor :log_level, type: Aruba::Contracts::Enum[:fatal, :warn, :debug, :info, :error, :unknown, :silent], default: :info # TODO: deprecate this value and replace with "filesystem allocation unit" # equal to 4096 by default. "filesystem allocation unit" would represent # the actual MINIMUM space taken in bytes by a 1-byte file option_accessor :physical_block_size, type: Aruba::Contracts::IsPowerOfTwo, default: 512 option_accessor :console_history_file, type: String, default: '~/.aruba_history' option_accessor :activate_announcer_on_command_failure, type: ArrayOf[Symbol], default: [] option_accessor :allow_absolute_paths, type: Bool, default: false end end # Aruba module Aruba @config = Configuration.new class << self attr_reader :config # Configure aruba # # @example How to configure aruba # # Aruba.configure do |config| # config.