automateit 0.70923 → 0.70928

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data.tar.gz.sig CHANGED
Binary file
@@ -1,3 +1,12 @@
1
+ 0.70928:
2
+ Date: Fri, 28 Sep 2007 23:18:37 -0700
3
+ Desc:
4
+ - (%) Fixed #cp, #ln and #install when called with relative path source and directory target. These tried to create items which included the relative path, rather than discarding it.
5
+ - (+) Added an "--add TAGS" feature to executables: automateit, aifield, aitag. This makes it easy to define tag(s) for a specific run.
6
+ - (+) Added #backup command to save copies of files, it's now used by default when using #edit to modify a file.
7
+ - (+) Added #download command to retrieve data via HTTP and FTP to a file or directory.
8
+ - Improved specs and provided coverage for more exception handling.
9
+
1
10
  0.70923:
2
11
  Date: Sun, 23 Sep 2007 16:01:03 -0700
3
12
  Desc:
data/Rakefile CHANGED
@@ -165,6 +165,11 @@ task :gem do
165
165
  hoe(:gem)
166
166
  end
167
167
 
168
+ task :publish do
169
+ automateit
170
+ hoe("release VERSION=#{AutomateIt::VERSION}")
171
+ end
172
+
168
173
  #---[ Install and uninstall ]-------------------------------------------
169
174
 
170
175
  =begin
@@ -184,12 +189,25 @@ namespace :install do
184
189
  puts automateit.package_manager.install({"automateit" => Dir["pkg/*.gem"].first}, :with => :gem, :docs => false)
185
190
  end
186
191
 
192
+ desc "Install Gem from RubyForge without docs, removing existing Gem first"
193
+ task :rf do
194
+ install_wrapper "http://gems.rubyforge.org"
195
+ end
196
+
187
197
  desc "Install Gem from website without docs, removing existing Gem first"
188
- task :remote do
198
+ task :site do
199
+ install_wrapper "http://automateit.org/pub", :source => "http://automateit.org/pub", :reset => true
200
+ end
201
+
202
+ # Options:
203
+ # * :url -- URL to clear
204
+ # * :opts -- Hash to pass to PackageManager#install
205
+ def install_wrapper(url, opts={})
189
206
  Rake::Task[:uninstall].invoke
190
- #sh "sudo gem install -y -r -s http://automateit.org/pub automateit --no-ri --no-rdoc"
191
- sh "gem sources -r http://automateit.org/pub" rescue nil
192
- automateit.package_manager.install("automateit", :source => "http://automateit.org/pub", :with => :gem, :docs => false)
207
+ sh "gem sources -r #{url}" rescue nil if opts.delete(:reset)
208
+ opts[:with] ||= :gem
209
+ opts[:docs] ||= false
210
+ automateit.package_manager.install("automateit", opts)
193
211
  end
194
212
  end
195
213
 
data/TODO.txt CHANGED
@@ -2,10 +2,8 @@ KEY: Important? Urgent? Easy? 1=yes, 0=no
2
2
 
3
3
  #===[ App ]=============================================================
4
4
 
5
- 101 Download -- Add OpenURI wrapper from gTag
6
5
  100 Shell -- Expand glob patterns, e.g. chown_R(500, 500, "*")
7
6
 
8
- 101 CLI -- Add tags via command-line
9
7
  100 Edit -- Display summary of edits, return with :details as [rv, list]
10
8
  100 Shell -- Incorporate which.cmd so #which can work on Windows
11
9
  100 Interpreter#invoke and HelpfulERB -- Extract error context code into class
@@ -128,6 +128,7 @@ AutomateIt uses an extensible plugin architecture to group together related comm
128
128
 
129
129
  * AutomateIt::AccountManager -- Manipulates users and groups.
130
130
  * AutomateIt::AddressManager -- Manipulates host's network addresses.
131
+ * AutomateIt::DownloadManager -- Downloads files.
131
132
  * AutomateIt::EditManager -- Edits files and strings.
132
133
  * AutomateIt::FieldManager -- Queries configuration variables.
133
134
  * AutomateIt::PackageManager -- Manipulates software packages.
@@ -46,9 +46,8 @@ EOB
46
46
  opts[:xml] = v
47
47
  end
48
48
 
49
- parser.on("-h", "--help", "Display this help message") do |v|
50
- puts parser
51
- exit
49
+ parser.on("-a", "--add TAGS", "Add list of space separated tags") do |v|
50
+ opts[:tags] = [v.split].flatten
52
51
  end
53
52
 
54
53
  parser.on("-v", "--version", "Display version") do |v|
@@ -56,6 +55,11 @@ EOB
56
55
  exit 0
57
56
  end
58
57
 
58
+ parser.on("-h", "--help", "Display this help message") do |v|
59
+ puts parser
60
+ exit
61
+ end
62
+
59
63
  args = parser.parse!.dup
