Skip to content

Commit

Permalink
Start adding dynamic plugin support (#111)
Browse files Browse the repository at this point in the history
* Start adding dynamic plugin support

* Correct extra space

* Update Gemfile

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Add and remove commands dynamically

* Plugin working

* Plugin command running

* Fix tests

* Fix plugins and update read_me

* Update version

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
aguspe and github-actions[bot] authored Jul 29, 2024
1 parent 0f21c24 commit f122881
Show file tree
Hide file tree
Showing 9 changed files with 258 additions and 17 deletions.
9 changes: 9 additions & 0 deletions lib/commands/loaded_commands.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

require 'thor'
require_relative '../plugin/plugin'

module RubyRaider
class LoadedCommands < Thor
end
end
34 changes: 34 additions & 0 deletions lib/commands/plugin_commands.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# frozen_string_literal: true

require 'thor'
require_relative '../plugin/plugin'

module RubyRaider
# :reek:FeatureEnvy { enabled: false }
# :reek:UtilityFunction { enabled: false }
class PluginCommands < Thor
desc 'add [NAME]', 'Adds a plugin to your project'

def add(plugin_name)
Plugin.add_plugin(plugin_name)
end

desc 'delete [NAME]', 'Deletes a plugin from your project'

def delete(plugin_name)
Plugin.delete_plugin(plugin_name)
end

desc 'local', 'Lists all the plugin in your project'

def local
pp Plugin.installed_plugins
end

desc 'list', 'Lists all the available plugin'

def list
pp Plugin.available_plugins
end
end
end
6 changes: 5 additions & 1 deletion lib/generators/menu_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,15 @@ def yes_no_menu_choices
end

def select_automation_framework(menu)
automation_options(menu)
menu.choice :Quit, -> { exit }
end

def automation_options(menu)
menu.choice :Selenium, -> { choose_test_framework('selenium') }
menu.choice :Appium, -> { choose_test_framework('appium') }
menu.choice :Watir, -> { choose_test_framework('watir') }
menu.choice :Applitools, -> { choose_test_framework('applitools') }
menu.choice :Axe, -> { choose_test_framework('axe') }
menu.choice :Quit, -> { exit }
end
end
19 changes: 8 additions & 11 deletions lib/generators/templates/common/read_me.tt
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@
<br />
<div align="center">
<a href="https://github.com/RubyRaider/ruby_raider">
<img src="https://rubyraiderdotcom.files.wordpress.com/2022/05/logo_transparent_background-1.png" alt="Logo">
<img src="https://ruby-raider.com/wp-content/uploads/2022/05/logo-160x160.png?w=890" alt="Logo" style="width:600px;">
</a>
<h1 align="center">Ruby Raider</h1>
<p align="center">
This is a gem to make setup and start of UI automation projects easier.
<br />
<a href="https://github.com/RubyRaider/ruby_raider#getting-started"><strong>Explore the docs »</strong></a>
<br />
<br />
Expand Down Expand Up @@ -79,13 +76,13 @@ Select the ones you will like to work with.
If you already know which frameworks you want to use, you can do:

```ruby
raider new [name_of_project] - p framework : [framework] automation : [automation_type] visual : [boolean] axe : [boolean]
raider new [name_of_project] p framework : [framework] automation : [automation_type]
```

An example of the command above would be:

```ruby
raider new test_project -p framework : rspec automation: selenium visual : false axe : true
raider new test_project p framework : rspec automation: selenium
```

Where [frameworks] is a comma separated list of the frameworks you want to use.
Expand Down Expand Up @@ -120,15 +117,15 @@ Ruby Raider also supports scaffolding:
* To create a new steps definition you do: ```raider g steps [STEPS_NAME]```
* To create both a page/spec or a page/feature/steps you do: ```raider g scaffold [SCAFFOLD_NAME]```

It's possible to add the option --path or -p if you want to specify where to create your features, pages, helpers and
It's possible to add the option --path or p if you want to specify where to create your features, pages, helpers and
specs.

If you want to set the default path for the creation of your features, helpers and specs:

```ruby
raider u path [PATH_NAME] - -feature or -f
raider u path [PATH_NAME] - -spec or -s
raider u path [PATH_NAME] - -helper or -h
raider u path [PATH_NAME] - -feature or f
raider u path [PATH_NAME] - -spec or s
raider u path [PATH_NAME] - -helper or h
```

If you don't specify an option, path will assume you want to change the default path for pages.
Expand All @@ -139,4 +136,4 @@ To initialise Appium server run this command:

```ruby
raider u start_appium
```
```
99 changes: 99 additions & 0 deletions lib/plugin/plugin.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# frozen_string_literal: true

require 'yaml'
require_relative 'plugin_exposer'

module RubyRaider
module Plugin
class << self
def add_plugin(plugin_name)
return pp 'The plugin was not found' unless available?(plugin_name)
return pp 'The plugin is already installed' if installed?(plugin_name)

pp "Adding #{plugin_name}..."
add_plugin_to_gemfile(plugin_name)
system('bundle install')
PluginExposer.expose_commands(plugin_name)
pp "The plugin #{plugin_name} is added"
end

def delete_plugin(plugin_name)
return 'The plugin is not installed' unless installed_plugins.include?(plugin_name)

pp "Deleting #{plugin_name}..."
remove_plugin_from_gemfile(plugin_name)
PluginExposer.remove_command(plugin_name)
system('bundle install')
pp "The plugin #{plugin_name} is deleted"
end

def installed_plugins
parsed_gemfile = File.readlines('Gemfile').map { |line| line.sub('gem ', '').strip.delete("'") }
parsed_gemfile.select { |line| available_plugins.include?(line) }
end

def available_plugins
plugins['plugins']
end

def installed?(plugin_name)
installed_plugins.include?(plugin_name)
end

def available?(plugin_name)
available_plugins.include?(plugin_name)
end

def camelize(str)
str.split('_').collect(&:capitalize).join
end

private

def add_plugin_to_gemfile(plugin_name)
File.open('Gemfile', 'a') do |file|
file.puts "\n# Ruby Raider Plugins\n" unless comment_present?
file.puts "gem '#{plugin_name}'" unless plugin_present?(plugin_name)
end
end

def remove_plugin_from_gemfile(plugin_name)
output_lines = remove_plugins_and_comments(plugin_name)
update_gemfile(output_lines)
end

def last_plugin?
installed_plugins.count == 1
end

def plugins
@plugins ||= YAML.load_file(File.expand_path('plugins.yml'))
end

def read_gemfile
File.readlines('Gemfile')
end

def comment_present?
read_gemfile.grep(/Ruby Raider Plugins/).any?
end

def plugin_present?(plugin_name)
read_gemfile.grep(/#{plugin_name}/).any?
end

def remove_plugins_and_comments(plugin_name)
read_gemfile.reject do |line|
line.include?(plugin_name) || line.include?('Ruby Raider Plugins') && last_plugin?
end
end

# :reek:NestedIterators { enabled: false }
def update_gemfile(output_lines)
File.open('Gemfile', 'w') do |file|
output_lines.each { |line| file.puts line }
end
end
end
end
end
77 changes: 77 additions & 0 deletions lib/plugin/plugin_exposer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# frozen_string_literal: true

require_relative '../plugin/plugin'

module RubyRaider
module PluginExposer
class << self
FILE_PATH = File.expand_path('../commands/loaded_commands.rb', __dir__)
# :reek:NestedIterators { enabled: false }
def expose_commands(plugin_name)
return pp 'The plugin is already installed' if plugin_present?(plugin_name)

commands = read_loaded_commands

File.open(FILE_PATH, 'w') do |file|
commands.each do |line|
file.puts line
file.puts require_plugin(plugin_name, line)
file.puts select_command_formatting(plugin_name, line)
end
end
end

def remove_command(plugin_name)
return pp 'The plugin is not installed' unless plugin_present?(plugin_name)

delete_plugin_command(plugin_name)
end

private

def any_commands?
read_loaded_commands.any? { |line| line.include?('subcommand') }
end

def read_loaded_commands
File.readlines(FILE_PATH)
end

def formatted_command_without_space(plugin_name)
"desc '#{plugin_name}', 'Provides access to all the commands for #{plugin_name}'\n" \
"subcommand '#{plugin_name}', #{Plugin.camelize(plugin_name)}::PluginCommands"
end

def formatted_command_with_space(plugin_name)
"\n#{formatted_command_without_space(plugin_name)}"
end

def plugin_present?(plugin_name)
read_loaded_commands.grep(/#{plugin_name}/).any?
end

def select_command_formatting(plugin_name, line)
if line.strip == 'class LoadedCommands < Thor' && !any_commands?
formatted_command_without_space(plugin_name)
elsif any_commands?
formatted_command_with_space(plugin_name)
end
end

def require_plugin(plugin_name, line)
"require '#{plugin_name}'" if line.include?("require 'thor'") && !plugin_present?(plugin_name)
end

# :reek:NestedIterators { enabled: false }
def delete_plugin_command(plugin_name)
output_lines = read_loaded_commands.reject do |line|
line.include?(plugin_name) if plugin_present?(plugin_name)
end

File.open(FILE_PATH, 'w') do |file|
output_lines.each { |line| file.puts line }
end
end
end
end
end
27 changes: 23 additions & 4 deletions lib/ruby_raider.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
# frozen_string_literal: true

require_relative '../lib/plugin/plugin'
require_relative '../lib/commands/plugin_commands'
require_relative '../lib/commands/loaded_commands'
require_relative '../lib/commands/scaffolding_commands'
require_relative '../lib/commands/utility_commands'

# :reek:FeatureEnvy { enabled: false }
# :reek:UtilityFunction { enabled: false }
module RubyRaider
class Raider < Thor
no_tasks do
def self.plugin_commands?
File.readlines(File.expand_path('commands/loaded_commands.rb', __dir__)).any? do |line|
line.include?('subcommand')
end
end

def current_version = File.read(File.expand_path('version', __dir__)).strip
end

desc 'new [PROJECT_NAME]', 'Creates a new framework based on settings picked'
option :parameters,
type: :hash, required: false, desc: 'Parameters to avoid using the menu', aliases: '-p'
type: :hash, required: false, desc: 'Parameters to avoid using the menu', aliases: 'p'

def new(project_name)
params = options[:parameters]
Expand All @@ -22,7 +35,7 @@ def new(project_name)
MenuGenerator.new(project_name).generate_choice_menu
end

map '-n' => 'new'
map 'n' => 'new'

desc 'version', 'It shows the version of Ruby Raider you are currently using'

Expand All @@ -40,8 +53,14 @@ def version
subcommand 'utility', UtilityCommands
map 'u' => 'utility'

no_commands do
def current_version = File.read(File.expand_path('version', __dir__)).strip
desc 'plugin_manager', 'Provides access to all the commands to manager your plugins'
subcommand 'plugin_manager', PluginCommands
map 'pm' => 'plugin_manager'

if plugin_commands?
desc 'plugins', 'loaded plugin commands'
subcommand 'plugins', LoadedCommands
map 'ps' => 'plugins'
end
end
end
2 changes: 1 addition & 1 deletion lib/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.9.5
0.9.8
2 changes: 2 additions & 0 deletions plugins.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
plugins:
- great_axe

0 comments on commit f122881

Please sign in to comment.