automateit 0.70923

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. data.tar.gz.sig +1 -0
  2. data/CHANGES.txt +100 -0
  3. data/Hoe.rake +35 -0
  4. data/Manifest.txt +111 -0
  5. data/README.txt +44 -0
  6. data/Rakefile +284 -0
  7. data/TESTING.txt +57 -0
  8. data/TODO.txt +26 -0
  9. data/TUTORIAL.txt +390 -0
  10. data/bin/ai +3 -0
  11. data/bin/aifield +82 -0
  12. data/bin/aitag +128 -0
  13. data/bin/automateit +117 -0
  14. data/docs/friendly_errors.txt +50 -0
  15. data/docs/previews.txt +86 -0
  16. data/env.sh +4 -0
  17. data/examples/basic/Rakefile +26 -0
  18. data/examples/basic/config/automateit_env.rb +16 -0
  19. data/examples/basic/config/fields.yml +3 -0
  20. data/examples/basic/config/tags.yml +13 -0
  21. data/examples/basic/dist/README.txt +9 -0
  22. data/examples/basic/dist/myapp_server.erb +30 -0
  23. data/examples/basic/install.log +15 -0
  24. data/examples/basic/lib/README.txt +10 -0
  25. data/examples/basic/recipes/README.txt +4 -0
  26. data/examples/basic/recipes/install.rb +53 -0
  27. data/examples/basic/recipes/uninstall.rb +6 -0
  28. data/gpl.txt +674 -0
  29. data/lib/automateit.rb +66 -0
  30. data/lib/automateit/account_manager.rb +106 -0
  31. data/lib/automateit/account_manager/linux.rb +171 -0
  32. data/lib/automateit/account_manager/passwd.rb +69 -0
  33. data/lib/automateit/account_manager/portable.rb +136 -0
  34. data/lib/automateit/address_manager.rb +165 -0
  35. data/lib/automateit/address_manager/linux.rb +80 -0
  36. data/lib/automateit/address_manager/portable.rb +37 -0
  37. data/lib/automateit/cli.rb +80 -0
  38. data/lib/automateit/common.rb +65 -0
  39. data/lib/automateit/constants.rb +33 -0
  40. data/lib/automateit/edit_manager.rb +292 -0
  41. data/lib/automateit/error.rb +10 -0
  42. data/lib/automateit/field_manager.rb +103 -0
  43. data/lib/automateit/interpreter.rb +641 -0
  44. data/lib/automateit/package_manager.rb +242 -0
  45. data/lib/automateit/package_manager/apt.rb +63 -0
  46. data/lib/automateit/package_manager/egg.rb +64 -0
  47. data/lib/automateit/package_manager/gem.rb +179 -0
  48. data/lib/automateit/package_manager/portage.rb +69 -0
  49. data/lib/automateit/package_manager/yum.rb +65 -0
  50. data/lib/automateit/platform_manager.rb +47 -0
  51. data/lib/automateit/platform_manager/darwin.rb +30 -0
  52. data/lib/automateit/platform_manager/debian.rb +26 -0
  53. data/lib/automateit/platform_manager/freebsd.rb +25 -0
  54. data/lib/automateit/platform_manager/gentoo.rb +26 -0
  55. data/lib/automateit/platform_manager/lsb.rb +40 -0
  56. data/lib/automateit/platform_manager/struct.rb +78 -0
  57. data/lib/automateit/platform_manager/uname.rb +29 -0
  58. data/lib/automateit/platform_manager/windows.rb +33 -0
  59. data/lib/automateit/plugin.rb +7 -0
  60. data/lib/automateit/plugin/base.rb +32 -0
  61. data/lib/automateit/plugin/driver.rb +218 -0
  62. data/lib/automateit/plugin/manager.rb +232 -0
  63. data/lib/automateit/project.rb +460 -0
  64. data/lib/automateit/root.rb +14 -0
  65. data/lib/automateit/service_manager.rb +79 -0
  66. data/lib/automateit/service_manager/chkconfig.rb +39 -0
  67. data/lib/automateit/service_manager/rc_update.rb +37 -0
  68. data/lib/automateit/service_manager/sysv.rb +126 -0
  69. data/lib/automateit/service_manager/update_rcd.rb +35 -0
  70. data/lib/automateit/shell_manager.rb +261 -0
  71. data/lib/automateit/shell_manager/base_link.rb +67 -0
  72. data/lib/automateit/shell_manager/link.rb +24 -0
  73. data/lib/automateit/shell_manager/portable.rb +421 -0
  74. data/lib/automateit/shell_manager/symlink.rb +32 -0
  75. data/lib/automateit/shell_manager/which.rb +25 -0
  76. data/lib/automateit/tag_manager.rb +63 -0
  77. data/lib/automateit/tag_manager/struct.rb +101 -0
  78. data/lib/automateit/tag_manager/tag_parser.rb +91 -0
  79. data/lib/automateit/tag_manager/yaml.rb +29 -0
  80. data/lib/automateit/template_manager.rb +55 -0
  81. data/lib/automateit/template_manager/base.rb +172 -0
  82. data/lib/automateit/template_manager/erb.rb +17 -0
  83. data/lib/ext/metaclass.rb +17 -0
  84. data/lib/ext/object.rb +18 -0
  85. data/lib/hashcache.rb +22 -0
  86. data/lib/helpful_erb.rb +63 -0
  87. data/lib/nested_error.rb +33 -0
  88. data/lib/queued_logger.rb +68 -0
  89. data/lib/tempster.rb +239 -0
  90. data/misc/index_gem_repository.rb +303 -0
  91. data/misc/setup_egg.rb +12 -0
  92. data/misc/setup_gem_dependencies.sh +7 -0
  93. data/misc/setup_rubygems.sh +21 -0
  94. data/misc/which.cmd +6 -0
  95. data/spec/extras/automateit_service_sysv_test +50 -0
  96. data/spec/extras/scratch.rb +15 -0
  97. data/spec/extras/simple_recipe.rb +8 -0
  98. data/spec/integration/account_manager_spec.rb +218 -0
  99. data/spec/integration/address_manager_linux_spec.rb +119 -0
  100. data/spec/integration/address_manager_portable_spec.rb +30 -0
  101. data/spec/integration/cli_spec.rb +215 -0
  102. data/spec/integration/examples_spec.rb +54 -0
  103. data/spec/integration/examples_spec_editor.rb +71 -0
  104. data/spec/integration/package_manager_spec.rb +104 -0
  105. data/spec/integration/platform_manager_spec.rb +69 -0
  106. data/spec/integration/service_manager_sysv_spec.rb +115 -0
  107. data/spec/integration/shell_manager_spec.rb +471 -0
  108. data/spec/integration/template_manager_erb_spec.rb +31 -0
  109. data/spec/spec_helper.rb +23 -0
  110. data/spec/unit/edit_manager_spec.rb +162 -0
  111. data/spec/unit/field_manager_spec.rb +79 -0
  112. data/spec/unit/hashcache_spec.rb +28 -0
  113. data/spec/unit/interpreter_spec.rb +98 -0
  114. data/spec/unit/platform_manager_spec.rb +44 -0
  115. data/spec/unit/plugins_spec.rb +253 -0
  116. data/spec/unit/tag_manager_spec.rb +189 -0
  117. data/spec/unit/template_manager_erb_spec.rb +137 -0
  118. metadata +249 -0
  119. metadata.gz.sig +0 -0