60
64
 
61
65
  # Clear ARGV so that IRB doesn't try to parse our options
data/bin/aitag CHANGED
@@ -64,9 +64,8 @@ EOB
64
64
  opts[:xml] = v
65
65
  end
66
66
 
67
- parser.on("-h", "--help", "Display this help message") do |v|
68
- puts parser
69
- exit
67
+ parser.on("-a", "--add TAGS", "Add list of space separated tags") do |v|
68
+ opts[:tags] = [v.split].flatten
70
69
  end
71
70
 
72
71
  parser.on("-v", "--version", "Display version") do |v|
@@ -74,13 +73,21 @@ EOB
74
73
  exit 0
75
74
  end
76
75
 
76
+ parser.on("-h", "--help", "Display this help message") do |v|
77
+ puts parser
78
+ exit
79
+ end
80
+
77
81
  args = parser.parse!.dup
78
82
 
79
83
  # Clear ARGV so that IRB doesn't try to parse our options
80
84
  opts[:args] = args
81
85
  ARGV.clear
82
86
 
83
- interpreter = AutomateIt.new(:project => opts[:project])
87
+ interpreter = AutomateIt.new(
88
+ :project => opts[:project],
89
+ :tags => opts[:tags]
90
+ )
84
91
  result = nil
85
92
 
86
93
  unless opts[:tags] or opts[:tags_for] or opts[:tagged?] or opts[:hosts_tagged_with]
@@ -125,4 +132,3 @@ EOB
125
132
 
126
133
  exit 0
127
134
  end
128
-
@@ -33,6 +33,12 @@ Examples:
33
33
 
34
34
  # Eval a string
35
35
  #{PROG} -e "puts tags.to_a.inspect"
36
+
37
+ # Add a tag
38
+ #{PROG} -a mytag -e "puts tags.to_a.inspect"
39
+
40
+ # Add tags
41
+ #{PROG} -a 'mytag othertag' -e "puts tags.to_a.inspect"
36
42
 
37
43
  Options:
38
44
  EOB
@@ -52,6 +58,10 @@ EOB
52
58
  opts[:eval] = v
53
59
  end
54
60
 
61
+ parser.on("-a", "--add TAGS", "Add list of space separated tags") do |v|
62
+ opts[:tags] = [v.split].flatten
63
+ end
64
+
55
65
  parser.on("-q", "--quiet", "Print only errors") do |v|
56
66
  opts[:verbosity] = Logger::ERROR
57
67
  end
@@ -64,16 +74,16 @@ EOB
64
74
  opts[:friendly_exceptions] = ! v
65
75
  end
66
76
 
67
- parser.on("-h", "--help", "Display this help message") do |v|
68
- puts parser
69
- exit
70
- end
71
-
72
77
  parser.on("-v", "--version", "Display version") do |v|
73
78
  puts AutomateIt::VERSION
74
79
  exit 0
75
80
  end
76
81
 
82
+ parser.on("-h", "--help", "Display this help message") do |v|
83
+ puts parser
84
+ exit
85
+ end
86
+
77
87
  args = parser.parse!.dup
78
88
 
79
89
  # Clear ARGV so that IRB doesn't try to parse our options
@@ -1,31 +1,38 @@
1
- # Install packages on hosts tagged 'rails_servers' or 'myapp_servers'
1
+ # Install dependencies on hosts with 'rails_servers' or 'myapp_servers' roles
2
2
  if tagged?("rails_servers | myapp_servers")
3
- # Install platform-specific packages, queries system-provided tags
3
+ # Install platform-specific packages
4
4
  if tagged?("ubuntu | debian")
5
- package_manager.install(%w(build-essential ruby1.8-dev libsqlite3-dev))
5
+ # Install the 'build-essential' package and others on Ubuntu or Debian
6
+ package_manager.install("build-essential", "ruby1.8-dev", "libsqlite3-dev")
6
7
  elsif tagged?("fedoracore | fedora | centos")
7
- package_manager.install(%w(gcc ruby-devel sqlite-devel))
8
+ # Install equivalent packages on Fedora and similar OSes
9
+ package_manager.install("gcc", "'ruby-devel", "sqlite-devel")
8
10
  else
11
+ # Fail if running on another platform
9
12
  raise NotImplementedError.new("no packages specified for this platform")
10
13
  end
11
14
 
