runbook 0.12.1 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 15bd413c481c171d9ee7fca96b11c2b33c2d253c3f454e1b16daaf3e5d37fb31
4
- data.tar.gz: b9400fe8bca1d7080e529093880331324bf8e353743a0242c959b9e945abb45d
3
+ metadata.gz: 5fe4b7ea15d7d74edf1a660fda55c9f8360a16f7e5032acadc427039240b9cf6
4
+ data.tar.gz: c72e2c91cd75587c87ed4b9e5921e1be050ea6466c59e1d903fefcf7f6770bfd
5
5
  SHA512:
6
- metadata.gz: 967f09b95b45ad9e220c7ddea7b6136f646446ceaef9219fc89f14be0a147d300560d5fa4a6223f37f2b66b10e9af76ffb574262b56587abb7b16ad546424cdd
7
- data.tar.gz: 6a204eda9e04545162d8c83ca23e6545c53df364aa5a6886aec0f0002dd920f27c0ccf4ca570e898faa9e6d1c72760ac48a915fb8cbda574e631b99184f67945
6
+ metadata.gz: 129f995881810339793273c74d00a872b62cd865f8712fe7db063356c95bdae7f090537d244383b00fbf81cf2de8555e59627248b9e4a6284320aa9594508ef1
7
+ data.tar.gz: b1c2ef5526b2225d02a246c2d4f5d8e657c599ab04faf96f192084ea4f11d61863f455abc91136a17174dd7645f1112231fa7614ed83862d4444debbc0d2ca07
data/CHANGELOG.md CHANGED
@@ -4,6 +4,21 @@ This log maintains a list of all substantive changes to Runbook. The log include
4
4
 
5
5
  ## master
6
6
 
7
+ ## `v0.13.0` (2019-07-10)
8
+
9
+ ### Potentially Breaking Changes:
10
+
11
+ * Uses of Runbook that expect the CLI to return a zero exit code may exhibit different behavior if their runbook encounters an error.
12
+
13
+ ### Fixes:
14
+
15
+ * Return non-zero exit code on CLI error
16
+
17
+ ### New Features
18
+
19
+ * Add runbook "generate" command, including generator, runbook, statement, dsl_extension, and project generators
20
+ * Add "install" CLI command
21
+
7
22
  ## `v0.12.1` (2019-06-12)
8
23
 
9
24
  ### Fixes:
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Runbook
2
2
 