@@ -0,0 +1,460 @@
1
+ module AutomateIt
2
+ # = Project
3
+ #
4
+ # An AutomateIt Project is a collection of related recipes, tags, fields and
5
+ # custom plugins.
6
+ #
7
+ # === Create a project
8
+ #
9
+ # You can create a project by running the following from the Unix shell:
10
+ #
11
+ # automateit --create myproject
12
+ #
13
+ # This will create a directory called +myproject+ with a number of
14
+ # directories and files. Each directory has a <tt>README.txt</tt> that
15
+ # explains what it's used for.
16
+ #
17
+ # === Advantages of a project over raw recipe files
18
+ #
19
+ # Although you can run recipes without a project, putting your recipes into a
20
+ # project provides you with the following benefits:
21
+ #
22
+ # 1. Directory structure to organize your files.
23
+ # 2. Automatically loads tags from project's <tt>config/tags.yml</tt> file.
24
+ # 3. Loads fields from the <tt>config/fields.yml</tt> file.
25
+ # 4. Loads all custom plugins and libraries found in the +lib+ directory.
26
+ # 5. Provides a +dist+ method that corresponds to your project's +dist+
27
+ # directory. Using this method will save you from having to type paths for
28
+ # files you intend to distribute from recipes, e.g.:
29
+ # cp(dist+"/source.txt", "/tmp/target.txt")
30
+ #
31
+ # === Using a project
32
+ #
33
+ # For example, create a new project:
34
+ #
35
+ # automateit --create hello_project
36
+ #
37
+ # Inside this project, edit its fields, which are stored in the
38
+ # <tt>config/fields.yml</tt> file, and make it look like this:
39
+ #
40
+ # greeting: Hello world!
41
+ #
42
+ # Then create a recipe in the <tt>recipes/greet.rb</tt> file:
43
+ #
44
+ # puts lookup(:greeting)
45
+ #
46
+ # You can run the recipe:
47
+ #
48
+ # automateit recipes/greet.rb
49
+ #
50
+ # And you should get the following output:
51
+ #
52
+ # Hello world!
53
+ #
54
+ # === Using project libraries
55
+ #
56
+ # Any files ending with <tt>.rb</tt> that you put into the project's
57
+ # <tt>lib</tt> directory will be loaded before your recipe starts executing.
58
+ # This is a good way to add common features, custom plugins and such.
59
+ #
60
+ # For example, put the following into a new <tt>lib/meow.rb</tt> file:
61
+ #
62
+ # def meow
63
+ # "MEOW!"
64
+ # end
65
+ #
66
+ # Now create a new recipe that uses this method in <tt>recipes/speak.rb</tt>
67
+ #
68
+ # puts meow
69
+ #
70
+ # Now you can run it:
71
+ #
72
+ # automateit recipes/speak.rb
73
+ #
74
+ # And you'll get this:
75
+ #
76
+ # MEOW!
77
+ #
78
+ # === Specifying project paths on the Unix shell
79
+ #
80
+ # AutomateIt will load the project automatically if you're executing a recipe
81
+ # that's inside a project's +recipes+ directory.
82
+ #
83
+ # For example, assume that you've create your project as
84
+ # <tt>/tmp/hello_project</tt> and have a recipe at
85
+ # <tt>/tmp/hello_project/recipes/greet.rb</tt>.
86
+ #
87
+ # You can execute the recipe with a full path:
88
+ #
89
+ # automateit /tmp/hello_project/recipes/greet.rb
90
+ #
91
+ # Or execute it with a relative path:
92
+ #
93
+ # cd /tmp/hello_project/recipes
94
+ # automateit greet.rb
95
+ #
96
+ # Or you can prepend a header to the <tt>greet.rb</tt> recipe so it looks like this
97
+ #
98
+ # #!/usr/bin/env automateit
99
+ #
100
+ # puts lookup(:greeting)
101
+ #
102
+ # And then make the file executable:
103
+ #
104
+ # chmod a+X /tmp/hello_project/recipes/greet.rb
105
+ #
106
+ # And execute the recipe directly:
107
+ #
108
+ # /tmp/hello_project/recipes/greet.rb
109
+ #
110
+ # === Specifying project paths for embedded programs
111
+ #
112
+ # If you're embedding the Interpreter into another Ruby program, you can run recipes and they'll automatically load the project if applicable. For example:
113
+ #
114
+ # require 'rubygems'
115
+ # require 'automateit'
116
+ # AutomateIt.invoke("/tmp/hello_project/recipes/greet.rb")
117
+ #
118
+ # Or if you may specify the project path explicitly:
119
+ #
120
+ # require 'rubygems'
121
+ # require 'automateit'
122
+ # interpreter = AutomateIt.new(:project => "/tmp/hello_project")
123
+ # puts interpreter.lookup("greeting")
124
+ #
125
+ # === Tag and field command-line helpers
126
+ #
127
+ # You can access a project's tags and fields from the Unix shell. This
128
+ # helps other programs access configuration data and make use of your roles.
129
+ #
130
+ # For example, with the <tt>hello_project</tt> we've created, we can lookup
131
+ # fields from the Unix shell like this:
132
+ #
133
+ # aifield -p /tmp/hello_project greeting
134
+ #
135
+ # The <tt>-p</tt> specifies the project path (its an alias for
136
+ # <tt>--project</tt>). More commands are available. You can see the
137
+ # documentation and examples for these commands by running:
138
+ #
139
+ # aifield --help
140
+ # aitag --help
141
+ #
142
+ # Sometimes it's convenient to set a default project path so you don't need
143
+ # to type as much by specifing the <tt>AUTOMATEIT_PROJECT</tt> environmental
144
+ # variable (or <tt>AIP</tt> if you want a shortcut) and use it like this:
145
+ #
146
+ # export AUTOMATEIT_PROJECT=/tmp/hello_project
147
+ # aifield greeting
148
+ #
149
+ # === Sharing a project between systems
150
+ #
151
+ # If you want to share a project between different hosts, you're responsible for distributing the files between them. This isn't a big deal though because these are just text files and your OS has dozens of excellent ways to distribute these.
152
+ #
153
+ # Common approaches to distribution:
154
+ # * *Shared directory*: Your hosts mount a shared network directory (e.g., +nfs+ or +smb+) with your project. This is very easy if your hosts already have a shared directory, but can be a nuisance otherwise because it opens potential security holes and risks having you hosts hang if the master goes offline.
155
+ # * *Client pull*: Your hosts download the latest copy of your project from a master repository using a remote copy tool (e.g., +rsync+) or a revision control system (e.g., +cvs+, +svn+, +hg+). This is a safe, simple and secure option.
156
+ # * *Server push*: You have a master push out the project files to clients using a remote copy tool. This can be awkward and time-consuming because the server must go through a list of all hosts and copy files to them individually.
157
+ #
158
+ # An example of a complete solution for distributing system configuration management files:
159
+ # * Setup an +svn+ or +hg+ repository to store your project and create a special account for the hosts to use to checkout code.
160
+ # * Write a wrapper script for running the recipes, for example, write a "/usr/bin/myautomateit" shell script like:
161
+ #
162
+ # #!/bin/sh
163
+ # cd /var/local/myautomateit
164
+ # svn update --quiet
165
+ # automateit recipe/default.rb
166
+ # * Run this wrapper once an hour using cron so that your systems are always up to date. AutomateIt only prints output when it makes a change, so cron will only email you when you commit new code to the repository and the hosts make changes.
167
+ # * If you need to run a recipe on the machine right now, SSH into it and run the wrapper.
168
+ # * If you need to run the script early on a bunch of machines and don't want to manually SSH into each one, you can leverage the +aitag+ (see <tt>aitag --help</tt>) to execute a Unix command across multiple systems. For example, you could use a Unix shell command like this to execute the wrapper on all hosts tagged with +apache_servers+:
169
+ #
170
+ # for host in `aitag -p /var/local/myautomateit -w apache_server`; do
171
+ # echo "# $host"
172
+ # ssh $host myautomateit
173
+ # done
174
+ #
175
+ # === Curios
176
+ #
177
+ # In case you're interested, the project creator is actually an AutomateIt
178
+ # recipe. You can read the recipe source code by looking at the
179
+ # AutomateIt::Project::create method.
180
+ class Project < Common
181
+ # Create a new project.
182
+ #
183
+ # Options:
184
+ # * :create -- Project path to create. Required.
185
+ # * All other options are passed to the AutomateIt::Interpreter.
186
+ def self.create(opts)
187
+ display = lambda {|message| puts message if ! opts[:verbosity] || (opts[:verbosity] && opts[:verbosity] <= Logger::INFO) }
188
+
189
+ path = opts.delete(:create) \
190
+ or raise ArgumentError.new(":create option not specified")
191
+ interpreter = AutomateIt.new(opts)
192
+ interpreter.instance_eval do
193
+ # +render+ only files that don't exist.
194
+ template_manager.default_check = :exists
195
+
196
+ mkdir_p(path) do |created|
197
+ display.call PNOTE+"%s AutomateIt project at: %s" %
198
+ [created ? "Creating" : "Updating", path]
199
+
200
+ render(:text => WELCOME_CONTENT, :to => "README_AutomateIt.txt")
201
+ render(:text => RAKEFILE_CONTENT, :to => "Rakefile")
202
+
203
+ mkdir("config")
204
+ render(:text => TAGS_CONTENT, :to => "config/tags.yml")
205
+ render(:text => FIELDS_CONTENT, :to => "config/fields.yml")
206
+ render(:text => ENV_CONTENT, :to => "config/automateit_env.rb")
207
+
208
+ mkdir("dist")
209
+ render(:text => DIST_README_CONTENT, :to => "dist/README_AutomateIt_dist.txt")
210
+
211
+ mkdir("lib")
212
+ render(:text => BASE_README_CONTENT, :to => "lib/README_AutomateIt_lib.txt")
213
+
214
+ mkdir("recipes")
215
+ render(:text => RECIPE_README_CONTENT, :to => "recipes/README_AutomateIt_recipes.txt")
216
+ render(:text => RECIPE_HELLO_CONTENT, :to => "recipes/hello.rb")
217
+ end
218
+
219
+ if log.info? and not opts[:quiet]
220
+ puts '-----------------------------------------------------------------------'
221
+ puts WELCOME_MESSAGE
222
+ puts '-----------------------------------------------------------------------'
223
+ end
224
+ end # of interpreter.instance_eval
225
+ end
226
+
227
+ #---[ Default text content for generated files ]------------------------
228
+
229
+ WELCOME_MESSAGE = <<-EOB #:nodoc:
230
+ Welcome to AutomateIt!
231
+
232
+ Learn:
233
+ * See it in action at http://AutomateIt.org/screenshots
234
+ * Read the tutorial at http://AutomateIt.org/tutorial
235
+ * Read the documentation at http://AutomateIt.org/documentation
236
+ * See the README files created in the project
237
+
238
+ Run:
239
+ * `automateit -p .` -- Starts interactive shell for project
240
+ * `automateit recipes/hello.rb` -- Runs a recipe called recipes/hello.rb
241
+ * `automateit -n recipes/hello.rb` -- Previews recipe
242
+
243
+ Rake:
244
+ * `rake` -- Starts interactive shell for project
245
+ * `rake hello` -- Runs sample recipe
246
+ * `rake preview` -- Turns on preview mode
247
+ * `rake preview hello` -- Previews the sample recipe
248
+
249
+ Changes:
250
+ * Sign up for RSS feed at http://automateit.org/changes
251
+ EOB
252
+
253
+ welcome_lines = WELCOME_MESSAGE.split(/\n/)
254
+ welcome_title = welcome_lines.first
255
+ welcome_body = welcome_lines[2, welcome_lines.size]
256
+ WELCOME_CONTENT = <<-EOB #:nodoc:
257
+ #-----------------------------------------------------------------------
258
+ #
259
+ # == #{welcome_title}
260
+ #
261
+ #{welcome_body.map{|t| "# %s" % t}.join("\n")}
262
+ #
263
+ #-----------------------------------------------------------------------
264
+ EOB
265
+
266
+ TAGS_CONTENT = <<-EOB # :nodoc:
267
+ # Put your roles here
268
+
269
+ #-----------------------------------------------------------------------
270
+ #
271
+ # == TAGS
272
+ #
273
+ # This is an AutomateIt tags file. Use it to assign tags to hosts so you
274
+ # can manage multiple hosts as a group.
275
+ #
276
+ # For example, in this file assign the tag "myrole" to two computers
277
+ # named "host1" and "host2":
278
+ #
279
+ # myrole:
280
+ # - host1
281
+ # - host2
282
+ #
283
+ # Then check from a recipe if this host has this tag:
284
+ #
285
+ # if tagged?("myrole")
286
+ # # Code will only run if this host is tagged with "myrole"
287
+ # end
288
+ #
289
+ # You can also retrieve tags:
290
+ #
291
+ # puts "Tags for this host: \#{tags.inspect}"
292
+ # # => ["myrole"]
293
+ # puts "Tags for a specific host: \#{tags_for("host1").inspect}"
294
+ # # => ["myrole"]
295
+ # puts "Hosts with a tag: \#{hosts_tagged_with("myrole").inspect}"
296
+ # # => ["host1", "host2"]
297
+ #
298
+ # You will likely see additional tags which are automatically added
299
+ # based on the host's operating system, architecture, hostnames, etc.
300
+ #
301
+ # You may use ERB statements within this file.
302
+ #
303
+ # See AutomateIt::TagManager for further details.
304
+ #
305
+ #-----------------------------------------------------------------------
306
+ EOB
307
+
308
+ FIELDS_CONTENT = <<-EOB #:nodoc:
309
+ # Put your fields here
310
+
311
+ #-----------------------------------------------------------------------
312
+ #
313
+ # == FIELDS
314
+ #
315
+ # This is an AutomateIt fields file. Fields are useful for extracting
316
+ # configuration-specific arguments out of your recipe logic, and making
317
+ # them easier to share between recipes and access from other programs.
318
+ #
319
+ # For example, declare fields using YAML:
320
+ #
321
+ # foo: bar
322
+ # mydaemon:
323
+ # mykey: myvalue
324
+ #
325
+ # And retrieve field values from a recipe:
326
+ #
327
+ # lookup("foo") # => "bar"
328
+ # lookup("mydaemon") # => {"mykey" => "myvalue"}
329
+ # lookup("mydaemon#mykey") # => "myvalue"
330
+ #
331
+ # You may use ERB statements within this file. Because this file is
332
+ # loaded after the tags, you can use ERB to dynamically set fields for
333
+ # specific groups of hosts, e.g.:
334
+ #
335
+ # magical: <%%= tagged?("magical_hosts") ? true : false %>
336
+ #
337
+ # See AutomateIt::FieldManager for further details.
338
+ #
339
+ #-----------------------------------------------------------------------
340
+ EOB
341
+
342
+ ENV_CONTENT = <<-EOB #:nodoc:
343
+ # Put your environment commands here
344
+
345
+ #-----------------------------------------------------------------------
346
+ #
347
+ # == ENVIRONMENT
348
+ #
349
+ # This is an AutomateIt environment file. Use it to customize AutomateIt
350
+ # and provide settings to recipes, interactive shell, or embedded
351
+ # Interpreters using this project.
352
+ #
353
+ # The "self" in this file is an Interpreter instance, so you can execute
354
+ # all the same commands that you'd normally put in a recipe.
355
+ #
356
+ # This file is loaded after the project's tags, fields and libraries.
357
+ #
358
+ #-----------------------------------------------------------------------
359
+ EOB
360
+
361
+ BASE_README_CONTENT = <<-EOB #:nodoc:
362
+ #-----------------------------------------------------------------------
363
+ #
364
+ # == LIB
365
+ #
366
+ # This is your AutomateIt project's "lib" directory. You can put custom
367
+ # plugins and convenience methods into this directory.
368
+ #
369
+ # For example, create a convenience method for geteting the time by
370
+ # creating a "lib/now.rb" file with the following contents:
371
+ #
372
+ # def now
373
+ # DateTime.now
374
+ # end
375
+ #
376
+ # This will provide a "now" method that's available to your recipes,
377
+ # interactive shell or embedded interpreter.
378
+ #
379
+ # Libraries are loaded every time an AutomateIt interpreter is started.
380
+ # It loads all "*.rb" files in this directory, and all "init.rb" files
381
+ # in subdirectories of this directory.
382
+ #
383
+ #-----------------------------------------------------------------------
384
+ EOB
385
+
386
+ DIST_README_CONTENT = <<-EOB #:nodoc:
387
+ #-----------------------------------------------------------------------
388
+ #
389
+ # == DIST
390
+ #
391
+ # This is your AutomateIt project's "dist" directory. It's a place for
392
+ # keeping files and templates you plan to distribute.
393
+ #
394
+ # You can retrieve this directory's path using the "dist" method in
395
+ # recipes, for example:
396
+ #
397
+ # # Display the "dist" directory's path
398
+ # puts dist
399
+ #
400
+ # # Render the template file "dist/foo.erb"
401
+ # render(:file => dist+"/foo.erb", ...)
402
+ #
403
+ # # Or copy the same file somewhere
404
+ # cp(dist+"/foo.erb", ...)
405
+ #
406
+ #-----------------------------------------------------------------------
407
+ EOB
408
+
409
+ RECIPE_README_CONTENT = <<-EOB #:nodoc:
410
+ #-----------------------------------------------------------------------
411
+ #
412
+ # == RECIPES
413
+ #
414
+ # This is your AutomateIt project's "recipes" directory. You should put
415
+ # recipes into this directory.
416
+ #
417
+ # For example, create a "recipes/hello.rb" file with these contents:
418
+ #
419
+ # puts "Hello"
420
+ #
421
+ # And execute it with:
422
+ #
423
+ # automateit recipes/your_recipe.rb
424
+ #
425
+ #-----------------------------------------------------------------------
426
+ EOB
427
+
428
+ RECIPE_HELLO_CONTENT = <<-'EOB' #:nodoc
429
+ puts "Hello, I'm an #{self.class} -- pleased to meet you!"
430
+ puts "I'm in preview mode" if preview?
431
+ EOB
432
+
433
+ RAKEFILE_CONTENT = <<-EOB #:nodoc
434
+ require "automateit"
435
+
436
+ # Create an Interpreter for project in current directory.
437
+ @interpreter = AutomateIt.new(:project => ".")
438
+
439
+ # Include Interpreter's methods into Rake session.
440
+ @interpreter.include_in(self)
441
+
442
+ task :default => :shell
443
+
444
+ desc "Interactive AutomateIt shell"
445
+ task :shell do
446
+ AutomateIt::CLI.run
447
+ end
448
+
449
+ desc "Run a recipe"
450
+ task :hello do
451
+ invoke "hello"
452
+ end
453
+
454
+ desc "Preview action, e.g, 'rake preview hello'"
455
+ task :preview do
456
+ preview true
457
+ end
458
+ EOB
459
+ end
460
+ end