12
- # Install Gems
13
- package_manager.install(%w(rails sqlite3-ruby mongrel),
15
+ # Install Rails and supporting libraries with RubyGems
16
+ package_manager.install("rails", "sqlite3-ruby", "mongrel",
14
17
  :with => :gem, :docs => false)
15
- end
18
+ end # ENDS: if tagged?("rails_servers | myapp_servers")
16
19
 
17
- # Setup the myapp server
20
+ # Setup the myapp server, a simple Rails server instance
18
21
  if tagged?(:myapp_servers)
19
22
  # Create user for the application
20
23
  account_manager.add_user(lookup(:user))
21
24
 
22
- # Create a directory for the application
25
+ # Create a directory for the application and 'cd' into it
23
26
  mkdir_p(lookup(:path)) do
24
27
  # Run shell commands to create the app and database
25
- sh("rails --database=sqlite3 . > /dev/null") \
26
- unless File.exists?("config/routes.rb")
28
+ unless File.exists?("config/routes.rb")
29
+ sh("rails --database=sqlite3 . > /dev/null")
30
+ end
27
31
 
28
- sh("rake db:migrate") if Dir["db/*.sqlite3"].empty?
32
+ # Create the database if it doesn't exist.
33
+ if Dir["db/*.sqlite3"].empty?
34
+ sh("rake db:migrate")
35
+ end
29
36
 
30
37
  # Edit the homepage
31
38
  edit(:file => "public/index.html") do
@@ -33,21 +40,22 @@ if tagged?(:myapp_servers)
33
40
  replace("Welcome aboard", "This is MyAppServer")
34
41
  end
35
42
 
36
- # Change the ownership for the files
37
- chown_R(lookup(:user), nil, ".")
38
-
39
- # Generate a service startup file from a template
40
- render(:file => dist+"myapp_server.erb",
41
- :to => "/etc/init.d/myapp_server",
42
- :mode => 0555,
43
- :locals => {
44
- :path => lookup(:path),
45
- :user => lookup(:user),
46
- :port => lookup(:port),
47
- }
43
+ # Set the ownership of the created files
44
+ chperm(".", :user => lookup(:user), :recurse => true)
45
+
46
+ # Generate a service startup file using a template
47
+ render(
48
+ :file => dist+"myapp_server.erb",
49
+ :to => "/etc/init.d/myapp_server",
50
+ :mode => 0555,
51
+ :locals => {
52
+ :path => lookup(:path),
53
+ :user => lookup(:user),
54
+ :port => lookup(:port),
55
+ }
48
56
  )
49
57
 
50
- # Start the service
58
+ # Start the server
51
59
  service_manager.start("myapp_server")
52
- end
53
- end
60
+ end # ENDS: mkdir_p(lookup(:path)) do
61
+ end # ENDS: if tagged?(:myapp_servers)
@@ -64,3 +64,4 @@ require 'automateit/package_manager' # requires shell
64
64
  require 'automateit/template_manager'
65
65
  require 'automateit/edit_manager'
66
66
  require 'automateit/account_manager'
67
+ require 'automateit/download_manager'
@@ -15,6 +15,7 @@ module AutomateIt
15
15
  # AutomateIt::CLI.run(:eval => "42")
16
16
  #
17
17
  # Options:
18
+ # * :tags -- Array of tags to add for this run.
18
19
  # * :project -- Project directory to load.
19
20
  # * :recipe -- Recipe file to execute.
20
21
  # * :eval -- Evaluate this string.
@@ -26,7 +27,9 @@ module AutomateIt
26
27
  opts[:project] = File.join(File.dirname(recipe), "..")
27
28
  opts[:guessed_project] = true
28
29
  end
30
+
29
31
  opts[:verbosity] ||= Logger::INFO
32
+
30
33
  if opts[:create]
31
34
  Project::create(opts)
32
35
  elsif code = opts.delete(:eval)
@@ -50,15 +53,17 @@ module AutomateIt
50
53
  irb.context.workspace.instance_variable_set(:@binding, interpreter.send(:binding))
51
54
 
52
55
  # Tab completion
56
+ message = "<CTRL-D> to quit"
53
57
  begin
54
58
  require 'irb/completion'
55
59
  irb.context.auto_indent_mode = true
56
60
  irb.context.load_modules << 'irb/completion' unless irb.context.load_modules.include?('irb/completion')
57
61
  irb.context.instance_eval{ @use_readline = true }
58
- display.call PNOTE+"<CTRL-D> to quit, <Tab> to auto-complete"
62
+ message << ", <Tab> to auto-complete"
59
63
  rescue LoadError
60
- display.call PNOTE+"<CTRL-D> to quit"
64
+ # Ignore
61
65
  end
66
+ display.call PNOTE+message
62
67
 
63
68
  # Set prompt
64
69
  unless opts[:custom_prompt] == false
@@ -3,9 +3,6 @@ module AutomateIt # :nodoc:
3
3
  #
4
4
  # Various constants.
5
5
  module AutomateIt::Constants
6
- # AutomateIt version
7
- VERSION=Gem::Version.new("0.70923")
8
-
9
6
  # Output prefix for command execution, e.g., "** ls -la"
10
7
  PEXEC = "** "
11
8
 
@@ -0,0 +1,46 @@
1
+ # == DownloadManager
2
+ #
3
+ # The DownloadManager provides a way of downloading files.
4
+ module AutomateIt
5
+ class DownloadManager < Plugin::Manager
6
+ alias_methods :download
7
+
8
+ # Downloads the +source+ document.
9
+ #
10
+ # Options:
11
+ # * :to -- Saves source to this filename or directory. Defaults to current directory.
12
+ def download(source, opts={}) dispatch(source, opts) end
13
+
14
+ # == DownloadManager::BaseDriver
15
+ #
16
+ # Base class for all DownloadManager drivers.
17
+ class BaseDriver < Plugin::Driver
18
+ end
19
+
20
+ # == DownloadManager::OpenURI
21
+ #
22
+ # A DownloadManager driver using the OpenURI module for handling HTTP and FTP transfers.
23
+ class OpenURI < BaseDriver
24
+ depends_on :libraries => %w(open-uri)
25
+
26
+ def suitability(method, *args) # :nodoc:
27
+ return available? ? 1 : 0
28
+ end
29
+
30
+ # See DownloadManager#download
31
+ def download(source, opts={})
32
+ target = opts[:to] || File.basename(source)
33
+ target = File.join(target, File.basename(source)) if File.directory?(target)
34
+ log.info(PNOTE+"Downloading #{target}")
35
+ if writing?
36
+ open(target, "w+") do |writer|
37
+ open(source) do |reader|
38
+ writer.write(reader.read)
39
+ end
40
+ end
41
+ end
42
+ return writing?
43
+ end
44
+ end
45
+ end
46
+ end
@@ -84,6 +84,7 @@ class AutomateIt::EditManager::EditSession < AutomateIt::Common
84
84
  # * :params -- Hash to make available to editor session.
85
85
  # * :create -- Create the file if it doesn't exist? Defaults to false.
86
86
  # * :mode, :user, :group -- Set permissions on generated file, see ShellManager#chperm
87
+ # * :backup -- Make a backup of original file? Defaults to true.
87
88
  #
88
89
  # Edit a string:
89
90
  #
@@ -110,10 +111,11 @@ class AutomateIt::EditManager::EditSession < AutomateIt::Common
110
111
  @filename = args.first
111
112
  else
112
113
  raise ArgumentError.new("no file or text specified for editing") unless opts[:file] or opts[:text]
113
- @filename = opts.delete(:file)
114
- @contents = opts.delete(:text)
114
+ @filename = opts[:file]
115
+ @contents = opts[:text]
115
116
  end
116
- @params = opts.delete(:params) || {}
117
+ @params = opts[:params] || {}
118
+ @is_backup = opts[:backup].nil? ? true : opts[:backup]
117
119
  @comment_prefix = "# "
118
120
  @comment_suffix = ""
119
121
  begin
@@ -130,7 +132,10 @@ class AutomateIt::EditManager::EditSession < AutomateIt::Common
130
132
  raise ArgumentError.new("no block given") unless block
131
133
  instance_eval(&block)
132
134
  if @filename
133
- _write if different?
135
+ if different?
136
+ _backup if @is_backup
137
+ _write
138
+ end
134
139
 
135
140
  chperm_opts = {}
136
141
  for key in [:owner, :user, :group, :mode]
@@ -270,17 +275,18 @@ class AutomateIt::EditManager::EditSession < AutomateIt::Common
270
275
  # into the buffer.
271
276
  def _read
272
277
  @contents = \
273
- if writing? or (preview? and @filename and File.exists?(@filename))
274
- File.read(@filename)
275
- else
276
- nil
277
- end
278
+ if writing? or (preview? and @filename and _exists?)
279
+ File.read(@filename)
280
+ else
281
+ nil
282
+ end
278
283
  end
279
284
  protected :_read
280
285
 
281
286
  # Write contents to #filename. Used by the #edit command to write the buffer
282
287
  # to a file.
283
288
  def _write
289
+ return false unless @filename
284
290
  log.info(PNOTE+"Edited '#{@filename}'")
285
291
  if preview?
286
292
  true
@@ -289,4 +295,21 @@ class AutomateIt::EditManager::EditSession < AutomateIt::Common
289
295
  end
290
296
  end
291
297
  protected :_write
298
+
299
+ # Backup the original file.
300
+ def _backup
301
+ return false unless @filename and File.exists?(@filename)
302
+ result = nil
303
+ log.silence(Logger::WARN) do
304
+ result = backup(@filename)
305
+ end
306
+ log.info(PNOTE+"Saved '#{@filename}' to '#{result}'")
307
+ end
308
+ protected :_backup
309
+
310
+ # Does the file exist?
311
+ def _exists?
312
+ File.exists?(@filename)
313
+ end
314
+ protected :_exists?
292
315
  end # class EditSession