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,14 @@
1
+ # See AutomateIt::Interpreter for usage information.
2
+ module AutomateIt # :nodoc:
3
+ # Instantiates a new Interpreter. See documentation for
4
+ # Interpreter#setup.
5
+ def self.new(opts={})
6
+ Interpreter.new(opts)
7
+ end
8
+
9
+ # Invokes an Interpreter on the recipe. See documentation for
10
+ # Interpreter::invoke.
11
+ def self.invoke(recipe, opts={})
12
+ Interpreter.invoke(recipe, opts)
13
+ end
14
+ end
@@ -0,0 +1,79 @@
1
+ # == ServiceManager
2
+ #
3
+ # ServiceManager provides a way of managing services, such starting and
4
+ # stopping Unix daemons.
5
+ class AutomateIt::ServiceManager < AutomateIt::Plugin::Manager
6
+ # Is this +service+ started?
7
+ #
8
+ # Options:
9
+ # * :wait -- Maximum number of seconds to wait until service starts. Useful
10
+ # when a service accepts a #start and returns immediately before the service
11
+ # has finished starting.
12
+ def started?(service, opts={}) dispatch(service, opts) end
13
+
14
+ # Is this +service+ stopped?
15
+ #
16
+ # Options:
17
+ # * :wait -- Maximum number of seconds to wait until service stops. Useful
18
+ # when a service accepts a #stop and returns immediately while the service
19
+ # continues running for a few seconds.
20
+ def stopped?(service, opts={}) dispatch(service, opts) end
21
+
22
+ # Alias for #started?
23
+ def running?(service, opts={}) dispatch_to(:started?, service, opts) end
24
+
25
+ # Start this +service+ if it's not running.
26
+ def start(service, opts={}) dispatch(service, opts) end
27
+
28
+ # Stop this +service+ if it's running.
29
+ def stop(service, opts={}) dispatch(service, opts) end
30
+
31
+ # Restart this +service+ if it's running, or start it if it's stopped.
32
+ def restart(service, opts={}) dispatch(service, opts) end
33
+
34
+ # If +is_restart+, #restart the service, otherwise #start it.
35
+ #
36
+ # Example:
37
+ # modified = edit "/etc/myapp.conf" {#...}
38
+ # service_manager.start_or_restart("myapp", modified)
39
+ def start_or_restart(service, is_restart, opts={}) dispatch(service, is_restart, opts) end
40
+
41
+ # Start and enable the service using #start and #enable.
42
+ def start_and_enable(service, opts={}) dispatch(service, opts) end
43
+
44
+ # Tell the +service+ to take a specific +action+, e.g., "condrestart".
45
+ def tell(service, action, opts={}) dispatch(service, action, opts={}) end
46
+
47
+ # Will this +service+ start when the computer is rebooted?
48
+ def enabled?(service) dispatch(service) end
49
+
50
+ # Make this +service+ start when the computer is rebooted, but only if it's
51
+ # not already enabled.
52
+ def enable(service, opts={}) dispatch(service, opts) end
53
+
54
+ # Don't make this +service+ start when the computer is rebooted, but only
55
+ # if it's already enabled.
56
+ def disable(service, opts={}) dispatch(service, opts) end
57
+ end
58
+
59
+ # == ServiceManager::BaseDriver
60
+ #
61
+ # Base class for all ServiceManager drivers.
62
+ class AutomateIt::ServiceManager::BaseDriver < AutomateIt::Plugin::Driver
63
+ # See ServiceManager#start_or_restart
64
+ def start_or_restart(service, is_restart, opts={})
65
+ send(is_restart ? :restart : :start, service, opts)
66
+ end
67
+
68
+ # See ServiceManager#start_and_enable
69
+ def start_and_enable(service, opts={})
70
+ start(service, opts)
71
+ enable(service, opts)
72
+ end
73
+ end
74
+
75
+ # Drivers
76
+ require 'automateit/service_manager/sysv'
77
+ require 'automateit/service_manager/update_rcd'
78
+ require 'automateit/service_manager/chkconfig'
79
+ require 'automateit/service_manager/rc_update'
@@ -0,0 +1,39 @@
1
+ # == ServiceManager::Chkconfig
2
+ #
3
+ # The Chkconfig driver implements the ServiceManager methods for #enabled?,
4
+ # #enable and #disable on RedHat-like platforms. It uses the SYSV driver
5
+ # for handling the methods #running?, #start and #stop.
6
+ class AutomateIt::ServiceManager::Chkconfig < AutomateIt::ServiceManager::SYSV
7
+ depends_on :programs => %w(chkconfig)
8
+
9
+ def suitability(method, *args) # :nodoc:
10
+ return available? ? 2 : 0
11
+ end
12
+
13
+ # See ServiceManager#enabled?
14
+ def enabled?(service)
15
+ _raise_unless_available
16
+ # "chkconfig --list service" may produce output like the below:
17
+ # service httpd supports chkconfig, but is not referenced in any runlevel (run 'chkconfig --add automateit_service_sysv_test')
18
+ # => httpd 0:off 1:off 2:off 3:off 4:off 5:off 6:off
19
+ if matcher = `chkconfig --list #{service} < /dev/null 2>&1` \
20
+ .match(/^(#{service}).+?(\d+:(on|off).+?)$/)
21
+ return true if matcher[2].match(/\b\d+:on\b/)
22
+ end
23
+ return false
24
+ end
25
+
26
+ # See ServiceManager#enable
27
+ def enable(service, opts={})
28
+ _raise_unless_available
29
+ return false if enabled?(service)
30
+ interpreter.sh("chkconfig --add #{service}")
31
+ end
32
+
33
+ # See ServiceManager#disable
34
+ def disable(service, opts={})
35
+ _raise_unless_available
36
+ return false unless enabled?(service)
37
+ interpreter.sh("chkconfig --del #{service}")
38
+ end
39
+ end
@@ -0,0 +1,37 @@
1
+ # == ServiceManager::RC_Update
2
+ #
3
+ # RC_Update implements the #enabled?, #enable and #disable features of the
4
+ # ServiceManager on Gentoo-like systems.
5
+ class AutomateIt::ServiceManager::RC_Update < AutomateIt::ServiceManager::SYSV
6
+ depends_on :programs => %w(rc-update)
7
+
8
+ def suitability(method, *args) # :nodoc:
9
+ return available? ? 2 : 0
10
+ end
11
+
12
+ # See ServiceManager#enabled?
13
+ def enabled?(service)
14
+ _raise_unless_available
15
+ # Do NOT use Gentoo's rc-update because the idiot that wrote that utility
16
+ # truncates service names to look "prettier" and provides no way to disable
17
+ # this annoyance for people that need to query services by name.
18
+ result = %w(boot default).select do |runlevel|
19
+ File.exists?(File.join("/etc/runlevels", runlevel, service))
20
+ end
21
+ return ! result.empty?
22
+ end
23
+
24
+ # See ServiceManager#enable
25
+ def enable(service, opts={})
26
+ _raise_unless_available
27
+ return false if enabled?(service)
28
+ interpreter.sh("rc-update add #{service} default > /dev/null 2>&1")
29
+ end
30
+
31
+ # See ServiceManager#disable
32
+ def disable(service, opts={})
33
+ _raise_unless_available
34
+ return false unless enabled?(service)
35
+ interpreter.sh("rc-update del #{service} default > /dev/null 2>&1")
36
+ end
37
+ end
@@ -0,0 +1,126 @@
1
+ # == ServiceManager::SYSV
2
+ #
3
+ # The SYSV driver implements the ServiceManager methods for #running?,
4
+ # #start and #stop on Unix-like platforms that use the System V init
5
+ # process using a <tt>/etc/init.d</tt> directory.
6
+ #
7
+ # It also implements a basic #enabled? method that's very fast but may not
8
+ # work correctly on all SysV platforms. This method should be overridden by
9
+ # more specific drivers when reasonable.
10
+ #
11
+ # It does not implement the #enable and #disable methods because these are
12
+ # not standardized and must be implemented using platform-specific drivers,
13
+ # e.g., Chkconfig on RedHat-like platforms.
14
+ class AutomateIt::ServiceManager::SYSV < AutomateIt::ServiceManager::BaseDriver
15
+ ETC_INITD = "/etc/init.d"
16
+
17
+ depends_on :directories => [ETC_INITD]
18
+
19
+ def suitability(method, *args) # :nodoc:
20
+ return 0 if %w(enabled? enable disable).include?(method.to_s)
21
+ return available? ? 1 : 0
22
+ end
23
+
24
+ def _run_command(args, opts={})
25
+ _raise_unless_available
26
+ cmd = String === args ? args : args.join(' ')
27
+ if opts[:silent] or opts[:check]
28
+ cmd += " > /dev/null 2>&1" # Discard STDOUT and STDERR
29
+ elsif opts[:quiet]
30
+ cmd += " > /dev/null" # Discard only STDOUT
31
+ end
32
+
33
+ level = (opts[:quiet] || opts[:silent] || opts[:check]) ? :debug : :info
34
+ log.send(level, PEXEC+cmd)
35
+ if writing? or opts[:check]
36
+ system(cmd)
37
+ return $?.exitstatus.zero?
38
+ else
39
+ false
40
+ end
41
+ end
42
+ private :_run_command
43
+
44
+ # See ServiceManager#tell
45
+ def tell(service, action, opts={})
46
+ return _run_command(["#{ETC_INITD}/#{service}", action.to_s], opts)
47
+ end
48
+
49
+ # See ServiceManager#running?
50
+ def running?(service, opts={})
51
+ return started?(service, opts)
52
+ end
53
+
54
+ def _started_and_stopped_helper(kind, service, opts={})
55
+ expected = \
56
+ case kind
57
+ when :started?: true
58
+ when :stopped?: false
59
+ else raise ArgumentError.new("unknown kind argument: #{kind}")
60
+ end
61
+
62
+ result = tell(service, :status, :check => true)
63
+ ### puts "k %s r %s e %s" % [kind, result, expected]
64
+ return result if expected == result
65
+ if opts[:wait]
66
+ timeout = Time.now + opts[:wait]
67
+ while timeout > Time.now
68
+ log.info(PNOTE+" ServiceManager#%s waiting on '%s' for %0.1f more seconds" %
69
+ [kind, service, timeout - Time.now])
70
+ sleep 0.5
71
+ result = tell(service, :status, :check => true)
72
+ break if expected == result
73
+ end
74
+ log.info(PNOTE+" ServiceManager#%s finished waiting for '%s', got: %s" %
75
+ [kind, service, result])
76
+ end
77
+ return result
78
+ end
79
+
80
+ # See ServiceManager#started?
81
+ def started?(service, opts={})
82
+ return _started_and_stopped_helper(:started?, service, opts)
83
+ end
84
+
85
+ # See ServiceManager#stopped?
86
+ def stopped?(service, opts={})
87
+ return ! _started_and_stopped_helper(:stopped?, service, opts)
88
+ end
89
+
90
+ # See ServiceManager#start
91
+ def start(service, opts={})
92
+ # TODO maybe add a :wait option?
93
+ if started?(service) and not opts[:force]
94
+ # Already started
95
+ return false
96
+ else
97
+ # Needs starting or forced
98
+ tell(service, :start, opts)
99
+ return true
100
+ end
101
+ end
102
+
103
+ # See ServiceManager#stop
104
+ def stop(service, opts={})
105
+ # TODO maybe add a :wait option?
106
+ if stopped?(service) and not opts[:force]
107
+ # Already stopped
108
+ return false
109
+ else
110
+ # Needs stopping or forced
111
+ tell(service, :stop, opts)
112
+ return true
113
+ end
114
+ end
115
+
116
+ # See ServiceManager#restart
117
+ def restart(service, opts={})
118
+ stop(service, opts) if running?(service)
119
+ return start(service, opts)
120
+ end
121
+
122
+ # See ServiceManager#enabled?
123
+ def enabled?(service)
124
+ return ! Dir["/etc/rc*.d/*"].grep(/\/S\d{2}#{service}$/).empty?
125
+ end
126
+ end
@@ -0,0 +1,35 @@
1
+ # == ServiceManager::UpdateRCD
2
+ #
3
+ # The UpdateRCD driver implements the ServiceManager methods for #enabled?,
4
+ # #enable and #disable on Debian-like platforms. It uses the SYSV driver
5
+ # for handling the methods #running?, #start and #stop.
6
+ class AutomateIt::ServiceManager::UpdateRCD < AutomateIt::ServiceManager::SYSV
7
+ TOOL = "update-rc.d"
8
+
9
+ depends_on :programs => [TOOL]
10
+
11
+ def suitability(method, *args) # :nodoc:
12
+ return available? ? 3 : 0
13
+ end
14
+
15
+ # See ServiceManager#enable
16
+ def enable(service, opts={})
17
+ _raise_unless_available
18
+ return false if enabled?(service)
19
+ interpreter.sh("#{TOOL} #{service} defaults < /dev/null > /dev/null")
20
+ end
21
+
22
+ # See ServiceManager#disable
23
+ def disable(service, opts={})
24
+ _raise_unless_available
25
+ return false unless enabled?(service)
26
+ interpreter.sh("#{TOOL} -f #{service} remove < /dev/null > /dev/null")
27
+ end
28
+
29
+ def enabled?(service, opts={})
30
+ _raise_unless_available
31
+ cmd = "#{TOOL} -n -f #{service} remove < /dev/null"
32
+ output = `#{cmd}`
33
+ return ! output.match(/etc\/rc[\dS].d|Nothing to do\./).nil?
34
+ end
35
+ end
@@ -0,0 +1,261 @@
1
+ # == ShellManager
2
+ #
3
+ # The ShellManager provides Unix-like shell commands for manipulating files and
4
+ # executing commands.
5
+ #
6
+ # *WARNING*: Previewing code can be dangerous. Read
7
+ # previews.txt[link:files/docs/previews_txt.html] for instructions on how to
8
+ # write code that can be safely previewed.
9
+ class AutomateIt::ShellManager < AutomateIt::Plugin::Manager
10
+ alias_methods :sh, :which, :which!, :mktemp, :mktempdir, :mktempdircd, :chperm, :umask
11
+ alias_methods :cd, :pwd, :mkdir, :mkdir_p, :rmdir, :ln, :ln_s, :ln_sf, :cp, :cp_r, :cp_R, :mv, :rm, :rm_r, :rm_rf, :install, :chmod, :chmod_R, :chown, :chown_R, :touch
12
+
13
+ #...[ Detection commands ]..............................................
14
+
15
+ # See ShellManager#provides_mode?
16
+ def provides_mode?() dispatch_safely end
17
+
18
+ # See ShellManager#provides_mode?
19
+ def provides_ownership?() dispatch_safely end
20
+
21
+ # See ShellManager#provides_mode?
22
+ def provides_symlink?() dispatch_safely end
23
+
24
+ # See ShellManager#provides_mode?
25
+ def provides_link?() dispatch_safely end
26
+
27
+ #...[ Custom commands ].................................................
28
+
29
+ # Execute a shell command.
30
+ def sh(*commands) dispatch(*commands) end
31
+
32
+ # What is the path for this command? Returns +nil+ if command isn't found.
33
+ #
34
+ # Example:
35
+ # which("ls") # => "/bin/ls"
36
+ def which(command) dispatch(command) end
37
+
38
+ # Same as #which but throws an ArgumentError if command isn't found.
39
+ def which!(command) dispatch(command) end
40
+
41
+ # Creates a temporary file. Optionally takes a +name+ argument which is
42
+ # purely cosmetic, e.g., if the +name+ is "foo", the routine may create a
43
+ # temporary file named <tt>/tmp/foo_qeKo7nJk1s</tt>.
44
+ #
45
+ # When called with a block, invokes the block with the path of the temporary
46
+ # file and deletes the file at the end of the block.
47
+ #
48
+ # Without a block, returns the path of the temporary file and you're
49
+ # responsible for removing it when done.
50
+ def mktemp(name=nil, &block) # :yields: path
51
+ dispatch(name, &block)
52
+ end
53
+
54
+ # Creates a temporary directory. See #mktemp for details on the +name+
55
+ # argument.
56
+ #
57
+ # When called with a block, invokes the block with the path of the
58
+ # temporary directory and recursively deletes the directory and its
59
+ # contents at the end of the block.
60
+ #
61
+ # Without a block, returns the path of the temporary directory and you're
62
+ # responsible for removing it when done.
63
+ #
64
+ # CAUTION: Read notes at the top of ShellManager for potentially
65
+ # problematic situations that may be encountered if using this command in
66
+ # preview mode!
67
+ def mktempdir(name=nil, &block) # :yields: path
68
+ dispatch(name, &block)
69
+ end
70
+
71
+ # Same as #mktempdir but performs a #cd into the directory for the duration
72
+ # of the block.
73
+ #
74
+ # Example:
75
+ #
76
+ # puts pwd # => "/home/bubba"
77
+ # mktempdircd do |path|
78
+ # puts path # => "/tmp/tempster_qeKo7nJk1s"
79
+ # puts pwd # => "/tmp/tempster_qeKo7nJk1s"
80
+ # end
81
+ # puts File.exists?("/tmp/tempster_qeKo7nJk1s") # => false
82
+ def mktempdircd(name=nil, &block) # :yields: path
83
+ dispatch(name, &block)
84
+ end
85
+
86
+ # Change the permissions of the +targets+. This command is like the #chmod
87
+ # and #chown in a single command.
88
+ #
89
+ # Options:
90
+ # * :recursive -- Change files and directories recursively. Defaults to false.
91
+ # * :user -- User name to change ownership to.
92
+ # * :group -- Group name to change ownership to.
93
+ # * :mode -- Mode to use as octal, e.g., <tt>0400</tt> to make a file
94
+ # readable only to its owner.
95
+ # * :details -- Reports the files modified, rather than the arguments
96
+ # modified. An argument might be a single directory, but this may result in
97
+ # modifications to many files within that directory. Use :details for
98
+ # situations when there's a need to see all files actually changed. The
99
+ # reason :details is off by default is that it will flood the screen with a
100
+ # list of all files modified in a large directory, which is overwhelming
101
+ # and probably unnecessary unless you actually need to see these details.
102
+ # Defaults to false.
103
+ def chperm(targets, opts={}) dispatch(targets, opts) end
104
+
105
+ # Set the umask to +mode+. If given a block, changes the umask only for the
106
+ # duration of the block and changes it back to its previous setting at the
107
+ # end.
108
+ def umask(mode=nil, &block) dispatch(mode, &block) end
109
+
110
+ #...[ FileUtils wrappers ]...............................................
111
+
112
+ # Changes the directory into the specified +dir+. If called with a block,
113
+ # changes to the directory for the duration of the block, and then changes
114
+ # back to the previous directory at the end.
115
+ #
116
+ # *WARNING*: Previewing code can be dangerous. Read
117
+ # previews.txt[link:files/docs/previews_txt.html] for instructions on how to
118
+ # write code that can be safely previewed.
119
+ def cd(dir, opts={}, &block) dispatch(dir, opts, &block) end
120
+
121
+ # Returns the current directory.
122
+ def pwd() dispatch() end
123
+
124
+ # Create a directory or directories. Returns an array of directories
125
+ # created or +false+ if all directories are already present.
126
+ #
127
+ # Options:
128
+ # * :parents -- Create parents, like "mkdir -p". Boolean.
129
+ # * :mode, :user, :group -- See #chperm
130
+ #
131
+ # *WARNING*: Previewing code can be dangerous. Read
132
+ # previews.txt[link:files/docs/previews_txt.html] for instructions on how to
133
+ # write code that can be safely previewed.
134
+ def mkdir(dirs, opts={}, &block) dispatch(dirs, &block) end
135
+
136
+ # Create a directory or directories with their parents. Returns an array of
137
+ # directories created or +false+ if all directories are already present.
138
+ #
139
+ # Options same as #mkdir.
140
+ #
141
+ # Example:
142
+ # File.exists?("/tmp/foo") # => false
143
+ # mkdir_p("/tmp/foo/bar")
144
+ # File.exists?("/tmp/foo") # => true
145
+ # File.exists?("/tmp/foo/bar") # => true
146
+ #
147
+ # *WARNING*: Previewing code can be dangerous. Read
148
+ # previews.txt[link:files/docs/previews_txt.html] for instructions on how to
149
+ # write code that can be safely previewed.
150
+ def mkdir_p(dirs, opts={}, &block) dispatch(dirs, &block) end
151
+
152
+ # Remove a directory or directories. The directories must be empty or an
153
+ # exception is thrown. Returns the directories removed or +false+ if none
154
+ # of the directories exist.
155
+ def rmdir(dirs) dispatch(dirs) end
156
+
157
+ # Create a hard link between the +source+ and +target+. Your platform must
158
+ # support hard links to use this. Returns the target created or +false+ if
159
+ # the link is already present.
160
+ def ln(source, target, opts={}) dispatch(source, target, opts) end
161
+
162
+ # Create a symbolic link between the +sources+ and +target+. Your platform
163
+ # must support symbolic links to use this. Returns an array of sources
164
+ # linked or +false+ if all are already present.
165
+ def ln_s(sources, target, opts={}) dispatch(sources, target, opts) end
166
+
167
+ # Create a symbolic link between the +sources+ and +target+. If the
168
+ # +target+ already exists, will remove it and recreate it. Your platform
169
+ # must support symbolic links to use this. Returns an array of sources
170
+ # linked or +false+ if all are already present.
171
+ def ln_sf(sources, target, opts={}) dispatch(sources, target, opts) end
172
+
173
+ # Copy the +sources+ to the +target+. Returns an array of sources copied or
174
+ # +false+ if all are present.
175
+ #
176
+ # Options:
177
+ # * :preserve -- preserve file modification time and ownership, boolean.
178
+ # * :recursive -- copy files and directories recursively, boolean.
179
+ def cp(sources, target, opts={}) dispatch(sources, target, opts) end
180
+
181
+ # Copy the +sources+ to the +target+ recursively. Returns an array of
182
+ # sources copied or +false+ if all are present.
183
+ def cp_r(sources, target, opts={}) dispatch(sources, target, opts) end
184
+
185
+ # Copy the +sources+ to the +target+ recursively. Returns an array of
186
+ # sources copied or +false+ if all are present.
187
+ def cp_R(sources, target, opts={}) dispatch(sources, target, opts) end
188
+
189
+ # Move the +sources+ to the +target+. Returns an array of sources copied or
190
+ # +false+ if none of the sources exist.
191
+ def mv(sources, target) dispatch(sources, target) end
192
+
193
+ # Remove the +targets+. Returns a list of targets removed or +false+ if
194
+ # none of them exist.
195
+ def rm(targets, opts={}) dispatch(targets, opts) end
196
+
197
+ # Remove the +targets+ recursively. Returns a list of targets removed or
198
+ # +false+ if none of them exist.
199
+ def rm_r(targets, opts={}) dispatch(targets, opts) end
200
+
201
+ # Remove the +targets+ recursively and forcefully. Returns a list of
202
+ # targets removed or +false+ if none of them exist.
203
+ def rm_rf(targets, opts={}) dispatch(targets, opts) end
204
+
205
+ # Copy the +source+ to the +target+ and set its +mode+. Returns true if the
206
+ # file was installed or +false+ if already present.
207
+ def install(source, target, mode) dispatch(source, target, mode) end
208
+
209
+ # Change the permission +mode+ of the +targets+. Returns an array of
210
+ # targets modified or +false+ if all have the desired mode.
211
+ def chmod(mode, targets, opts={}) dispatch(mode, targets, opts) end
212
+
213
+ # Change the permission +mode+ of the +targets+ recursively. Returns an
214
+ # array of targets modified or +false+ if all have the desired mode.
215
+ def chmod_R(mode, targets, opts={}) dispatch(mode, targets, opts) end
216
+
217
+ # Change the +user+ and +group+ ownership of the +targets+. You can leave
218
+ # either the user or group as nil if you don't want to change it. Returns
219
+ # an array of targets modified or +false+ if all have the desired
220
+ # ownership.
221
+ def chown(user, group, targets, opts={}) dispatch(user, group, targets, opts) end
222
+
223
+ # Change the +user+ and +group+ ownership of the +targets+ recursively. You
224
+ # can leave either the user or group as nil if you don't want to change it.
225
+ # Returns an array of targets modified or +false+ if all have the desired
226
+ # ownership.
227
+ def chown_R(user, group, targets, opts={}) dispatch(user, group, targets, opts) end
228
+
229
+ # Create the +targets+ as files if needed and update their modification
230
+ # time. Unlike most other commands provided by ShellManager, this one will
231
+ # always modify the targets. Returns an array of targets modified.
232
+ def touch(targets) dispatch(targets) end
233
+ end
234
+
235
+ # == ShellManager::BaseDriver
236
+ #
237
+ # Base class for all ShellManager drivers.
238
+ class AutomateIt::ShellManager::BaseDriver < AutomateIt::Plugin::Driver
239
+ def _replace_owner_with_user(opts)
240
+ value = opts.delete(:owner)
241
+ opts[:user] = value if value and not opts[:user]
242
+ return opts
243
+ end
244
+ protected :_replace_owner_with_user
245
+
246
+ # Returns hash of verbosity and preview settings for FileUtils commands.
247
+ def _fileutils_opts
248
+ opts = {}
249
+ opts[:verbose] = false # Generate our own log messages
250
+ opts[:noop] = true if preview?
251
+ return opts
252
+ end
253
+ private :_fileutils_opts
254
+ end
255
+
256
+ # Drivers
257
+ require 'automateit/shell_manager/portable'
258
+ require 'automateit/shell_manager/which'
259
+ require 'automateit/shell_manager/base_link'
260
+ require 'automateit/shell_manager/symlink'
261
+ require 'automateit/shell_manager/link'