puppet-debugger 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.gitlab-ci.yml +30 -13
  4. data/.rubocop.yml +3 -1
  5. data/.rubocop_todo.yml +11 -2
  6. data/.ruby-version +1 -1
  7. data/CHANGELOG.md +9 -0
  8. data/DEVELOPMENT.md +6 -1
  9. data/Gemfile +14 -12
  10. data/Plugin_development.md +304 -0
  11. data/README.md +4 -7
  12. data/Rakefile +6 -5
  13. data/bin/pdb +1 -0
  14. data/lib/awesome_print/ext/awesome_puppet.rb +1 -0
  15. data/lib/plugins/puppet-debugger/input_responders/benchmark.rb +40 -0
  16. data/lib/plugins/puppet-debugger/input_responders/classes.rb +15 -0
  17. data/lib/plugins/puppet-debugger/input_responders/classification.rb +14 -0
  18. data/lib/plugins/puppet-debugger/input_responders/commands.rb +95 -0
  19. data/lib/plugins/puppet-debugger/input_responders/datatypes.rb +17 -0
  20. data/lib/plugins/puppet-debugger/input_responders/environment.rb +14 -0
  21. data/lib/plugins/puppet-debugger/input_responders/exit.rb +14 -0
  22. data/lib/plugins/puppet-debugger/input_responders/facterdb_filter.rb +16 -0
  23. data/lib/plugins/puppet-debugger/input_responders/facts.rb +15 -0
  24. data/lib/plugins/puppet-debugger/input_responders/functions.rb +15 -0
  25. data/lib/plugins/puppet-debugger/input_responders/help.rb +14 -0
  26. data/lib/plugins/puppet-debugger/input_responders/krt.rb +14 -0
  27. data/lib/{puppet-debugger/support → plugins/puppet-debugger/input_responders}/play.rb +37 -26
  28. data/lib/plugins/puppet-debugger/input_responders/reset.rb +21 -0
  29. data/lib/plugins/puppet-debugger/input_responders/resources.rb +22 -0
  30. data/lib/plugins/puppet-debugger/input_responders/set.rb +55 -0
  31. data/lib/plugins/puppet-debugger/input_responders/types.rb +35 -0
  32. data/lib/plugins/puppet-debugger/input_responders/vars.rb +18 -0
  33. data/lib/plugins/puppet-debugger/input_responders/whereami.rb +29 -0
  34. data/lib/puppet-debugger.rb +12 -1
  35. data/lib/puppet-debugger/cli.rb +38 -22
  36. data/lib/puppet-debugger/code/code_file.rb +16 -15
  37. data/lib/puppet-debugger/code/code_range.rb +1 -0
  38. data/lib/puppet-debugger/code/loc.rb +1 -0
  39. data/lib/puppet-debugger/debugger_code.rb +1 -0
  40. data/lib/puppet-debugger/hooks.rb +174 -0
  41. data/lib/puppet-debugger/input_responder_plugin.rb +45 -0
  42. data/lib/puppet-debugger/plugin_test_helper.rb +44 -0
  43. data/lib/puppet-debugger/support.rb +13 -9
  44. data/lib/puppet-debugger/support/compiler.rb +1 -0
  45. data/lib/puppet-debugger/support/environment.rb +2 -0
  46. data/lib/puppet-debugger/support/errors.rb +9 -0
  47. data/lib/puppet-debugger/support/facts.rb +2 -1
  48. data/lib/puppet-debugger/support/functions.rb +3 -1
  49. data/lib/puppet-debugger/support/loader.rb +2 -0
  50. data/lib/puppet-debugger/support/node.rb +1 -0
  51. data/lib/puppet-debugger/support/scope.rb +1 -0
  52. data/lib/puppet/application/debugger.rb +1 -0
  53. data/lib/version.rb +2 -1
  54. data/puppet-debugger.gemspec +20 -15
  55. data/run_container_test.sh +1 -1
  56. data/spec/environment_spec.rb +2 -1
  57. data/spec/facts_spec.rb +1 -0
  58. data/spec/hooks_spec.rb +341 -0
  59. data/spec/input_responder_plugin_spec.rb +45 -0
  60. data/spec/input_responders/help_spec.rb +17 -0
  61. data/spec/input_responders/krt_spec.rb +12 -0
  62. data/spec/input_responders/play_spec.rb +160 -0
  63. data/spec/pdb_spec.rb +1 -0
  64. data/spec/puppet/application/debugger_spec.rb +1 -2
  65. data/spec/puppet_debugger_spec.rb +49 -88
  66. data/spec/remote_node_spec.rb +3 -2
  67. data/spec/spec_helper.rb +7 -0
  68. data/spec/support_spec.rb +5 -116
  69. data/test_matrix.rb +2 -0
  70. metadata +65 -12
  71. data/Gemfile.lock +0 -95
  72. data/lib/puppet-debugger/support/input_responders.rb +0 -191
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 44f5198a38560ebf262df1bb5d9fb27b4689f6d0
4
- data.tar.gz: 76718414d5e49a617b755e6157f29b2188ff52cf
3
+ metadata.gz: 6e41642281d06f230cba649f0ad0cca8845fc713
4
+ data.tar.gz: 5f51ef9afa5c431937be5fa750978b3bedcf1b70
5
5
  SHA512:
