deployml 0.5.1 → 0.5.2

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/.document CHANGED
@@ -1,3 +1,3 @@
1
1
  -
2
2
  LICENSE.txt
3
- ChangeLog.*
3
+ ChangeLog.md
data/ChangeLog.md CHANGED
@@ -1,3 +1,15 @@
1
+ ### 0.5.2 / 2011-06-21
2
+
3
+ * Added {DeploYML::Shell#ruby}.
4
+ * Override {DeploYML::LocalShell#exec} and {DeploYML::RemoteShell#exec}
5
+ to prevent full commands from being escaped.
6
+ * Ensure that {DeploYML::Shell#ruby} and {DeploYML::Shell#rake} will
7
+ prefix commands with `bundle exec`, if Bundler is enabled.
8
+ * All `thin` and `mongrel_cluster` commands now support running under
9
+ `bundle exec`.
10
+ * Merged `DeploYML::Frameworks::Rails2` and `DeploYML::Frameworks::Rails3`
11
+ into {DeploYML::Frameworks::Rails}.
12
+
1
13
  ### 0.5.1 / 2011-04-25
2
14
 
3
15
  * Emergency typo fix for {DeploYML::Environment#invoke}.
data/README.md CHANGED
@@ -77,7 +77,7 @@ Multiple environments:
77
77
 
78
78
  # config/deploy.yml
79
79
  source: git@github.com:user/project.git
80
- framework: rails3
80
+ framework: rails
81
81
  orm: datamapper
82
82
 
83
83
  # config/deploy/staging.yml
data/Rakefile CHANGED
@@ -25,7 +25,7 @@ task :test => :spec
25
25
  task :default => :spec
26
26
 
27
27
  begin
28
- gem 'yard', '~> 0.6.0'
28
+ gem 'yard', '~> 0.7.0'
29
29
  require 'yard'
30
30
 
31
31
  YARD::Rake::YardocTask.new
data/deployml.gemspec CHANGED
@@ -1,15 +1,127 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
- begin
4
- Ore::Specification.new do |gemspec|
5
- # custom logic here
6
- end
7
- rescue NameError
8
- begin
9
- require 'ore/specification'
10
- retry
11
- rescue LoadError
12
- STDERR.puts "The 'deployml.gemspec' file requires Ore."
13
- STDERR.puts "Run `gem install ore-core` to install Ore."
1
+ # encoding: utf-8
2
+
3
+ require 'yaml'
4
+
5
+ Gem::Specification.new do |gemspec|
6
+ files = if File.directory?('.git')
7
+ `git ls-files`.split($/)
8
+ elsif File.directory?('.hg')
9
+ `hg manifest`.split($/)
10
+ elsif File.directory?('.svn')
11
+ `svn ls -R`.split($/).select { |path| File.file?(path) }
12
+ else
13
+ Dir['{**/}{.*,*}'].select { |path| File.file?(path) }
14
+ end
15
+
16
+ filter_files = lambda { |paths|
17
+ case paths
18
+ when Array
19
+ (files & paths)
20
+ when String
21
+ (files & Dir[paths])
22
+ end
23
+ }
24
+
25
+ version = {
26
+ :file => 'lib/deployml/version.rb',
27
+ :constant => 'DeploYML::VERSION'
28
+ }
29
+
30
+ defaults = {
31
+ 'name' => File.basename(File.dirname(__FILE__)),
32
+ 'files' => files,
33
+ 'executables' => filter_files['bin/*'].map { |path| File.basename(path) },
34
+ 'test_files' => filter_files['{test/{**/}*_test.rb,spec/{**/}*_spec.rb}'],
35
+ 'extra_doc_files' => filter_files['*.{txt,rdoc,md,markdown,tt,textile}'],
36
+ }
37
+
38
+ metadata = defaults.merge(YAML.load_file('gemspec.yml'))
39
+
40
+ gemspec.name = metadata.fetch('name',defaults[:name])
41
+ gemspec.version = if metadata['version']
42
+ metadata['version']
43
+ elsif File.file?(version[:file])
44
+ require File.join('.',version[:file])
45
+ eval(version[:constant])
46
+ end
47
+
48
+ gemspec.summary = metadata.fetch('summary',metadata['description'])
49
+ gemspec.description = metadata.fetch('description',metadata['summary'])
50
+
51
+ case metadata['license']
52
+ when Array
53
+ gemspec.licenses = metadata['license']
54
+ when String
55
+ gemspec.license = metadata['license']
56
+ end
57
+
58
+ case metadata['authors']
59
+ when Array
60
+ gemspec.authors = metadata['authors']
61
+ when String
62
+ gemspec.author = metadata['authors']
63
+ end
64
+
65
+ gemspec.email = metadata['email']
66
+ gemspec.homepage = metadata['homepage']
67
+
68
+ case metadata['require_paths']
69
+ when Array
70
+ gemspec.require_paths = metadata['require_paths']
71
+ when String
72
+ gemspec.require_path = metadata['require_paths']
73
+ end
74
+
75
+ gemspec.files = filter_files[metadata['files']]
76
+
77
+ gemspec.executables = metadata['executables']
78
+ gemspec.extensions = metadata['extensions']
79
+
80
+ if Gem::VERSION < '1.7.'
81
+ gemspec.default_executable = gemspec.executables.first
82
+ end
83
+
84
+ gemspec.test_files = filter_files[metadata['test_files']]
85
+
86
+ unless gemspec.files.include?('.document')
87
+ gemspec.extra_rdoc_files = metadata['extra_doc_files']
88
+ end
89
+
90
+ gemspec.post_install_message = metadata['post_install_message']
91
+ gemspec.requirements = metadata['requirements']
92
+
93
+ if gemspec.respond_to?(:required_ruby_version=)
94
+ gemspec.required_ruby_version = metadata['required_ruby_version']
95
+ end
96
+
97
+ if gemspec.respond_to?(:required_rubygems_version=)
98
+ gemspec.required_rubygems_version = metadata['required_ruby_version']
99
+ end
100
+
101
+ parse_versions = lambda { |versions|
102
+ case versions
103
+ when Array
104
+ versions.map { |v| v.to_s }
105
+ when String
106
+ versions.split(/,\s*/)
107
+ end
108
+ }
109
+
110
+ if metadata['dependencies']
111
+ metadata['dependencies'].each do |name,versions|
112
+ gemspec.add_dependency(name,parse_versions[versions])
113
+ end
114
+ end
115
+
116
+ if metadata['runtime_dependencies']
117
+ metadata['runtime_dependencies'].each do |name,versions|
118
+ gemspec.add_runtime_dependency(name,parse_versions[versions])
119
+ end
120
+ end
121
+
122
+ if metadata['development_dependencies']
123
+ metadata['development_dependencies'].each do |name,versions|
124
+ gemspec.add_development_dependency(name,parse_versions[versions])
125
+ end
14
126
  end
15
127
  end
data/gemspec.yml CHANGED
@@ -20,4 +20,4 @@ dependencies:
20
20
  development_dependencies:
21
21
  ore-tasks: ~> 0.4
22
22
  rspec: ~> 2.4
23
- yard: ~> 0.6.0
23
+ yard: ~> 0.7.0
@@ -94,7 +94,10 @@ module DeploYML
94
94
 
95
95
  @bundler = config.fetch(:bundler,false)
96
96
 
97
- @framework = if config[:framework]
97
+ @framework = case config[:framework]
98
+ when 'rails', 'rails2', 'rails3'
99
+ :rails
100
+ when String, Symbol
98
101
  config[:framework].to_sym
99
102
  end
100
103
 
@@ -23,8 +23,7 @@ module DeploYML
23
23
 
24
24
  # Mapping of possible 'framework' names to their mixins.
25
25
  FRAMEWORKS = {
26
- :rails2 => Frameworks::Rails2,
27
- :rails3 => Frameworks::Rails3
26
+ :rails => Frameworks::Rails
28
27
  }
29
28
 
30
29
  #
@@ -74,7 +73,7 @@ module DeploYML
74
73
  # @since 0.3.0
75
74
  #
76
75
  def local_shell(&block)
77
- each_dest.map { |dest| LocalShell.new(dest,&block) }
76
+ each_dest.map { |dest| LocalShell.new(dest,self,&block) }
78
77
  end
79
78
 
80
79
  #
@@ -100,7 +99,7 @@ module DeploYML
100
99
  RemoteShell
101
100
  end
102
101
 
103
- shell.new(dest,&block)
102
+ shell.new(dest,self,&block)
104
103
  end
105
104
  end
106
105
 
@@ -1,7 +1,7 @@
1
1
  module DeploYML
2
2
  module Frameworks
3
3
  #
4
- # Provides common methods needed to deploy Rails 2 and 3 projects.
4
+ # Provides methods for deploying Rails projects.
5
5
  #
6
6
  module Rails
7
7
  #
@@ -15,6 +15,27 @@ module DeploYML
15
15
 
16
16
  super(task,*arguments)
17
17
  end
18
+
19
+ #
20
+ # Migrates the database using the `db:autoupgrade` if
21
+ # [DataMapper](http://datamapper.org) is being used, or the typical
22
+ # `db:migrate` task.
23
+ #
24
+ # @param [LocalShell, RemoteShell] shell
25
+ # The shell to execute commands in.
26
+ #
27
+ def migrate(shell)
28
+ case @orm
29
+ when :datamapper
30
+ shell.status "Running DataMapper auto-upgrades ..."
31
+ shell.ruby 'rake', 'db:autoupgrade', "RAILS_ENV=#{@environment}"
32
+ else
33
+ shell.status "Running ActiveRecord migrations ..."
34
+ shell.ruby 'rake', 'db:migrate', "RAILS_ENV=#{@environment}"
35
+ end
36
+
37
+ shell.status "Database migrated."
38
+ end
18
39
  end
19
40
  end
20
41
  end
@@ -1,2 +1 @@
1
- require 'deployml/frameworks/rails2'
2
- require 'deployml/frameworks/rails3'
1
+ require 'deployml/frameworks/rails'
@@ -22,6 +22,18 @@ module DeploYML
22
22
  system(program,*arguments)
23
23
  end
24
24
 
25
+ #
26
+ # Executes a command.
27
+ #
28
+ # @param [String] command
29
+ # The command to be executed.
30
+ #
31
+ # @since 0.5.2
32
+ #
33
+ def exec(command)
34
+ system(command)
35
+ end
36
+
25
37
  #
26
38
  # Prints out a message.
27
39
  #
@@ -18,16 +18,19 @@ module DeploYML
18
18
  # @param [Addressable::URI, String] uri
19
19
  # The URI of the host to connect to.
20
20
  #
21
+ # @param [Environment] environment
22
+ # The environment the shell is connected to.
23
+ #
21
24
  # @yield [session]
22
25
  # If a block is given, it will be passed the new remote shell session.
23
26
  #
24
27
  # @yieldparam [ShellSession] session
25
28
  # The remote shell session.
26
29
  #
27
- def initialize(uri,&block)
30
+ def initialize(uri,environment=nil,&block)
28
31
  @history = []
29
32
 
30
- super(uri,&block)
33
+ super(uri,environment,&block)
31
34
 
32
35
  replay if block
33
36
  end
@@ -45,6 +48,18 @@ module DeploYML
45
48
  @history << [program, *arguments]
46
49
  end
47
50
 
51
+ #
52
+ # Adds a command to be executed.
53
+ #
54
+ # @param [String] command
55
+ # The command string.
56
+ #
57
+ # @since 0.5.2
58
+ #
59
+ def exec(command)
60
+ @history << [command]
61
+ end
62
+
48
63
  #
49
64
  # Enqueues an `echo` command to be ran in the session.
50
65
  #
@@ -82,9 +97,16 @@ module DeploYML
82
97
  # A single command string.
83
98
  #
84
99
  def join
85
- @history.map { |command|
86
- command.map { |word| shellescape(word.to_s) }.join(' ')
87
- }.join(' && ')
100
+ commands = []
101
+
102
+ @history.each do |command|
103
+ program = command[0]
104
+ arguments = command[1..-1].map { |word| shellescape(word.to_s) }
105
+
106
+ commands << [program, *arguments].join(' ')
107
+ end
108
+
109
+ return commands.join(' && ')
88
110
  end
89
111
 
90
112
  #
@@ -137,44 +159,5 @@ module DeploYML
137
159
  ssh(self.join) unless @history.empty?
138
160
  end
139
161
 
140
- protected
141
-
142
- #
143
- # Escapes a string so that it can be safely used in a Bourne shell
144
- # command line.
145
- #
146
- # Note that a resulted string should be used unquoted and is not
147
- # intended for use in double quotes nor in single quotes.
148
- #
149
- # @param [String] str
150
- # The string to escape.
151
- #
152
- # @return [String]
153
- # The shell-escaped string.
154
- #
155
- # @example
156
- # open("| grep #{Shellwords.escape(pattern)} file") { |pipe|
157
- # # ...
158
- # }
159
- #
160
- # @note Vendored from `shellwords.rb` line 72 from Ruby 1.9.2.
161
- #
162
- def shellescape(str)
163
- # An empty argument will be skipped, so return empty quotes.
164
- return "''" if str.empty?
165
-
166
- str = str.dup
167
-
168
- # Process as a single byte sequence because not all shell
169
- # implementations are multibyte aware.
170
- str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/n, "\\\\\\1")
171
-
172
- # A LF cannot be escaped with a backslash because a backslash + LF
173
- # combo is regarded as line continuation and simply ignored.
174
- str.gsub!(/\n/, "'\n'")
175
-
176
- return str
177
- end
178
-
179
162
  end
180
163
  end
@@ -28,7 +28,7 @@ module DeploYML
28
28
  def mongrel_cluster(shell,*arguments)
29
29
  options = arguments + ['-c', @mongrel.config]
30
30
 
31
- shell.run 'mongrel_rails', *options
31
+ shell.ruby 'mongrel_rails', *options
32
32
  end
33
33
 
34
34
  #
@@ -49,7 +49,7 @@ module DeploYML
49
49
  shell.status "Configuring Mongrel ..."
50
50
 
51
51
  options = ['-c', shell.uri.path] + @mongrel.arguments
52
- shell.run 'mongrel_rails', 'cluster::configure', *options
52
+ shell.ruby 'mongrel_rails', 'cluster::configure', *options
53
53
 
54
54
  shell.status "Mongrel configured."
55
55
  end
@@ -28,7 +28,7 @@ module DeploYML
28
28
  def thin(shell,*arguments)
29
29
  options = arguments + ['-C', @thin.config, '-s', @thin.servers]
30
30
 
31
- shell.run 'thin', *options
31
+ shell.ruby 'thin', *options
32
32
  end
33
33
 
34
34
  #
@@ -49,7 +49,7 @@ module DeploYML
49
49
  shell.status "Configuring Thin ..."
50
50
 
51
51
  options = ['-c', shell.uri.path] + @thin.arguments
52
- shell.run 'thin', 'config', *options
52
+ shell.ruby 'thin', 'config', *options
53
53
 
54
54
  shell.status "Thin configured."
55
55
  end
@@ -19,14 +19,18 @@ module DeploYML
19
19
  # @param [Addressable::URI, String] uri
20
20
  # The URI of the shell.
21
21
  #
22
+ # @param [Environment] environment
23
+ # The environment the shell is connected to.
24
+ #
22
25
  # @yield [session]
23
26
  # If a block is given, it will be passed the new shell session.
24
27
  #
25
28
  # @yieldparam [ShellSession] session
26
29
  # The shell session.
27
30
  #
28
- def initialize(uri)
31
+ def initialize(uri,environment=nil)
29
32
  @uri = uri
33
+ @environment = environment
30
34
 
31
35
  if block_given?
32
36
  status "Entered #{@uri}."
@@ -44,17 +48,14 @@ module DeploYML
44
48
  end
45
49
 
46
50
  #
47
- # Runs a command in the shell.
51
+ # Place holder method.
48
52
  #
49
53
  # @param [String] command
50
- # The command to run.
51
- #
52
- # @see #run
54
+ # The command to execute.
53
55
  #
54
56
  # @since 0.5.0
55
57
  #
56
58
  def exec(command)
57
- run(*shellwords(command))
58
59
  end
59
60
 
60
61
  #
@@ -65,6 +66,30 @@ module DeploYML
65
66
  def echo(message)
66
67
  end
67
68
 
69
+ #
70
+ # Executes a Ruby program.
71
+ #
72
+ # @param [Symbol, String] program
73
+ # Name of the Ruby program to run.
74
+ #
75
+ # @param [Array<String>] arguments
76
+ # Additional arguments for the Ruby program.
77
+ #
78
+ # @since 0.5.2
79
+ #
80
+ def ruby(program,*arguments)
81
+ command = [program, *arguments]
82
+
83
+ # assume that `.rb` scripts do not have a `#!/usr/bin/env ruby`
84
+ command.unshift('ruby') if program[-3,3] == '.rb'
85
+
86
+ if (@environment && @environment.bundler)
87
+ command.unshift('bundle','exec')
88
+ end
89
+
90
+ run(*command)
91
+ end
92
+
68
93
  #
69
94
  # Executes a Rake task.
70
95
  #
@@ -75,7 +100,7 @@ module DeploYML
75
100
  # Additional arguments for the Rake task.
76
101
  #
77
102
  def rake(task,*arguments)
78
- run 'rake', rake_task(task,*arguments)
103
+ ruby('rake', rake_task(task,*arguments))
79
104
  end
80
105
 
81
106
  #
@@ -92,6 +117,43 @@ module DeploYML
92
117
 
93
118
  protected
94
119
 
120
+ #
121
+ # Escapes a string so that it can be safely used in a Bourne shell
122
+ # command line.
123
+ #
124
+ # Note that a resulted string should be used unquoted and is not
125
+ # intended for use in double quotes nor in single quotes.
126
+ #
127
+ # @param [String] str
128
+ # The string to escape.
129
+ #
130
+ # @return [String]
131
+ # The shell-escaped string.
132
+ #
133
+ # @example
134
+ # open("| grep #{Shellwords.escape(pattern)} file") { |pipe|
135
+ # # ...
136
+ # }
137
+ #
138
+ # @note Vendored from `shellwords.rb` line 72 from Ruby 1.9.2.
139
+ #
140
+ def shellescape(str)
141
+ # An empty argument will be skipped, so return empty quotes.
142
+ return "''" if str.empty?
143
+
144
+ str = str.dup
145
+
146
+ # Process as a single byte sequence because not all shell
147
+ # implementations are multibyte aware.
148
+ str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/n, "\\\\\\1")
149
+
150
+ # A LF cannot be escaped with a backslash because a backslash + LF
151
+ # combo is regarded as line continuation and simply ignored.
152
+ str.gsub!(/\n/, "'\n'")
153
+
154
+ return str
155
+ end
156
+
95
157
  #
96
158
  # Builds a `rake` task name.
97
159
  #
@@ -1,4 +1,4 @@
1
1
  module DeploYML
2
2
  # deploYML version
3
- VERSION = '0.5.1'
3
+ VERSION = '0.5.2'
4
4
  end
@@ -8,7 +8,7 @@ describe Environment do
8
8
  Environment.new(name, {
9
9
  'source' => 'git@github.com:user/project.git',
10
10
  'dest' => 'ssh://user@www.example.com/srv/project',
11
- 'framework' => 'rails3',
11
+ 'framework' => 'rails',
12
12
  'orm' => 'datamapper',
13
13
  'server' => {
14
14
  'name' => 'thin',
@@ -25,7 +25,7 @@ describe Environment do
25
25
  end
26
26
 
27
27
  it "should include the framework mixin" do
28
- subject.should be_kind_of(Frameworks::Rails3)
28
+ subject.should be_kind_of(Frameworks::Rails)
29
29
  end
30
30
 
31
31
  it "should include the server mixin" do
@@ -1,3 +1,3 @@
1
1
  source: git@github.com:user/project.git
2
- framework: rails3
2
+ framework: rails
3
3
  orm: datamapper
data/spec/project_spec.rb CHANGED
@@ -59,7 +59,7 @@ describe Project do
59
59
  project = Project.new(project_dir(:rails))
60
60
 
61
61
  project.environments.all? { |name,env|
62
- env.framework == :rails3 && env.orm == :datamapper
62
+ env.framework == :rails && env.orm == :datamapper
63
63
  }.should == true
64
64
  end
65
65
  end
@@ -69,9 +69,9 @@ describe RemoteShell do
69
69
  end
70
70
 
71
71
  it "should escape all command arguments" do
72
- subject.run 'the program'
72
+ subject.run 'program arg1 arg2'
73
73
  subject.run 'echo', '>>> status'
74
74
 
75
- subject.join.should == "the\\ program && echo \\>\\>\\>\\ status"
75
+ subject.join.should == "program arg1 arg2 && echo \\>\\>\\>\\ status"
76
76
  end
77
77
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: deployml
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.5.1
5
+ version: 0.5.2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Postmodern
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-04-25 00:00:00 Z
13
+ date: 2011-06-21 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: addressable
@@ -75,7 +75,7 @@ dependencies:
75
75
  requirements:
76
76
  - - ~>
77
77
  - !ruby/object:Gem::Version
78
- version: 0.6.0
78
+ version: 0.7.0
79
79
  type: :development
80
80
  version_requirements: *id006
81
81
  description: DeploYML is a simple deployment solution that uses a single YAML file, Git and SSH.
@@ -113,8 +113,6 @@ files:
113
113
  - lib/deployml/exceptions/unknown_server.rb
114
114
  - lib/deployml/frameworks.rb
115
115
  - lib/deployml/frameworks/rails.rb
116
- - lib/deployml/frameworks/rails2.rb
117
- - lib/deployml/frameworks/rails3.rb
118
116
  - lib/deployml/local_shell.rb
119
117
  - lib/deployml/options.rb
120
118
  - lib/deployml/options/mongrel.rb
@@ -166,7 +164,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
166
164
  requirements: []
167
165
 
168
166
  rubyforge_project: deployml
169
- rubygems_version: 1.7.2
167
+ rubygems_version: 1.8.5
170
168
  signing_key:
171
169
  specification_version: 3
172
170
  summary: A simple deployment solution that works.
@@ -1,26 +0,0 @@
1
- require 'deployml/frameworks/rails'
2
-
3
- module DeploYML
4
- module Frameworks
5
- #
6
- # Provides methods for deploying Rails 2 projects.
7
- #
8
- module Rails2
9
- include Rails
10
-
11
- #
12
- # Migrates the database using the `db:migrate` task.
13
- #
14
- # @param [LocalShell, RemoteShell] shell
15
- # The shell to execute commands in.
16
- #
17
- def migrate(shell)
18
- shell.status "Migrating the ActiveRecord Database ..."
19
-
20
- shell.run 'rake', 'db:migrate', "RAILS_ENV=#{@environment}"
21
-
22
- shell.status "ActiveRecord Database migrated."
23
- end
24
- end
25
- end
26
- end
@@ -1,33 +0,0 @@
1
- require 'deployml/frameworks/rails'
2
-
3
- module DeploYML
4
- module Frameworks
5
- #
6
- # Provides methods for deploying Rails 3 projects.
7
- #
8
- module Rails3
9
- include Rails
10
-
11
- #
12
- # Migrates the database using the `db:autoupgrade` if
13
- # [DataMapper](http://datamapper.org) is being used, or the typical
14
- # `db:migrate` task.
15
- #
16
- # @param [LocalShell, RemoteShell] shell
17
- # The shell to execute commands in.
18
- #
19
- def migrate(shell)
20
- case @orm
21
- when :datamapper
22
- shell.status "Running DataMapper auto-upgrades ..."
23
- shell.run 'rake', 'db:autoupgrade', "RAILS_ENV=#{@environment}"
24
- else
25
- shell.status "Running ActiveRecord migrations ..."
26
- shell.run 'rake', 'db:migrate', "RAILS_ENV=#{@environment}"
27
- end
28
-
29
- shell.status "Database migrated."
30
- end
31
- end
32
- end
33
- end