deployml 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
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