6
- metadata.gz: 84b776b0a55d4d9cc116d4bf5a9ef8d67ecde7a8b6ac357b9f9af5dd990c555f258de0ea87ba1c5a359733ff8ec6524eac4e60d0a66d4858e8dbb4a0299a2c1c
7
- data.tar.gz: d47bae21bef89a828e225bcb9095bb4bd1c7a40af174891ae4c17bd69eb487795deff60718ccac0aa9b1e1e7e48fa433b6ed140386e69418be2b29ce79aa00b0
6
+ metadata.gz: 991540c9bb5dbd2e8995695818f0c05ce139c2832cfccd793ad01b3c062d242fd70026b4d4b2d19773b0268d0bc6d8d6709241dbe8bf030dd0663215ec43f1bf
7
+ data.tar.gz: bd44969d0b5b2c934de7f4705ed6fa9828363d9c5e8a4a8bbcd672da351885552ab3e54d2b8197a26b56d6729fab21a97aa7eb536f4c6da0e07c73e1959ee6d5
data/.gitignore CHANGED
@@ -1,4 +1,5 @@
1
1
  # rcov generated
2
+ Gemfile.lock
2
3
  .bash_history
3
4
  .gems
4
5
  .gem
data/.gitlab-ci.yml CHANGED
@@ -31,7 +31,7 @@ rubocop_ruby:
31
31
  only:
32
32
  - branches
33
33
  tags:
34
- - ruby2.2
34
+ - ruby
35
35
  script:
36
36
  - bundle install
37
37
  - bundle exec rubocop -D
@@ -73,8 +73,13 @@ bump_and_tag:
73
73
  .ruby_23: &ruby23
74
74
  image: ruby:2.3
75
75
 
76
+ .ruby_24: &ruby24
77
+ image: ruby:2.4
78
+
76
79
  gem_production:
77
80
  image: ruby:2.1
81
+ tags:
82
+ - ruby
78
83
  before_script:
79
84
  - gem install dpl
80
85
  stage: deploy
@@ -85,72 +90,84 @@ gem_production:
85
90
 
86
91
  puppet_38_ruby193:
87
92
  variables:
88
- PUPPET_GEM_VERSION: "~> 3.8"
93
+ PUPPET_GEM_VERSION: "~> 3.8.0"
89
94
  <<: *puppet_job_def
90
95
  <<: *ruby193
91
96
 
92
97
  puppet_38_ruby20:
93
98
  variables:
94
- PUPPET_GEM_VERSION: "~> 3.8"
99
+ PUPPET_GEM_VERSION: "~> 3.8.0"
95
100
  <<: *puppet_job_def
96
101
  <<: *ruby20
97
102
 
98
103
  puppet_38_ruby21:
99
104
  variables:
100
- PUPPET_GEM_VERSION: "~> 3.8"
105
+ PUPPET_GEM_VERSION: "~> 3.8.0"
101
106
  <<: *puppet_job_def
102
107
  <<: *ruby21
103
108
 
