automateit 0.70923
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +1 -0
- data/CHANGES.txt +100 -0
- data/Hoe.rake +35 -0
- data/Manifest.txt +111 -0
- data/README.txt +44 -0
- data/Rakefile +284 -0
- data/TESTING.txt +57 -0
- data/TODO.txt +26 -0
- data/TUTORIAL.txt +390 -0
- data/bin/ai +3 -0
- data/bin/aifield +82 -0
- data/bin/aitag +128 -0
- data/bin/automateit +117 -0
- data/docs/friendly_errors.txt +50 -0
- data/docs/previews.txt +86 -0
- data/env.sh +4 -0
- data/examples/basic/Rakefile +26 -0
- data/examples/basic/config/automateit_env.rb +16 -0
- data/examples/basic/config/fields.yml +3 -0
- data/examples/basic/config/tags.yml +13 -0
- data/examples/basic/dist/README.txt +9 -0
- data/examples/basic/dist/myapp_server.erb +30 -0
- data/examples/basic/install.log +15 -0
- data/examples/basic/lib/README.txt +10 -0
- data/examples/basic/recipes/README.txt +4 -0
- data/examples/basic/recipes/install.rb +53 -0
- data/examples/basic/recipes/uninstall.rb +6 -0
- data/gpl.txt +674 -0
- data/lib/automateit.rb +66 -0
- data/lib/automateit/account_manager.rb +106 -0
- data/lib/automateit/account_manager/linux.rb +171 -0
- data/lib/automateit/account_manager/passwd.rb +69 -0
- data/lib/automateit/account_manager/portable.rb +136 -0
- data/lib/automateit/address_manager.rb +165 -0
- data/lib/automateit/address_manager/linux.rb +80 -0
- data/lib/automateit/address_manager/portable.rb +37 -0
- data/lib/automateit/cli.rb +80 -0
- data/lib/automateit/common.rb +65 -0
- data/lib/automateit/constants.rb +33 -0
- data/lib/automateit/edit_manager.rb +292 -0
- data/lib/automateit/error.rb +10 -0
- data/lib/automateit/field_manager.rb +103 -0
- data/lib/automateit/interpreter.rb +641 -0
- data/lib/automateit/package_manager.rb +242 -0
- data/lib/automateit/package_manager/apt.rb +63 -0
- data/lib/automateit/package_manager/egg.rb +64 -0
- data/lib/automateit/package_manager/gem.rb +179 -0
- data/lib/automateit/package_manager/portage.rb +69 -0
- data/lib/automateit/package_manager/yum.rb +65 -0
- data/lib/automateit/platform_manager.rb +47 -0
- data/lib/automateit/platform_manager/darwin.rb +30 -0
- data/lib/automateit/platform_manager/debian.rb +26 -0
- data/lib/automateit/platform_manager/freebsd.rb +25 -0
- data/lib/automateit/platform_manager/gentoo.rb +26 -0
- data/lib/automateit/platform_manager/lsb.rb +40 -0
- data/lib/automateit/platform_manager/struct.rb +78 -0
- data/lib/automateit/platform_manager/uname.rb +29 -0
- data/lib/automateit/platform_manager/windows.rb +33 -0
- data/lib/automateit/plugin.rb +7 -0
- data/lib/automateit/plugin/base.rb +32 -0
- data/lib/automateit/plugin/driver.rb +218 -0
- data/lib/automateit/plugin/manager.rb +232 -0
- data/lib/automateit/project.rb +460 -0
- data/lib/automateit/root.rb +14 -0
- data/lib/automateit/service_manager.rb +79 -0
- data/lib/automateit/service_manager/chkconfig.rb +39 -0
- data/lib/automateit/service_manager/rc_update.rb +37 -0
- data/lib/automateit/service_manager/sysv.rb +126 -0
- data/lib/automateit/service_manager/update_rcd.rb +35 -0
- data/lib/automateit/shell_manager.rb +261 -0
- data/lib/automateit/shell_manager/base_link.rb +67 -0
- data/lib/automateit/shell_manager/link.rb +24 -0
- data/lib/automateit/shell_manager/portable.rb +421 -0
- data/lib/automateit/shell_manager/symlink.rb +32 -0
- data/lib/automateit/shell_manager/which.rb +25 -0
- data/lib/automateit/tag_manager.rb +63 -0
- data/lib/automateit/tag_manager/struct.rb +101 -0
- data/lib/automateit/tag_manager/tag_parser.rb +91 -0
- data/lib/automateit/tag_manager/yaml.rb +29 -0
- data/lib/automateit/template_manager.rb +55 -0
- data/lib/automateit/template_manager/base.rb +172 -0
- data/lib/automateit/template_manager/erb.rb +17 -0
- data/lib/ext/metaclass.rb +17 -0
- data/lib/ext/object.rb +18 -0
- data/lib/hashcache.rb +22 -0
- data/lib/helpful_erb.rb +63 -0
- data/lib/nested_error.rb +33 -0
- data/lib/queued_logger.rb +68 -0
- data/lib/tempster.rb +239 -0
- data/misc/index_gem_repository.rb +303 -0
- data/misc/setup_egg.rb +12 -0
- data/misc/setup_gem_dependencies.sh +7 -0
- data/misc/setup_rubygems.sh +21 -0
- data/misc/which.cmd +6 -0
- data/spec/extras/automateit_service_sysv_test +50 -0
- data/spec/extras/scratch.rb +15 -0
- data/spec/extras/simple_recipe.rb +8 -0
- data/spec/integration/account_manager_spec.rb +218 -0
- data/spec/integration/address_manager_linux_spec.rb +119 -0
- data/spec/integration/address_manager_portable_spec.rb +30 -0
- data/spec/integration/cli_spec.rb +215 -0
- data/spec/integration/examples_spec.rb +54 -0
- data/spec/integration/examples_spec_editor.rb +71 -0
- data/spec/integration/package_manager_spec.rb +104 -0
- data/spec/integration/platform_manager_spec.rb +69 -0
- data/spec/integration/service_manager_sysv_spec.rb +115 -0
- data/spec/integration/shell_manager_spec.rb +471 -0
- data/spec/integration/template_manager_erb_spec.rb +31 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/unit/edit_manager_spec.rb +162 -0
- data/spec/unit/field_manager_spec.rb +79 -0
- data/spec/unit/hashcache_spec.rb +28 -0
- data/spec/unit/interpreter_spec.rb +98 -0
- data/spec/unit/platform_manager_spec.rb +44 -0
- data/spec/unit/plugins_spec.rb +253 -0
- data/spec/unit/tag_manager_spec.rb +189 -0
- data/spec/unit/template_manager_erb_spec.rb +137 -0
- metadata +249 -0
- metadata.gz.sig +0 -0
data/bin/ai
ADDED
data/bin/aifield
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# XXX What can go wrong with this loading approach?
|
4
|
+
libdir = File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
5
|
+
if File.directory?(libdir) and File.exists?(File.join(libdir, "automateit.rb"))
|
6
|
+
$LOAD_PATH.unshift(libdir)
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'rubygems'
|
10
|
+
require 'optparse'
|
11
|
+
require 'automateit'
|
12
|
+
|
13
|
+
OptionParser.new do |parser|
|
14
|
+
PROG = File.basename($0)
|
15
|
+
opts = {}
|
16
|
+
parser.banner = <<EOB
|
17
|
+
#{PROG} - tool for querying AutomateIt fields
|
18
|
+
|
19
|
+
Usage: #{PROG} [options] query
|
20
|
+
|
21
|
+
Examples:
|
22
|
+
# Load 'myproject' and get value of 'user' field in 'myapp' hash:
|
23
|
+
#{PROG} -p myproject myapp#user
|
24
|
+
|
25
|
+
# Same but using environmental variable to specify project:
|
26
|
+
AUTOMATEIT_PROJECT=myproject
|
27
|
+
#{PROG} myapp#user
|
28
|
+
|
29
|
+
# Dump the 'myapp' hash contents as YAML
|
30
|
+
#{PROG} -y myapp#user
|
31
|
+
|
32
|
+
# Dump the 'myapp' hash contents as XML
|
33
|
+
#{PROG} -x myapp#user
|
34
|
+
|
35
|
+
Options:
|
36
|
+
EOB
|
37
|
+
parser.on("-p", "--project PATH", "Set project path") do |v|
|
38
|
+
opts[:project] = v
|
39
|
+
end
|
40
|
+
|
41
|
+
parser.on("-Y", "--yaml", "Dump as YAML") do |v|
|
42
|
+
opts[:yaml] = v
|
43
|
+
end
|
44
|
+
|
45
|
+
parser.on("-X", "--xml", "Dump as XML") do |v|
|
46
|
+
opts[:xml] = v
|
47
|
+
end
|
48
|
+
|
49
|
+
parser.on("-h", "--help", "Display this help message") do |v|
|
50
|
+
puts parser
|
51
|
+
exit
|
52
|
+
end
|
53
|
+
|
54
|
+
parser.on("-v", "--version", "Display version") do |v|
|
55
|
+
puts AutomateIt::VERSION
|
56
|
+
exit 0
|
57
|
+
end
|
58
|
+
|
59
|
+
args = parser.parse!.dup
|
60
|
+
|
61
|
+
# Clear ARGV so that IRB doesn't try to parse our options
|
62
|
+
opts[:args] = args
|
63
|
+
ARGV.clear
|
64
|
+
|
65
|
+
query = args.first unless args.empty?
|
66
|
+
|
67
|
+
interpreter = AutomateIt.new(:project => opts[:project])
|
68
|
+
result = interpreter.lookup(query)
|
69
|
+
if result.nil?
|
70
|
+
puts result.inspect
|
71
|
+
exit 1
|
72
|
+
elsif opts[:yaml]
|
73
|
+
puts result.to_yaml
|
74
|
+
elsif opts[:xml]
|
75
|
+
require 'active_support/core_ext/hash'
|
76
|
+
require 'active_support/core_ext/array'
|
77
|
+
puts result.to_xml
|
78
|
+
else
|
79
|
+
puts result.is_a?(String) ? result : result.inspect
|
80
|
+
end
|
81
|
+
exit 0
|
82
|
+
end
|
data/bin/aitag
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# XXX What can go wrong with this loading approach?
|
4
|
+
libdir = File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
5
|
+
if File.directory?(libdir) and File.exists?(File.join(libdir, "automateit.rb"))
|
6
|
+
$LOAD_PATH.unshift(libdir)
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'rubygems'
|
10
|
+
require 'optparse'
|
11
|
+
require 'automateit'
|
12
|
+
|
13
|
+
OptionParser.new do |parser|
|
14
|
+
PROG = File.basename($0)
|
15
|
+
opts = {}
|
16
|
+
parser.banner = <<EOB
|
17
|
+
#{PROG} - tool for querying AutomateIt tags
|
18
|
+
|
19
|
+
Usage: #{PROG} [options] [arguments...]
|
20
|
+
|
21
|
+
Examples:
|
22
|
+
# Load 'myproject' and see if it's tagged with 'apache' or 'svn':
|
23
|
+
#{PROG} -p myproject 'apache || svn'
|
24
|
+
echo $?
|
25
|
+
|
26
|
+
# Same but using environmental variable to specify project:
|
27
|
+
AUTOMATEIT_PROJECT=myproject
|
28
|
+
#{PROG} 'apache || svn'
|
29
|
+
echo $?
|
30
|
+
|
31
|
+
# Dump the results of a query as YAML
|
32
|
+
#{PROG} -Y myapp#user
|
33
|
+
|
34
|
+
# Dump the results of a query as XML
|
35
|
+
#{PROG} -X myapp#user
|
36
|
+
|
37
|
+
Options:
|
38
|
+
EOB
|
39
|
+
parser.on("-s", "--tags", "List tags for this host") do |v|
|
40
|
+
opts[:tags] = v
|
41
|
+
end
|
42
|
+
|
43
|
+
parser.on("-f", "--tags_for HOST", "List tags for a specific host") do |v|
|
44
|
+
opts[:tags_for] = v
|
45
|
+
end
|
46
|
+
|
47
|
+
parser.on("-t", "--tagged? QUERY", "Is this host tagged with the query?") do |v|
|
48
|
+
opts[:tagged?] = v
|
49
|
+
end
|
50
|
+
|
51
|
+
parser.on("-w", "--hosts_tagged_with QUERY", "List hosts tagged with query") do |v|
|
52
|
+
opts[:hosts_tagged_with] = v
|
53
|
+
end
|
54
|
+
|
55
|
+
parser.on("-p", "--project PATH", "Set project path") do |v|
|
56
|
+
opts[:project] = v
|
57
|
+
end
|
58
|
+
|
59
|
+
parser.on("-Y", "--yaml", "Dump as YAML") do |v|
|
60
|
+
opts[:yaml] = v
|
61
|
+
end
|
62
|
+
|
63
|
+
parser.on("-X", "--xml", "Dump as XML") do |v|
|
64
|
+
opts[:xml] = v
|
65
|
+
end
|
66
|
+
|
67
|
+
parser.on("-h", "--help", "Display this help message") do |v|
|
68
|
+
puts parser
|
69
|
+
exit
|
70
|
+
end
|
71
|
+
|
72
|
+
parser.on("-v", "--version", "Display version") do |v|
|
73
|
+
puts AutomateIt::VERSION
|
74
|
+
exit 0
|
75
|
+
end
|
76
|
+
|
77
|
+
args = parser.parse!.dup
|
78
|
+
|
79
|
+
# Clear ARGV so that IRB doesn't try to parse our options
|
80
|
+
opts[:args] = args
|
81
|
+
ARGV.clear
|
82
|
+
|
83
|
+
interpreter = AutomateIt.new(:project => opts[:project])
|
84
|
+
result = nil
|
85
|
+
|
86
|
+
unless opts[:tags] or opts[:tags_for] or opts[:tagged?] or opts[:hosts_tagged_with]
|
87
|
+
if args.first
|
88
|
+
opts[:tagged?] = args.first
|
89
|
+
else
|
90
|
+
puts parser
|
91
|
+
puts "\nERROR: insufficient arguments"
|
92
|
+
exit 1
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
result = \
|
97
|
+
if opts[:tags]
|
98
|
+
interpreter.tags
|
99
|
+
elsif opts[:tags_for]
|
100
|
+
interpreter.tags_for(opts[:tags_for])
|
101
|
+
elsif opts[:tagged?]
|
102
|
+
exit(interpreter.tagged?(opts[:tagged?]) ? 0 : 1)
|
103
|
+
elsif opts[:hosts_tagged_with]
|
104
|
+
interpreter.hosts_tagged_with(opts[:hosts_tagged_with])
|
105
|
+
end
|
106
|
+
|
107
|
+
puts(
|
108
|
+
if result.nil?
|
109
|
+
result.inspect
|
110
|
+
elsif opts[:yaml]
|
111
|
+
result.to_yaml
|
112
|
+
elsif opts[:xml]
|
113
|
+
require 'active_support/core_ext/hash'
|
114
|
+
require 'active_support/core_ext/array'
|
115
|
+
result.to_xml
|
116
|
+
else
|
117
|
+
case result
|
118
|
+
when String: result
|
119
|
+
when Set: result.sort.to_a.join(' ')
|
120
|
+
when Array: result.sort.join(' ')
|
121
|
+
else result.inspect
|
122
|
+
end
|
123
|
+
end
|
124
|
+
)
|
125
|
+
|
126
|
+
exit 0
|
127
|
+
end
|
128
|
+
|
data/bin/automateit
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# XXX What can go wrong with this loading approach?
|
4
|
+
libdir = File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
5
|
+
if File.directory?(libdir) and File.exists?(File.join(libdir, "automateit.rb"))
|
6
|
+
$LOAD_PATH.unshift(libdir)
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'rubygems'
|
10
|
+
require 'logger'
|
11
|
+
require 'optparse'
|
12
|
+
require 'automateit'
|
13
|
+
|
14
|
+
include AutomateIt::Constants
|
15
|
+
|
16
|
+
OptionParser.new do |parser|
|
17
|
+
PROG = File.basename($0)
|
18
|
+
opts = {}
|
19
|
+
parser.banner = <<EOB
|
20
|
+
#{PROG} - tool for automating the setup and maintenance of servers
|
21
|
+
|
22
|
+
Usage: #{PROG} [options] [recipe]
|
23
|
+
|
24
|
+
Examples:
|
25
|
+
# Start an interactive shell session
|
26
|
+
#{PROG}
|
27
|
+
|
28
|
+
# Execute a recipe
|
29
|
+
#{PROG} myrecipe.rb
|
30
|
+
|
31
|
+
# Preview the commands a recipe will run without running them
|
32
|
+
#{PROG} -n myrecipe.rb
|
33
|
+
|
34
|
+
# Eval a string
|
35
|
+
#{PROG} -e "puts tags.to_a.inspect"
|
36
|
+
|
37
|
+
Options:
|
38
|
+
EOB
|
39
|
+
parser.on("-c", "--create PATH", "Create project at path") do |v|
|
40
|
+
opts[:create] = v
|
41
|
+
end
|
42
|
+
|
43
|
+
parser.on("-p", "--project PATH", "Set project path") do |v|
|
44
|
+
opts[:project] = v
|
45
|
+
end
|
46
|
+
|
47
|
+
parser.on("-n", "--preview", "Preview without executing commands") do |v|
|
48
|
+
opts[:preview] = v
|
49
|
+
end
|
50
|
+
|
51
|
+
parser.on("-e", "--eval STRING", "Evaluate string") do |v|
|
52
|
+
opts[:eval] = v
|
53
|
+
end
|
54
|
+
|
55
|
+
parser.on("-q", "--quiet", "Print only errors") do |v|
|
56
|
+
opts[:verbosity] = Logger::ERROR
|
57
|
+
end
|
58
|
+
|
59
|
+
parser.on("-d", "--debug", "Print debugging information") do |v|
|
60
|
+
opts[:verbosity] = Logger::DEBUG
|
61
|
+
end
|
62
|
+
|
63
|
+
parser.on("-T", "--trace", "Display raw exception traces") do |v|
|
64
|
+
opts[:friendly_exceptions] = ! v
|
65
|
+
end
|
66
|
+
|
67
|
+
parser.on("-h", "--help", "Display this help message") do |v|
|
68
|
+
puts parser
|
69
|
+
exit
|
70
|
+
end
|
71
|
+
|
72
|
+
parser.on("-v", "--version", "Display version") do |v|
|
73
|
+
puts AutomateIt::VERSION
|
74
|
+
exit 0
|
75
|
+
end
|
76
|
+
|
77
|
+
args = parser.parse!.dup
|
78
|
+
|
79
|
+
# Clear ARGV so that IRB doesn't try to parse our options
|
80
|
+
opts[:args] = args
|
81
|
+
ARGV.clear
|
82
|
+
|
83
|
+
opts[:recipe] = args.first unless args.empty?
|
84
|
+
|
85
|
+
# Save vars because +run+ will delete opts
|
86
|
+
argscopy = args.clone
|
87
|
+
optscopy = opts.clone
|
88
|
+
|
89
|
+
begin
|
90
|
+
rv = AutomateIt::CLI.run(opts)
|
91
|
+
rescue Exception => e
|
92
|
+
msg = nil
|
93
|
+
if opts[:friendly_exceptions] != false and e.is_a?(AutomateIt::Error)
|
94
|
+
# Friendly message
|
95
|
+
msg = PERROR+e.message
|
96
|
+
msg << "\n\n"+PNOTE+"Use 'automateit --trace' to see complete backtrace"
|
97
|
+
else
|
98
|
+
# Raw backtrace
|
99
|
+
puts PERROR+"AutomateIt error trace:"
|
100
|
+
stack = e.backtrace.clone
|
101
|
+
msg = "#{stack.shift}: #{e.message} (#{e.exception.class})}";
|
102
|
+
for line in stack
|
103
|
+
msg << "\n "+line
|
104
|
+
end
|
105
|
+
end
|
106
|
+
puts msg
|
107
|
+
exit 1
|
108
|
+
rescue SysExit => e
|
109
|
+
# Don't display errors when exit gets called
|
110
|
+
end
|
111
|
+
if optscopy[:create] or optscopy[:eval] or argscopy.size > 0
|
112
|
+
exit rv ? 0 :1
|
113
|
+
else
|
114
|
+
# CTRL-D ends the line prematurely, so add a newline
|
115
|
+
puts
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
== User-friendly error messages
|
2
|
+
|
3
|
+
AutomateIt provides user-friendly error messages that make it easier to fix
|
4
|
+
problems in recipes and templates. These pinpoint the cause and show code
|
5
|
+
snippets.
|
6
|
+
|
7
|
+
For example, one of the sample recipes is executed -- but there's a problem and
|
8
|
+
the output is shown below.
|
9
|
+
|
10
|
+
The message is telling us the error happened in the
|
11
|
+
'examples/basic/recipes/install.rb' recipe at line 47. The first snippet shows
|
12
|
+
the end of a failed TemplateManager +render+ call.
|
13
|
+
|
14
|
+
In the second code snippet, we see there was a problem with the ERB template
|
15
|
+
'dist/myapp_server.erb'. This template failed at line 5 because it couldn't
|
16
|
+
find a variable called +pat+.
|
17
|
+
|
18
|
+
With the help of the second snippet, we quickly see that there's a typo -- that
|
19
|
+
bad variable should have been +path+. Problem solved!
|
20
|
+
|
21
|
+
root@kagami> automateit -n examples/basic/recipes/install.rb
|
22
|
+
!! Problem with recipe 'examples/basic/recipes/install.rb' at line 47
|
23
|
+
|
24
|
+
41 :to => "/etc/init.d/myapp_server",
|
25
|
+
42 :mode => 0555,
|
26
|
+
43 :locals => {
|
27
|
+
44 :path => lookup(:path),
|
28
|
+
45 :user => lookup(:user),
|
29
|
+
46 :port => lookup(:port),
|
30
|
+
* 47 }
|
31
|
+
48 )
|
32
|
+
49
|
33
|
+
|
34
|
+
(NestedError) Problem with template 'dist/myapp_server.erb' at line 5:
|
35
|
+
|
36
|
+
1 #!/usr/bin/env ruby
|
37
|
+
2
|
38
|
+
3 user = "<%=user%>"
|
39
|
+
4 port = "<%=port%>"
|
40
|
+
* 5 path = "<%=pat%>"
|
41
|
+
6 pid = "mongrel.pid"
|
42
|
+
7
|
43
|
+
|
44
|
+
(NameError) undefined local variable or method `pat' for #<AutomateIt::TemplateManager::ERB:0xb78a4e8c>
|
45
|
+
/home/igal/workspace/automateit/app/lib/helpful_erb.rb:60:in `result'
|
46
|
+
/home/igal/workspace/automateit/app/lib/automateit/template_manager/erb.rb:105:in `render'
|
47
|
+
(eval):2:in `render'
|
48
|
+
examples/basic/recipes/install.rb:47:in `invoke'
|
49
|
+
|
50
|
+
=> Use 'automateit --trace' to see complete backtrace
|
data/docs/previews.txt
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
== Previews
|
2
|
+
|
3
|
+
AutomateIt provides a way to preview commands without actually running them.
|
4
|
+
Read the TUTORIAL.txt[link:files/TUTORIAL_txt.html] to learn the basic previewing concepts and commands.
|
5
|
+
|
6
|
+
=== WARNING: Previewing code can be dangerous!
|
7
|
+
|
8
|
+
AutomateIt only provides logic for previewing its own commands. Recipe authors
|
9
|
+
are responsible for providing previewing logic for their own custom code.
|
10
|
+
|
11
|
+
Here's what *not* to do with previews:
|
12
|
+
|
13
|
+
puts "Hello!"
|
14
|
+
|
15
|
+
The above +puts+ method will execute in both preview and non-preview modes.
|
16
|
+
To execute custom code only in a specific mode, wrap it with conditionals.
|
17
|
+
|
18
|
+
For example:
|
19
|
+
|
20
|
+
if preview?
|
21
|
+
puts "This is a preview"
|
22
|
+
end
|
23
|
+
|
24
|
+
preview_for("PREVIEW: Will run custom commands") do
|
25
|
+
puts "Custom commands"
|
26
|
+
end
|
27
|
+
|
28
|
+
When in preview mode, the above recipe will display:
|
29
|
+
|
30
|
+
This is a preview
|
31
|
+
=> PREVIEW: Will run custom commands
|
32
|
+
|
33
|
+
When run normally without preview mode:
|
34
|
+
|
35
|
+
Custom commands
|
36
|
+
|
37
|
+
Therefore, wrap all non-AutomateIt commands (e.g. +system+) that shouldn't be
|
38
|
+
executed during the preview with conditionals.
|
39
|
+
|
40
|
+
=== WARNING: Changing directories during preview can be dangerous!
|
41
|
+
|
42
|
+
AutomateIt will only *pretend* to make directories in preview mode. In
|
43
|
+
preview mode, it will also only *pretend* to change into non-existent
|
44
|
+
directories when using commands like #cd, #mkdir and #mktempdircd.
|
45
|
+
|
46
|
+
This can be *disastrous* if you're executing non-AutomateIt commands (e.g.
|
47
|
+
+system+) that use *relative* *paths* and expect to be run inside the
|
48
|
+
newly-created temporary directory because the +chdir+ didn't actually happen.
|
49
|
+
|
50
|
+
For example:
|
51
|
+
|
52
|
+
# DON'T EVER DO THIS!!!
|
53
|
+
mkdir_p "/tmp/foo/bar" do
|
54
|
+
system "echo 'I'm going to do: rm -rf *'"
|
55
|
+
end
|
56
|
+
|
57
|
+
If that directory didn't already exist, then running the above code in
|
58
|
+
preview mode would cause the +system+ command to actually run! If that wasn't
|
59
|
+
an +echo+ command, it would have deleted the contents of your *current*
|
60
|
+
directory -- not the <tt>/tmp/foo/bar</tt> directory -- because that
|
61
|
+
directory wasn't actually created due to the preview mode!
|
62
|
+
|
63
|
+
The correct way to write the above example is:
|
64
|
+
|
65
|
+
mkdir_p "/tmp/foo/bar" do
|
66
|
+
preview_for("PREVIEW: Deleting all files in directory /tmp/foo/bar") do
|
67
|
+
system "echo 'I'm going to do: rm -rf *'"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
The Interpreter#preview_for method provides conditional execution of blocks.
|
72
|
+
When running in preview mode, it will display the supplied message and not
|
73
|
+
execute the block containing the +system+ command:
|
74
|
+
|
75
|
+
=> PREVIEW: Deleting all files in directory /tmp/foo/bar
|
76
|
+
|
77
|
+
When running without preview mode, the method will not display the message
|
78
|
+
but will call block, generating the following output:
|
79
|
+
|
80
|
+
** echo 'I'm going to do: rm -rf *'"
|
81
|
+
I'm going to do: rm -rf *
|
82
|
+
|
83
|
+
=== Conclusion
|
84
|
+
|
85
|
+
Keeping the preview issues in mind and wrapping custom code with conditionals
|
86
|
+
will help you write code that can be safely previewed.
|