3
- > Runbook is a framework for progressively automating system operations.
3
+ [![Gem Version](https://badge.fury.io/rb/runbook.svg)](https://badge.fury.io/rb/runbook)
4
4
 
5
5
  Runbook provides a DSL for specifying a series of steps to execute an operation. Once your runbook is specified, you can use it to generate a formatted representation of the book or to execute the runbook interactively. For example, you can export your runbook to markdown or use the same runbook to execute commands on remote servers.
6
6
 
@@ -9,14 +9,14 @@ Runbook provides a DSL for specifying a series of steps to execute an operation.
9
9
  </div>
10
10
  <br>
11
11
 
12
- Runbook provides two modes for evaluating your runbook. The first mode, view mode, allows you to export your runbook into various formats such as markdown. The second mode, run mode, allows you to execute behavior based on the statements in your runbook.
12
+ Runbook has two modes for evaluating your runbook. The first mode, view mode, allows you to export your runbook into various formats such as markdown. The second mode, run mode, allows you to execute behavior based on the statements in your runbook.
13
13
 
14
14
  <div align="center">
15
15
  <img width="600" src="images/runbook_execution_modes.png" alt="diagram of execution modes" />
16
16
  </div>
17
17
  <br>
18
18
 
19
- Runbook provides a very flexible interface. It can be integrated into your existing projects to add orchestration functionality, installed on systems as a stand-alone executable, or runbooks can be defined as self-executable scripts. In addition to being useful for automating common tasks, runbooks are a perfect bridge for providing operations teams with step-by-step instructions to handle common issues (especially when solutions cannot be easily automated).
19
+ Runbook can be integrated into existing infrastructure in many different ways. It can be integrated into existing projects to add orchestration functionality, installed on systems as a stand-alone executable, or runbooks can be defined as self-executable scripts. In addition to being useful for automating common tasks, runbooks are a perfect bridge for providing operations teams with step-by-step instructions to handle common issues (especially when solutions cannot be easily automated).
20
20
 
21
21
  Lastly, Runbook provides an extendable interface for augmenting the DSL and defining your own behavior.
22
22
 
@@ -28,15 +28,18 @@ Lastly, Runbook provides an extendable interface for augmenting the DSL and defi
28
28
  * **Noop and Auto Modes** - Runbooks can be executed in noop mode. This allows you to see what a runbook will do before it executes. Runbooks can be run in auto mode to eliminate the need for human interaction.
29
29
  * **Execution Lifecycle Hooks** - Runbook provides before, after, around hooks to augment its execution behavior.
30
30
  * **Tmux Integration** - Runbook integrates with [tmux](https://github.com/tmux/tmux). You can define terminal pane layouts and send commands to terminal panes.
31
+ * **Generators** - Runbook provides commands to generate runbooks, extensions, and runbook projects. You can define your own generators for easy, customized runbook creation.
31
32
  * **Extendable DSL** - Runbook's DSL is designed to be extendable. You can extend its DSL to add your own behavior.
32
33
 
33
34
  ## Use Cases
34
35
 
35
- Runbook is a very flexible tool. Though it can solve a myriad of problems, Runbook is best used for removing the need for repeated, rote developer operations. Runbook allows developers to execute processes at a higher level than that of individual command-line commands. Additionally, Runbook provides features to simply and safely execute operations in mission-critical environments.
36
+ Though Runbook can solve a myriad of problems, it is best used for removing the need for repeated, rote developer operations. Runbook allows developers to execute processes at a higher level than that of individual command-line commands. Additionally, Runbook provides features to simply and safely execute operations in mission-critical environments.
36
37
 
37
38
  Runbook is not intended to replace more special-purpose automation solutions such as configuration management solutions (Puppet, Chef, Ansible, Salt), deployment solutions (Capistrano, Kubernetes, Docker Swarm), monitoring solutions (Nagios, Datadog), or local command execution (shell scripts, Rake tasks, Make). Instead Runbook is best used as a glue when needing to accomplish a task that cuts across these domains.
38
39
 
39
- ## Installation
40
+ ## Quick Start
41
+
42
+ ### Installation
40
43
 
41
44
  Add this line to your application's Gemfile:
42
45
 
@@ -52,6 +55,62 @@ Or install it yourself as:
52
55
 
53
56
  $ gem install runbook
54
57
 
58
+ ### Your First Runbook
59
+
60
+ Generate a runbook using the Runbook Generator:
61
+
62
+ $ runbook generate runbook my_first_runbook
63
+
64
+ Execute the runbook:
65
+
66
+ $ runbook exec my_first_runbook.rb
67
+
68
+ ## Slightly Longer Start
69
+
70
+ When setting up Runbook, you can install it at a system level, create a dedicated runbook project, or incorporate Runbook into an existing project.
71
+
72
+ ### System Level Setup
73
+
74
+ Install runbook at a system level using `gem`:
75
+
76
+ $ gem install runbook
77
+
78
+ Set any Runbook [configuration](#configuration) in `/etc/runbook.conf`.
79
+
80
+ Generate runbook files using `runbook generate runbook`. Execute `runbook generate help runbook` for more details.
81
+
82
+ Installing Runbook at a system level can be useful for executing runbooks on remote hosts or within docker containers. One disadvantage of installing Runbook at a system level is that there is no built-in solution for dependency management.
83
+
84
+ ### New Project Setup
85
+
86
+ Install runbook using `gem`:
87
+
88
+ $ gem install runbook
89
+
90
+ Generate a new runbook project:
91
+
92
+ $ runbook generate project <PROJECT_NAME>
93
+
94
+ This will generate a new runbook project. Cd into your project directory and initialize its dependencies:
95
+
96
+ $ cd <PROJECT_NAME> && bin/setup
97
+
98
+ ### Existing Project Setup
99
+
100
+ Add this line to your project's Gemfile:
101
+
102
+ ```ruby
103
+ gem 'runbook'
104
+ ```
105
+
106
+ Install the Runbook gem:
107
+
108
+ $ bundle install
109
+
110
+ Install Runbook into your project:
111
+
112
+ $ bundle exec runbook install
113
+
55
114
  ## Contents
56
115
 
57
116
  * [1. Runbook Anatomy](#runbook-anatomy)
@@ -92,21 +151,24 @@ Or install it yourself as:
92
151
  * [4.5 Deep Nesting](#deep-nesting)
93
152
  * [4.6 Load Vs. Eval](#load-vs-eval)
94
153
  * [4.7 Passing State](#passing-state)
95
- * [5. Extending Runbook](#extending-runbook)
96
- * [5.1 Adding Runs and Views](#adding-runs-and-views)
97
- * [5.2 DSL Extensions](#dsl-extensions)
98
- * [5.3 Adding New Statements](#adding-new-statements)
99
- * [5.4 Adding Run and View Functionality](#adding-run-and-view-functionality)
100
- * [5.5 Augmenting Functionality With Hooks](#augmenting-functionality-with-hooks)
101
- * [5.6 Adding New Run Behaviors](#adding-new-run-behaviors)
102
- * [5.7 Adding to Runbook's Run Metadata](#adding-to-runbooks-run-metadata)
103
- * [5.8 Adding to Runbook's Configuration](#adding-to-runbooks-configuration)
104
- * [6. Known Issues](#known-issues)
105
- * [7. Development](#development)
106
- * [8. Contributing](#contributing)
107
- * [9. Feature Requests](#feature-requests)
108
- * [10. License](#license)
109
- * [11. Code of Conduct](#code-of-conduct)
154
+ * [5. Generators](#generators)
155
+ * [5.1 Predefined Generators](#predefined-generators)
156
+ * [5.2 Custom Generators](#custom-generators)
157
+ * [6. Extending Runbook](#extending-runbook)
158
+ * [6.1 Adding Runs and Views](#adding-runs-and-views)
159
+ * [6.2 DSL Extensions](#dsl-extensions)
160
+ * [6.3 Adding New Statements](#adding-new-statements)
161
+ * [6.4 Adding Run and View Functionality](#adding-run-and-view-functionality)
162
+ * [6.5 Augmenting Functionality With Hooks](#augmenting-functionality-with-hooks)
163
+ * [6.6 Adding New Run Behaviors](#adding-new-run-behaviors)
164
+ * [6.7 Adding to Runbook's Run Metadata](#adding-to-runbooks-run-metadata)
165
+ * [6.8 Adding to Runbook's Configuration](#adding-to-runbooks-configuration)
166
+ * [7. Known Issues](#known-issues)
167
+ * [8. Development](#development)
168
+ * [9. Contributing](#contributing)
169
+ * [10. Feature Requests](#feature-requests)
170
+ * [11. License](#license)
171
+ * [12. Code of Conduct](#code-of-conduct)
110
172
 
111
173
  ## Runbook Anatomy
112
174
 
@@ -496,7 +558,7 @@ If the `ssh_kit` configuration looks familiar, that's because it's an SSHKit Con
496
558
 
497
559
  ### Configuration Files
498
560
 
499
- Runbook automatically loads configuration from a number of predefined files. Runbook will attempt to load configuration from the following locations on startup: `/etc/runbook.conf`, a `Runbookfile` in a parent directory from the current directory, a `.runbook.conf` file in the current user's home directory, a file specified with `--config` on the command line, any configuration specified in a runbook. Runbook will also load configuration from these files in this order of preference, respectively. That is, configuration values specified at the project level (`Runbookfile`) will override configuration values set at the global level (`/etc/runbook.conf`), etc.
561
+ Runbook loads configuration from a number of predefined files. Runbook will attempt to load configuration from the following locations on startup: `/etc/runbook.conf`, a `Runbookfile` in a parent directory from the current directory, a `.runbook.conf` file in the current user's home directory, a file specified with `--config` on the command line, any configuration specified in a runbook. Runbook will also load configuration from these files in this order of preference, respectively. That is, configuration values specified at the project level (`Runbookfile`) will override configuration values set at the global level (`/etc/runbook.conf`), etc.
500
562
 
501
563
  ## Working With Runbooks
502
564
 
@@ -617,7 +679,7 @@ The following are best practices when developing your own runbooks.
617
679
 
618
680
  ### Iterative Automation
619
681
 
620
- Runbooks allow for a very gradual transition from entirely manual operations to full automation. Runbooks can start out as a simple outline of all steps required to carry out an operation. From there, commands and prompts can be added to the runbook, actually carrying out and replacing the manual processes.
682
+ Runbooks allow for a gradual transition from entirely manual operations to full automation. Runbooks can start out as a simple outline of all steps required to carry out an operation. From there, commands and prompts can be added to the runbook, actually carrying out and replacing the manual processes.
621
683
 
622
684
  Monitoring can transition from a process required by a human into something that can be codified and executed by your runbook. Eventually, the runner's `auto` flag can be used to allow the runbook to run uninterrupted without any human intervention. These runbooks can be triggered automatically in response to detected events. This will allow you to do more important things with your time, like eat ice cream.
623
685
 
@@ -739,6 +801,50 @@ Instance variables are only passed between statements such as `ruby_command`. Th
739
801
 
740
802
  Be careful with your naming of instance variables as it is possible to clobber the step's DSL methods because they share the same namespace.
741
803
 
804
+ ## Generators
805
+
806
+ Runbook provides a number of generators accessible via the command line that can be used to generate code for new runbooks, Runbook projects, and Runbook extensions. Additionally, Runbook provides a generator generator so you can define your own custom generators.
807
+
808
+ ### Predefined Generators
809
+
810
+ Runbook provides a number of predefined generators. You can see the full list using Runbook's command line help.
811
+
812
+ $ runbook help generate
813
+
814
+ Commands:
815
+ runbook generate dsl_extension NAME [options] # Generate a dsl_extension for adding custom runbook DSL functionality
816
+ runbook generate generator NAME [options] # Generate a runbook generator named NAME, e.x. acme_runbook
817
+ runbook generate help [COMMAND] # Describe subcommands or one specific subcommand
818
+ runbook generate project NAME [options] # Generate a project for your runbooks
819
+ runbook generate runbook NAME [options] # Generate a runbook named NAME, e.x. deploy_nginx
820
+ runbook generate statement NAME [options] # Generate a statement named NAME (e.x. ruby_command) that can be used in your runbooks
821
+
822
+ Base options:
823
+ -c, [--config=CONFIG] # Path to runbook config file
824
+ [--root=ROOT] # The root directory for your generated code
825
+ # Default: .
826
+
827
+ Runtime options:
828
+ -f, [--force] # Overwrite files that already exist
829
+ -p, [--pretend], [--no-pretend] # Run but do not make any changes
830
+ -q, [--quiet], [--no-quiet] # Suppress status output
831
+ -s, [--skip], [--no-skip] # Skip files that already exist
832
+
833
+ Unless otherwise specified, all `NAME` arguments should be specified in a snake case format (e.x. `acme_runbook`). The `-p/--pretend` flag can be helpful for seeing what files a generator will create before it creates them.
834
+
835
+ ### Custom Generators
836
+
837
+ The generator generator is useful for defining your own custom generators. Runbook uses [Thor Generators](https://github.com/erikhuda/thor/wiki/Generators) in the background, so any functionality you can do using Thor Generators can also be done using Runbook generators.
838
+
839
+ Generate your own generator using the `generate generator` command
840
+
841
+ $ runbook generate generator my_new_generator --root lib/runbook/generators
842
+ create my_new_generator
843
+ create my_new_generator/templates
844
+ create my_new_generator/my_new_generator.rb
845
+
846
+ `my_new_generator/my_new_generator.rb` contains all the logic for generating your new code including arguments, options, and new files. ERB-templated files live in `my_new_generator/templates`. Remember to require your generator file in a runbook config file such as your `Runbookfile` so it can be loaded by the CLI. Generators cannot be required in config files specified at the command line due to the order with which the command line code is loaded. Once loaded, any child classes of `Runbook::Generators` will be included in Runbook's generator CLI.
847
+
742
848
  ## Extending Runbook
743
849
 
744
850
  Runbook can be extended to add custom functionality.
@@ -800,7 +906,7 @@ module Runbook::Statements
800
906
  end
801
907
  ```
802
908
 
803
- In the above example a keyword `diagram` will be automatically added to the step dsl and its arguments will be used to initialize the Diagram object.
909
+ In the above example a keyword `diagram` will be added to the step dsl and its arguments will be used to initialize the Diagram object.
804
910
 
805
911
  ### Adding Run and View Functionality
806
912
 
data/TODO.md CHANGED
@@ -1,10 +1,10 @@
1
1
  ## Desired feature list
2
2
  * [X] Revise README.md
3
- * [] capistrano-runbook gem that integrates runbook into capistrano tasks
4
- * [] Create a generator for a runbook? Allow for custom generators?
3
+ * [X] Create a generator for a runbook? Allow for custom generators?
5
4
  * Generate runbook templates
6
5
  * Generate runbook projects with Runbookfile, Gemfile, etc.
7
6
  * Generate plugins
7
+ * [] capistrano-runbook gem that integrates runbook into capistrano tasks
8
8
  * [] Add Appraisal to test against multiple versions of Ruby
9
9
  * [] Update output to be more log friendly, including timestamps for operations
10
10
  * [] Allow for preventing echo when prompting for input
@@ -15,11 +15,18 @@
15
15
  * [] Replace Thor with a solution that is more easily extendable (adding new flags, etc.)
16
16
  * [] Add goto statements for repeating steps (functionality exists in paranoid mode)
17
17
  * [] Add test statement
18
+ * [] Add ruby_assert statement
18
19
  * [] Feedback on completion of tmux commands (when they complete, return values, outputs)
19
20
  * [] Add shorter aliases for tmux layout keys
20
21
  * [] Add host aliases for ssh_config setters
21
22
  * [] Allow for step dependencies that get executed before the step
22
23
  * [] Add periodic flush for sshkit output
24
+ * [] Update assert attribute nomenclature (timeout_statement)
25
+ * [] Update ssh_kit to count commands separately between steps
26
+ * [] Create a plugin generator
27
+ * [] Create generator for a new run (sshkit, etc.)
28
+ * [] Create generator for a new view (markdown, yaml, html, etc.)
29
+ * Add rake tasks to generators for viewing and executing runbooks
23
30
  * Add a way to execute a series of commands in groups
24
31
  * Docker testing story for more full-stack integration tests
25
32
  * Test integration with sshkit
@@ -34,5 +41,6 @@
34
41
  * Can convert from Ruby format to yaml (depending on compatibility) and yaml to Ruby
35
42
  * Guard for view updates (How to handle arguments?)
36
43
  * Be able to serve up markdown docs (web server) for easy viewing
44
+ * Add interactive executable for all runbooks in a project
37
45
  * Could provide a rake task for compiling and nooping runbooks?
38
46
  * Can specify input-format, output-format, input (file), and output (file)
data/lib/runbook/cli.rb CHANGED
@@ -1,17 +1,17 @@
1
1
  require "thor"
2
2
  require "runbook"
3
+ require "runbook/cli_base"
4
+ require "runbook/installer"
5
+
6
+ # Needed to load custom generators
7
+ Runbook::Configuration.load_config
8
+ require "runbook/generator"
3
9
 
4
10
  module Runbook
5
11
  class CLI < Thor
6
- map "--version" => :__print_version
7
- class_option :config, aliases: :c, type: :string
12
+ include ::Runbook::CLIBase
8
13
 
9
- def initialize(args = [], local_options = {}, config = {})
10
- super(args, local_options, config)
11
-
12
- cmd_name = config[:current_command].name
13
- _set_cli_config(options[:config], cmd_name) if options[:config]
14
- end
14
+ map "--version" => :__print_version
15
15
 
16
16
  desc "view RUNBOOK", "Prints a formatted version of the runbook"
17
17
  long_desc <<-LONGDESC
@@ -19,7 +19,7 @@ module Runbook
19
19
 
20
20
  With --view (-v), Prints the view using the specified view type
21
21
  LONGDESC
22
- option :view, aliases: :v, type: :string, default: :markdown
22
+ option :view, aliases: "-v", type: :string, default: :markdown
23
23
  def view(runbook)
24
24
  runbook = _retrieve_runbook(runbook, :view)
25
25
  puts Runbook::Viewer.new(runbook).generate(
@@ -49,11 +49,11 @@ module Runbook
49
49
  With --start-at (-s), Runs the runbook starting at the specified
50
50
  section or step.
51
51
  LONGDESC
52
- option :run, aliases: :r, type: :string, default: :ssh_kit
53
- option :noop, aliases: :n, type: :boolean
54
- option :auto, aliases: :a, type: :boolean
55
- option :"no-paranoid", aliases: :P, type: :boolean
56
- option :start_at, aliases: :s, type: :string, default: "0"
52
+ option :run, aliases: "-r", type: :string, default: :ssh_kit
53
+ option :noop, aliases: "-n", type: :boolean
54
+ option :auto, aliases: "-a", type: :boolean
55
+ option :"no-paranoid", aliases: "-P", type: :boolean
56
+ option :start_at, aliases: "-s", type: :string, default: "0"
57
57
  def exec(runbook)
58
58
  runbook = _retrieve_runbook(runbook, :exec)
59
59
  Runbook::Runner.new(runbook).run(
@@ -65,6 +65,23 @@ module Runbook
65
65
  )
66
66
  end
67
67
 
68
+ desc "generate GENERATOR", "Generate runbook objects from a template, such as runbooks, projects, or plugins."
69
+ long_desc <<-LONGDESC
70
+ Generates a runbook, runbook node, runbook project, or runbook plugin from a template.
71
+ LONGDESC
72
+ subcommand "generate", Runbook::Generator
73
+
74
+ desc "install", "Install Runbook into an existing project"
75
+ long_desc "Set up Runbook directory structure and Runbookfile in an existing project for executing runbooks."
76
+ Runbook::Installer.class_options.values.each do |co|
77
+ method_option co.name, desc: co.description, required: co.required,
78
+ default: co.default, aliases: co.aliases, type: co.type,
79
+ banner: co.banner, hide: co.hide
80
+ end
81
+ def install
82
+ invoke(Runbook::Installer)
83
+ end
84
+
68
85
  desc "--version", "Print runbook's version"
69
86
  def __print_version
70
87
  puts "Runbook v#{Runbook::VERSION}"
@@ -72,13 +89,6 @@ module Runbook
72
89
 
73
90
  private
74
91
 
75
- def _set_cli_config(config, cmd)
76
- unless File.exist?(config)
77
- raise Thor::InvocationError, "#{cmd}: cannot access #{config}: No such file or directory"
78
- end
79
- Runbook::Configuration.cli_config_file = config
80
- end
81
-
82
92
  def _retrieve_runbook(runbook, cmd)
83
93
  unless File.exist?(runbook)
84
94
  raise Thor::InvocationError, "#{cmd}: cannot access #{runbook}: No such file or directory"
@@ -0,0 +1,38 @@
1
+ module Runbook::CLIBase
2
+ def self.included(base)
3
+ base.extend(ClassMethods)
4
+
5
+ base.check_unknown_options!
6
+
7
+ base.class_option(
8
+ :config,
9
+ aliases: "-c",
10
+ type: :string,
11
+ group: :base,
12
+ desc: "Path to runbook config file"
13
+ )
14
+ end
15
+
16
+ def initialize(args = [], local_options = {}, config = {})
17
+ super(args, local_options, config)
18
+
19
+ cmd_name = config[:current_command].name
20
+ _set_cli_config(options[:config], cmd_name) if options[:config]
21
+ end
22
+
23
+ module ClassMethods
24
+ def exit_on_failure?
25
+ true
26
+ end
27
+ end
28
+
29
+ protected
30
+
31
+ def _set_cli_config(config, cmd)
32
+ unless File.exist?(config)
33
+ raise Thor::InvocationError, "#{cmd}: cannot access #{config}: No such file or directory"
34
+ end
35
+ Runbook::Configuration.cli_config_file = config
36
+ Runbook::Configuration.reconfigure
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ module Runbook
2
+ class Generator < Thor
3
+ include Runbook::CLIBase
4
+ include Thor::Actions
5
+
6
+ Runbook::Generators::Base.set_base_options(self)
7
+
8
+ def self._unique_class_options(generator)
9
+ generator.class_options.values.reject do |class_option|
10
+ class_option.group == "Runtime" ||
11
+ class_option.group == "Base"
12
+ end
13
+ end
14
+
15
+ Runbook.generators.each do |generator|
16
+ desc(generator.usage, generator.description, generator.options)
17
+
18
+ long_desc(generator.long_description)
19
+
20
+ _unique_class_options(generator).each do |co|
21
+ method_option(
22
+ co.name,
23
+ desc: co.description,
24
+ required: co.required,
25
+ default: co.default,
26
+ aliases: co.aliases,
27
+ type: co.type,
28
+ banner: co.banner,
29
+ hide: co.hide,
30
+ )
31
+ end
32
+
33
+ define_method(generator.command) do |*args|
34
+ invoke(generator, args)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,45 @@
1
+ module Runbook::Generators
2
+ module Base
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+ base.include(Thor::Actions)
6
+
7
+ set_base_options(base)
8
+ base.check_unknown_options!
9
+ end
10
+
11
+ def self.set_base_options(base)
12
+ base.class_option(
13
+ :root,
14
+ group: :base,
15
+ default: ".",
16
+ desc: "The root directory for your generated code",
17
+ )
18
+ base.add_runtime_options!
19
+ end
20
+
21
+ module ClassMethods
22
+ def command
23
+ self.to_s.gsub("Runbook::Generators::", "").underscore
24
+ end
25
+
26
+ def usage
27
+ args = arguments.map(&:banner).join(" ")
28
+ args += " " unless args.empty?
29
+ "#{command} #{args}[options]"
30
+ end
31
+
32
+ def description
33
+ "Generate a #{command}"
34
+ end
35
+
36
+ def long_description
37
+ description
38
+ end
39
+
40
+ def options
41
+ {}
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,29 @@
1
+ module Runbook::Generators
2
+ class DslExtension < Thor::Group
3
+ include ::Runbook::Generators::Base
4
+
5
+ source_root File.dirname(__FILE__)
6
+
7
+ def self.description
8
+ "Generate a dsl_extension for adding custom runbook DSL functionality"
9
+ end
10
+
11
+ def self.long_description
12
+ <<-LONG_DESC
13
+ This generator provides a template for extending Runbook's DSL. Using a
14
+ DSL extension, you can add custom commands to a book, section, or step
15
+ that can be used in your runbooks.
16
+ LONG_DESC
17
+ end
18
+
19
+ argument :name, desc: "The name of your dsl_extension, e.x. rollback_section"
20
+
21
+ def create_dsl_extension
22
+ target = File.join(
23
+ parent_options[:root],
24
+ "#{name.underscore}.rb",
25
+ )
26
+ template('templates/dsl_extension.tt', target)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,25 @@
1
+ # Remember to require this file in a runbook config file
2
+ # or in your project so it is available in your runbooks
3
+ # See https://github.com/braintree/runbook/tree/master/lib/runbook/extensions
4
+ # for examples of DSL extensions
5
+ module MyProject::RunbookExtensions
6
+ module <%= name.classify %>
7
+ module DSL
8
+ # def description(msg)
9
+ # Runbook::Statements::Description.new(msg).tap do |desc|
10
+ # # All DSLs can reference their parent object using
11
+ # # the parent method. This allows you to modify the
12
+ # # parent book, section, or step of the DSL
13
+ # parent.add(desc)
14
+ # end
15
+ # end
16
+ end
17
+ end
18
+
19
+ # Uncomment the below statements to add the the DSL methods to
20
+ # Book, Section, and Step DSLs respectively. Now this method can
21
+ # be called from the corresponding DSL in your runbooks
22
+ # Runbook::Entities::Book::DSL.prepend(<%= name.classify %>::DSL)
23
+ # Runbook::Entities::Section::DSL.prepend(<%= name.classify %>::DSL)
24
+ # Runbook::Entities::Step::DSL.prepend(<%= name.classify %>::DSL)
25
+ end
@@ -0,0 +1,43 @@
1
+ module Runbook::Generators
2
+ class Generator < Thor::Group
3
+ include ::Runbook::Generators::Base
4
+
5
+ source_root File.dirname(__FILE__)
6
+
7
+ def self.usage
8
+ "generator NAME [options]"
9
+ end
10
+
11
+ def self.description
12
+ "Generate a runbook generator named NAME, e.x. acme_runbook"
13
+ end
14
+
15
+ argument :name, desc: "The name of your generator for populating boilerplate"
16
+
17
+ def create_generator_directory
18
+ target = File.join(
19
+ parent_options[:root],
20
+ name.underscore,
21
+ )
22
+ empty_directory(target)
23
+ end
24
+
25
+ def create_templates_directory
26
+ target = File.join(
27
+ parent_options[:root],
28
+ name.underscore,
29
+ "templates",
30
+ )
31
+ empty_directory(target)
32
+ end
33
+
34
+ def create_generator
35
+ target = File.join(
36
+ parent_options[:root],
37
+ name.underscore,
38
+ "#{name.underscore}.rb",
39
+ )
40
+ template('templates/generator.tt', target)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,53 @@
1
+ module Runbook::Generators
2
+ # Remember to require this class in a runbook config file such as your
3
+ # Runbookfile so it can be used from the command line. Note that you cannot
4
+ # require this generator from a config file specified on the command line.
5
+ class <%= name.classify %> < Thor::Group
6
+ include ::Runbook::Generators::Base
7
+
8
+ source_root File.dirname(__FILE__)
9
+
10
+ # Uncomment this method to customize the generator's usage
11
+ # description in runbook's help description.
12
+ #
13
+ # def self.usage
14
+ # args = arguments.map(&:banner).join(" ")
15
+ # args += " " unless args.empty?
16
+ # "<%= name.underscore %> #{args}[options]"
17
+ # end
18
+
19
+ # Uncomment this method to customize the generator's
20
+ # description in runbook's help message.
21
+ #
22
+ # def self.description
23
+ # "Generate a <%= name %>"
24
+ # end
25
+
26
+ # Uncomment this method to customize the generator's
27
+ # long description in runbook's help message.
28
+ #
29
+ # def self.long_description
30
+ # <<-LONG_DESC
31
+ # Here you can fully describe the options of your generator.
32
+ # LONG_DESC
33
+ # end
34
+
35
+ # Argument example
36
+ # argument :name, desc: "The name of your <%= name.underscore %>, e.x. deploy_nginx"
37
+
38
+ # Option example
39
+ # class_option :include-readme, default: true, type: :boolean
40
+
41
+ # Example of a generator step
42
+ # See: https://github.com/erikhuda/thor/wiki/Generators
43
+ # for further documentation on using thor generators.
44
+ #
45
+ # def create_<%= name.underscore %>
46
+ # target = File.join(
47
+ # parent_options[:root],
48
+ # "#{name.underscore}.rb",
49
+ # )
50
+ # template('templates/<%= name.underscore %>.tt', target)
51
+ # end
52
+ end
53
+ end