104
109
  puppet_43_ruby20:
105
110
  variables:
106
- PUPPET_GEM_VERSION: "~> 4.3"
111
+ PUPPET_GEM_VERSION: "~> 4.3.0"
107
112
  <<: *puppet_job_def
108
113
  <<: *ruby20
109
114
 
110
115
  puppet_43_ruby21:
111
116
  variables:
112
- PUPPET_GEM_VERSION: "~> 4.3"
117
+ PUPPET_GEM_VERSION: "~> 4.3.0"
113
118
  <<: *puppet_job_def
114
119
  <<: *ruby21
115
120
 
116
121
  puppet_43_ruby22:
117
122
  variables:
118
- PUPPET_GEM_VERSION: "~> 4.3"
123
+ PUPPET_GEM_VERSION: "~> 4.3.0"
119
124
  <<: *puppet_job_def
120
125
  <<: *ruby22
121
126
 
122
127
  puppet_44_ruby21:
123
128
  variables:
124
- PUPPET_GEM_VERSION: "~> 4.4"
129
+ PUPPET_GEM_VERSION: "~> 4.4.0"
125
130
  <<: *puppet_job_def
126
131
  <<: *ruby21
127
132
 
128
133
  puppet_44_ruby22:
129
134
  variables:
130
- PUPPET_GEM_VERSION: "~> 4.4"
135
+ PUPPET_GEM_VERSION: "~> 4.4.0"
131
136
  <<: *puppet_job_def
132
137
  <<: *ruby22
133
138
 
134
139
  puppet_45_ruby21:
135
140
  variables:
136
- PUPPET_GEM_VERSION: "~> 4.5"
141
+ PUPPET_GEM_VERSION: "~> 4.5.0"
137
142
  <<: *puppet_job_def
138
143
  <<: *ruby21
139
144
 
140
145
  puppet_46_ruby22:
141
146
  variables:
142
- PUPPET_GEM_VERSION: "~> 4.6"
147
+ PUPPET_GEM_VERSION: "~> 4.6.0"
143
148
  <<: *puppet_job_def
144
149
  <<: *ruby22
145
150
 
146
151
  puppet_47_ruby22:
147
152
  variables:
148
- PUPPET_GEM_VERSION: "~> 4.7"
153
+ PUPPET_GEM_VERSION: "~> 4.7.0"
149
154
  <<: *puppet_job_def
150
155
  <<: *ruby22
151
156
 
152
157
  puppet_48_ruby22:
153
158
  variables:
154
- PUPPET_GEM_VERSION: "~> 4.8"
159
+ PUPPET_GEM_VERSION: "~> 4.8.0"
155
160
  <<: *puppet_job_def
156
161
  <<: *ruby22
162
+
163
+ puppet_49_ruby23:
164
+ variables:
165
+ PUPPET_GEM_VERSION: "~> 4.9.0"
166
+ <<: *puppet_job_def
167
+ <<: *ruby23
168
+
169
+ puppet_410_ruby24:
170
+ variables:
171
+ PUPPET_GEM_VERSION: "~> 4.10.0"
172
+ <<: *puppet_job_def
173
+ <<: *ruby24
data/.rubocop.yml CHANGED
@@ -15,6 +15,7 @@ AllCops:
15
15
  - lib/version.rb
16
16
  - lib/puppet-debugger.rb
17
17
  - bin
18
+
18
19
  # Offense count: 7
19
20
  # Configuration parameters: AllowSafeAssignment.
20
21
  Lint/AssignmentInCondition:
@@ -30,7 +31,8 @@ Lint/Debugger:
30
31
  Exclude:
31
32
  - spec/**/*.rb
32
33
 
33
-
34
+ Style/NumericPredicate:
35
+ Enabled: false
34
36
  # Offense count: 1
35
37
  # Cop supports --auto-correct.
36
38
  # Configuration parameters: AlignWith, SupportedStyles, AutoCorrect.
data/.rubocop_todo.yml CHANGED
@@ -63,10 +63,18 @@ Lint/UselessAssignment:
63
63
  Metrics/AbcSize:
64
64
  Max: 150
65
65
 
66
+ Style/IndentHeredoc:
67
+ Enabled: false
68
+
69
+ Style/FileName:
70
+ Exclude:
71
+ - Rakefile
72
+ - Gemfile
73
+ - puppet-debugger.gemspec
66
74
  # Offense count: 3
67
75
  # Configuration parameters: CountComments.
68
76
  Metrics/BlockLength:
69
- Max: 442
77
+ Max: 518
70
78
 
71
79
  # Offense count: 3
72
80
  Metrics/BlockNesting:
@@ -89,7 +97,7 @@ Metrics/MethodLength:
89
97
  # Offense count: 2
90
98
  # Configuration parameters: CountComments.
91
99
  Metrics/ModuleLength:
92
- Max: 115
100
+ Max: 168
93
101
 
94
102
  # Offense count: 10
95
103
  Metrics/PerceivedComplexity:
@@ -154,6 +162,7 @@ Style/GuardClause:
154
162
  - 'lib/puppet-debugger/support/input_responders.rb'
155
163
  - 'lib/puppet-debugger/support/play.rb'
156
164
  - 'lib/trollop.rb'
165
+ - puppet-debugger.gemspec
157
166
 
158
167
  # Offense count: 2
159
168
  Style/IdenticalConditionalBranches:
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.3.1
1
+ 2.3.3
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## Unreleased
2
+
3
+ ## 0.7.0
4
+ * Adds new commands command
5
+ * Adds new help command
6
+ * Adds plugin framework
7
+ * Adds hooks framework
8
+ * Moves all commands to plugins
9
+ * Adds pluginator gem
1
10
  ## 0.6.1
2
11
  * Adds benchmark feature
3
12
  ## 0.6.0
data/DEVELOPMENT.md CHANGED
@@ -5,4 +5,9 @@ The puppet command will then load the face so you can use with `puppet debugger`
5
5
 
6
6
  `export RUBYLIB=lib/`
7
7
 
8
- `puppet debugger`
8
+ `puppet debugger`
9
+
10
+
11
+ ## Plugin Development
12
+ * [Plugin Development Guide](Plugin_development.md)
13
+
data/Gemfile CHANGED
@@ -1,21 +1,23 @@
1
- source "http://rubygems.org"
2
- gem 'puppet', ENV['PUPPET_GEM_VERSION'] || "~> 4.9.0"
3
- gem 'facterdb', ">= 0.3.8"
4
- gem 'awesome_print', "~> 1.6"
5
-
6
- group :test do
1
+ # frozen_string_literal: true
2
+ source 'http://rubygems.org'
3
+ gem 'awesome_print', '~> 1.7'
4
+ gem 'facterdb', '~> 0.3.8'
5
+ gem 'puppet', ENV['PUPPET_GEM_VERSION'] || '~> 4.10.1'
6
+ gem 'pluginator', '~> 1.4.1'
7
+ group :test, :development do
7
8
  # ruby versions prior to 2.0 cannot install json_pure 2.0.2+
9
+ gem 'bundler'
10
+ gem 'CFPropertyList'
8
11
  gem 'json_pure', '<= 2.0.1'
9
- gem "rdoc", "~> 3.12"
10
- gem "rspec"
11
- gem "bundler"
12
- gem "simplecov", ">= 0"
12
+ gem 'pry'
13
+ gem 'puppet-debugger', path: './'
13
14
  gem 'rake'
15
+ gem 'rdoc', '~> 3.12'
14
16
  gem 'release_me'
15
- gem 'pry'
17
+ gem 'rspec', '~> 3.6'
18
+ gem 'simplecov', '>= 0'
16
19
  end
17
20
 
18
21
  group :validate do
19
22
  gem 'rubocop'
20
23
  end
21
-
@@ -0,0 +1,304 @@
1
+ <!-- START doctoc generated TOC please keep comment here to allow auto update -->
2
+ <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
3
+ **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
4
+
5
+ - [Plugin Development Guide](#plugin-development-guide)
6
+ - [Creating a new Plugin](#creating-a-new-plugin)
7
+ - [Creating a plugin as a gem](#creating-a-plugin-as-a-gem)
8
+ - [Testing your gem plugin code](#testing-your-gem-plugin-code)
9
+ - [Creating a plugin to be merged into core](#creating-a-plugin-to-be-merged-into-core)
10
+ - [New Plugin Instructions](#new-plugin-instructions)
11
+ - [Required Directory layout](#required-directory-layout)
12
+ - [Run Method](#run-method)
13
+ - [Required Constants](#required-constants)
14
+ - [Command words](#command-words)
15
+ - [Summary](#summary)
16
+ - [Command groups](#command-groups)
17
+ - [Plugin API](#plugin-api)
18
+ - [Debugger Hooks](#debugger-hooks)
19
+ - [Hook Events](#hook-events)
20
+ - [Calling other plugins](#calling-other-plugins)
21
+ - [Indirectly](#indirectly)
22
+ - [Directly](#directly)
23
+ - [Testing your plugin code](#testing-your-plugin-code)
24
+ - [Examples](#examples)
25
+
26
+ <!-- END doctoc generated TOC please keep comment here to allow auto update -->
27
+
28
+ # Plugin Development Guide
29
+ The puppet debugger now features a plugin system. This was added to support future expansion
30
+ via third party developers.
31
+
32
+ At this time there is only a single type of plugin called InputResponder, but in the future there will be additional types of plugins.
33
+
34
+ ## Creating a new Plugin
35
+ There are two ways to package a plugin.
36
+
37
+ 1. create a core plugin to be merged into the puppet-debugger codebase
38
+ 2. create a external plugin packaged as a gem and distributed via gem server such as rubygems.org
39
+
40
+ If you think your plugin should be in the core please create a PR and ensure you have unit test coverage for your plugin.
41
+
42
+ ## Creating a plugin as a gem
43
+ For reference you can use the following doc [How to create a gem](http://bundler.io/v1.15/guides/creating_gem.html)
44
+
45
+ 1. Create the gem via `bundle gem <plugin_name>`
46
+
47
+ ```
48
+ bundle gem --test=rspec fancy_plugin
49
+ cd fancy_plugin
50
+ mkdir -p lib/plugins/puppet-debugger/input_responders
51
+
52
+ ```
53
+
54
+ 2. Add the following to your Gemfile
55
+ ```ruby
56
+ group :dev, :test do
57
+ gem 'puppet-debugger'
58
+ gem 'pry'
59
+ gem 'CFPropertyList'
60
+ gem 'rake'
61
+ gem 'rspec', '>= 3.6'
62
+ # loads itself so you don't have to update RUBYLIB path
63
+ gem 'your_plugin', path: './'
64
+ end
65
+ ```
66
+
67
+ 3. bundle install
68
+ 2. Follow the [New Plugin Instructions](#new-plugin-instructions)
69
+ 3. Version the gem
70
+ 4. Package and push the gem to rubygems.
71
+ 5. Tell others about it.
72
+
73
+ ### Testing your gem plugin code
74
+ In order to test your plugin gem with the puppet-debugger you will need to add your gem's lib path to the RUBYLIB environment variable.
75
+
76
+ `RUBYLIB=~/path_to_gem/lib:$RUBYLIB puppet debugger`
77
+
78
+ Once this is set, puppet-debugger will discover your gem automatically and you should see it in the commands list.
79
+
80
+ Note: if you add the your plugin to the Gemfile as shown above in step 2 there is no need to set the RUBYLIB variable.
81
+
82
+ ## Creating a plugin to be merged into core
83
+ 1. Fork the puppet-debugger repo
84
+ 1. Follow the [New Plugin Instructions](#new-plugin-instructions)
85
+ 2. Submit a PR
86
+
87
+
88
+ ## New Plugin Instructions
89
+ 1. Create a file with the name of your plugin lib/plugins/puppet-debugger/input_responders/fancy_plugin.rb
90
+ 2. Add the following content to the plugin.
91
+
92
+ ```
93
+ require 'puppet-debugger/input_responder_plugin'
94
+ module PuppetDebugger
95
+ module InputResponders
96
+ class Fancy < InputResponderPlugin
97
+ COMMAND_WORDS = %w(fancy)
98
+ SUMMARY = 'This is a fancy plugin'
99
+ COMMAND_GROUP = :tools
100
+
101
+ def run(args = [])
102
+ 'hello from a fancy plugin'
103
+ end
104
+ end
105
+ end
106
+ end
107
+ ```
108
+
109
+ 4. ensure the class name is the same as the file name which follows ruby best practices
110
+ 5. Add words to the COMMAND_WORDS constant which will be used to run your plugin from the debugger.
111
+ 6. Add a short summary that describes your plugin's functionality
112
+ 7. Add a group to which your plugin should belong to. This appears in the `commands` plugin output.
113
+ 8. You must implement the [Run Method](#run-method). This method is called when your plugin's command word is entered.
114
+ 9. Write unit tests to validate your code works.
115
+
116
+ You can review the [Required Constants](#required-constants) docs for more info.
117
+
118
+ ## Required Directory layout
119
+ In order for you plugin to be discovered you must create this exact directly layout. Your plugin file must be in
120
+ the following directory `lib/plugins/puppet-debugger/input_responders/`
121
+
122
+ If you are packaging as a gem you must still provide this directory layout in addition to whatever other supporting files
123
+ are also in your gem.
124
+
125
+ ## Run Method
126
+
127
+ Your plugin must override the run method. When your plugin is executed, an array is passed as the args variable.
128
+ This variable contains all the arguments that can be supplied to your plugin. It is not required that you utilize
129
+ the `args` variable as some plugins run without arguments but it must be the only argument.
130
+
131
+ For example: `fancy hello there sir` would be passed as ['hello', 'there', 'sir'] to your plugin's run method.
132
+
133
+
134
+ ```ruby
135
+ def run(args = [])
136
+ greeting = args.first
137
+ "#{greeting} from a fancy plugin"
138
+ end
139
+
140
+ ```
141
+
142
+ ## Required Constants
143
+
144
+ ### Command words
145
+ These are the words the user will enter to interact with your plugin. You can provide
146
+ multiple words but only the first word will show up in the commands help screen.
147
+
148
+ Example:
149
+
150
+ ```
151
+ 2:>> classes
152
+ [
153
+ [0] "settings",
154
+ [1] "__node_regexp__foo"
155
+ ]
156
+ 2:>>
157
+ ```
158
+
159
+ Ensure you set the following in your plugin class
160
+ `COMMAND_WORDS = %w(fancy werd)`
161
+
162
+ ### Summary
163
+ Set the Summary Constant to tell users what your plugin does. This will show up in the commands help
164
+ screen.
165
+
166
+ ```bash
167
+ Tools
168
+ fancy This is a fancy plugin that does nothing
169
+ ```
170
+
171
+ `SUMMARY = 'This is a fancy plugin that does nothing'`
172
+
173
+
174
+ ### Command groups
175
+ The group name appears on the commands help screen and categories tools
176
+ based on the value of the command_group constant ie. `COMMAND_GROUP = :tools`
177
+
178
+ Below is a list of groups you can use to categorize your plugin. Groups are created dynamically by simply supplying
179
+ a new group name.
180
+
181
+ * `:help`
182
+ * `:tools`
183
+ * `:scope`
184
+ * `:node`
185
+ * `:environment`
186
+ * `:editing`
187
+ * `:context`
188
+
189
+ ## Plugin API
190
+ Every plugin has access to debugger's central objects. You may need to use these objects to implement your plugin.
191
+
192
+ Objects exposed that you might want access to:
193
+
194
+ * debugger (direct use is not recommended)
195
+ * scope (The puppet scope object)
196
+ * node (The puppet node object)
197
+ * environment (The puppet environment object)
198
+ * facts (The puppet facts hash)
199
+ * compiler (The puppet compiler object)
200
+ * catalog (The puppet catalog)
201
+ * function_map (Current map of functions)
202
+
203
+ While you do have access to the `debugger` object itself and everything inside this object. I would recommend not using the debugger
204
+ object directly since the debugger code base is changing rapidly. Usage can result in a broken plugin. If you are using
205
+ the debugger object directly please open an issue so we can create a interface for your use case to provide future compatibility.
206
+
207
+ ## Debugger Hooks
208
+ In addition the plugin API you can run code during certain events in the debugger lifecycle. This allows you to run your plugin code
209
+ only when certain actions occur. Please remember that your hook's code will be run multiple times during the debugger's session.
210
+
211
+ If your hook code takes a while to run, please ensure it runs fast or throw the code into a separate thread if applicable.
212
+
213
+ ### Hook Events
214
+ Below is a list of the current events that you can hook into.
215
+
216
+ * after_output (After the debugger has returned control back to the console)
217
+ * before_eval (Occurs before puppet evaluates the code)
218
+ * after_eval (Occurs after puppet evaluates the code and before the debugger sends the output to the console)
219
+
220
+ To hook into a debugger event you just add a hook via the `add_hook` method with the name of the event you wish to hook into.
221
+
222
+ An example of this pattern is below. In this example, when `graph` is entered by the user, the plugin toggles the execution
223
+ of creating a graph after the output is sent to the console. The toggle either adds or deletes the hook. Since creating the graph
224
+ can take a while we also create a thread so we don't hold the console hostage. A new graph is created each time a puppet evaluation occurs.
225
+
226
+ ```ruby
227
+ def run(args = [])
228
+ toggle_status
229
+ end
230
+
231
+ def toggle_status
232
+ status = !status
233
+ if status
234
+ add_hook(:after_eval, :create_graph) do |code, debugger|
235
+ # ensure we only start a single thread, otherwise they could stack up
236
+ # and try to write to the same file.
237
+ Thread.kill(@graph_thread) if @graph_thread
238
+ @graph_thread = Thread.new { create_html(create_graph_content) }
239
+ end
240
+ out = "Graph mode enabled at #{get_url}"
241
+ else
242
+ delete_hook(:after_output, :create_graph_content)
243
+ out = "Graph mode disabled"
244
+ end
245
+ out
246
+ end
247
+ ```
248
+
249
+ ## Calling other plugins
250
+ There are two ways to call other plugins.
251
+
252
+ ### Indirectly
253
+ You can call another plugin via the handle_input method ie. `debugger.handle_input('help')`. Just use the plugin command word
254
+ and any arguments that it takes to call the plugin.
255
+
256
+ This makes the debugger handle the loading of the plugin and returns formatted output which is most of the time what you want.
257
+ This does not send any output to the console so it is up to you to decide what to do next.
258
+
259
+ ### Directly
260
+ Should you want to call the plugin directly you can bypass the `handle_input` method and use the `plugin_from_command`
261
+ to return the plugin instance.
262
+
263
+ ```
264
+ # get a plugin instance
265
+ play_plugin = PuppetDebugger::InputResponders::Commands.plugin_from_command('play')
266
+
267
+ # execute the plugin
268
+ args = ['https://gists.github.com/sdalfsdfadsfds.txt']
269
+ # pass an instance of the debugger (always do this)
270
+ output = plugin.execute(args, debugger)
271
+
272
+ ```
273
+
274
+ If the command used to find the plugin is incorrect a `PuppetDebugger::Exception::InvalidCommand` error will be raised.
275
+
276
+ ## Testing your plugin code
277
+ 1. Create a new rspec test file as `spec/input_responders/plugin_name_spec.rb`
278
+
279
+ At a minimum you will need the following test code. By including the shared examples `plugin_tests' you will automatially
280
+ inherit some basic tests for your plugin. However, you will need to further test your code by creating additional
281
+ tests.
282
+
283
+ Replace `:plugin_name ` with the name of your plugin command word.
284
+
285
+ ```ruby
286
+ require 'spec_helper'
287
+ require 'puppet-debugger'
288
+ require 'puppet-debugger/plugin_test_helper'
289
+
290
+ describe :plugin_name do
291
+ include_examples "plugin_tests"
292
+ let(:args) { [] }
293
+
294
+ # you must test your run implementation similar to this, if you have args please set them in the args let blocks
295
+ it 'works' do
296
+ expect(plugin.run(args)).to eq('????')
297
+ end
298
+ end
299
+
300
+ ```
301
+
302
+ ## Examples
303
+ There are plenty of examples of plugins that are in the core code base. See lib/plugins/puppet-debugger/input_responders
304
+ for examples.