railsthemes 1.1.pre → 1.1.pre.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.
Files changed (33) hide show
  1. data/Gemfile +2 -2
  2. data/bin/railsthemes +27 -12
  3. data/cacert.pem +3331 -0
  4. data/lib/railsthemes/email_installer.rb +73 -0
  5. data/lib/railsthemes/ensurer.rb +152 -0
  6. data/lib/railsthemes/installer.rb +116 -345
  7. data/lib/railsthemes/logging.rb +35 -0
  8. data/lib/railsthemes/theme_installer.rb +126 -0
  9. data/lib/railsthemes/utils.rb +116 -24
  10. data/lib/railsthemes/version.rb +1 -1
  11. data/lib/railsthemes.rb +22 -1
  12. data/railsthemes.gemspec +2 -0
  13. data/spec/fixtures/blank-assets/{base/app/assets/images/bg/sprite.png → email/app/assets/stylesheets/email.css} +0 -0
  14. data/spec/fixtures/blank-assets/{base/app/assets/images/image1.png → erb-css/base/app/assets/images/bg/sprite.png} +0 -0
  15. data/spec/fixtures/blank-assets/{base/app/assets/javascripts/jquery.dataTables.js → erb-css/base/app/assets/images/image1.png} +0 -0
  16. data/spec/fixtures/blank-assets/{base/app/assets/javascripts/scripts.js.erb → erb-css/base/app/assets/javascripts/jquery.dataTables.js} +0 -0
  17. data/spec/fixtures/blank-assets/{base/app/views/layouts/_interior_sidebar.html.erb → erb-css/base/app/assets/javascripts/scripts.js.erb} +0 -0
  18. data/spec/fixtures/blank-assets/{base → erb-css/base}/app/assets/stylesheets/style.css.erb +0 -0
  19. data/spec/fixtures/blank-assets/{base/app/views/layouts/application.html.erb → erb-css/base/app/views/layouts/_interior_sidebar.html.erb} +0 -0
  20. data/spec/fixtures/blank-assets/{base/app/views/layouts/homepage.html.erb → erb-css/base/app/views/layouts/application.html.erb} +0 -0
  21. data/spec/fixtures/blank-assets/{gems/formtastic/app/assets/stylesheets/formtastic.css.scss → erb-css/base/app/views/layouts/homepage.html.erb} +0 -0
  22. data/spec/fixtures/blank-assets/{gems/simple_form/app/assets/stylesheets/simple_form.css.scss → erb-css/gems/formtastic/app/assets/stylesheets/formtastic.css.scss} +0 -0
  23. data/spec/fixtures/blank-assets/erb-css/gems/simple_form/app/assets/stylesheets/simple_form.css.scss +0 -0
  24. data/spec/fixtures/{blank-assets.tar.gz → blank-assets-archived/email.tar.gz} +0 -0
  25. data/spec/fixtures/blank-assets-archived/erb-css.tar.gz +0 -0
  26. data/spec/lib/railsthemes/email_installer_spec.rb +8 -0
  27. data/spec/lib/railsthemes/ensurer_spec.rb +215 -0
  28. data/spec/lib/railsthemes/installer_spec.rb +100 -456
  29. data/spec/lib/railsthemes/theme_installer_spec.rb +206 -0
  30. data/spec/lib/railsthemes/utils_spec.rb +62 -0
  31. data/spec/spec_helper.rb +49 -0
  32. metadata +71 -26
  33. data/lib/railsthemes/win_cacerts.rb +0 -26
@@ -1,11 +1,6 @@
1
- require 'fileutils'
2
- require 'open-uri'
3
- require 'railsthemes/os'
4
-
5
- # a bunch of things that should never be called in testing due to side effects
6
1
  module Railsthemes
7
2
  class Utils
8
- @@https_seen_before = false
3
+ extend Railsthemes::Logging
9
4
 
10
5
  # remove file only if it exists
11
6
  def self.remove_file filepath
@@ -25,31 +20,128 @@ module Railsthemes
25
20
  end
26
21
 
27
22
  # would be nice to put download status in the output (speed, progress, etc.)
28
- def self.download_file_to url, save_to
29
- File.open(save_to, "wb") do |saved_file|
30
- # the following "open" is provided by open-uri
31
- open(url) do |read_file|
32
- saved_file.write(read_file.read)
23
+ # needs tests
24
+ def self.download params = {}
25
+ url = params[:url]
26
+ save_to = params[:save_to]
27
+ return unless url && save_to
28
+ logger.info "Downloading url: #{url}"
29
+ logger.info "Saving to: #{save_to}"
30
+ uri = URI(url)
31
+ http = Net::HTTP.new uri.host, uri.port
32
+ set_https http if uri.scheme == 'https'
33
+ path = url.gsub(%r{https?://[^/]+}, '')
34
+ response = http.get(path)
35
+ if response.code.to_s == '200'
36
+ File.open(save_to, 'wb') do |file|
37
+ file.write(response.body)
38
+ end
39
+ else
40
+ logger.debug "response.code: #{response.code}"
41
+ logger.debug "response.body: #{response.body}"
42
+ Safe.log_and_abort 'Had trouble downloading a file and cannot continue.'
43
+ end
44
+ end
45
+
46
+ # needs tests I think
47
+ def self.get_url url
48
+ uri = URI.parse url
49
+ http = Net::HTTP.new uri.host, uri.port
50
+ set_https http if uri.scheme == 'https'
51
+ path = url.gsub(%r{https?://[^/]+}, '')
52
+ http.request_get(path)
53
+ end
54
+
55
+ # needs tests
56
+ def self.set_https http
57
+ cacert_file = File.join(File.expand_path(File.dirname(__FILE__)), '..', '..', 'cacert.pem')
58
+ http.ca_file = cacert_file
59
+ http.ca_path = cacert_file
60
+ ENV['SSL_CERT_FILE'] = cacert_file
61
+
62
+ http.use_ssl = true
63
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
64
+ end
65
+
66
+ def self.archive? filepath
67
+ File.exists?(filepath) && filepath =~ /\.tar\.gz$/
68
+ end
69
+
70
+ # needs tests
71
+ def self.with_tempdir &block
72
+ tempdir = generate_tempdir_name
73
+ FileUtils.mkdir_p tempdir
74
+ yield tempdir
75
+ FileUtils.rm_rf tempdir
76
+ end
77
+
78
+ # needs tests
79
+ def self.generate_tempdir_name
80
+ tempdir = File.join(Dir.tmpdir, DateTime.now.strftime("railsthemes-%Y%m%d-%H%M%S-#{rand(100000000)}"))
81
+ logger.debug "tempdir: #{tempdir}"
82
+ tempdir
83
+ end
84
+
85
+ # needs tests
86
+ def self.gemspecs gemfile_contents = nil
87
+ gemfile_contents ||= Utils.read_file('Gemfile.lock')
88
+ return [] if gemfile_contents.strip == ''
89
+ lockfile = Bundler::LockfileParser.new(gemfile_contents)
90
+ lockfile.specs
91
+ end
92
+
93
+ def self.unarchive archive, extract_to
94
+ Safe.log_and_abort "Archive expected at #{archive}, but none exists." unless File.exist?(archive)
95
+ logger.warn "Extracting..."
96
+ logger.info "Attempting to extract #{archive}"
97
+ io = Tar.ungzip(File.open(archive, 'rb'))
98
+ Tar.untar(io, extract_to)
99
+ logger.warn "Finished extracting."
100
+ end
101
+
102
+ def self.get_primary_configuration gemfile_contents = read_file('Gemfile.lock')
103
+ gem_names = gemspecs(gemfile_contents).map(&:name)
104
+ [(gem_names.include?('haml') ? 'haml' : 'erb'),
105
+ (gem_names.include?('sass') ? 'scss' : 'css')]
106
+ end
107
+
108
+ # needs tests
109
+ def self.conditionally_insert_routes routes_hash
110
+ if File.exists?(File.join('config', 'routes.rb'))
111
+ lines = Utils.read_file('config/routes.rb').split("\n")
112
+ last = lines.pop
113
+ routes_hash.each do |first, second|
114
+ if lines.grep(/#{second}/).empty?
115
+ lines << " match '#{first}' => '#{second}'"
116
+ end
117
+ end
118
+ lines << last
119
+ File.open(File.join('config', 'routes.rb'), 'w') do |f|
120
+ lines.each do |line|
121
+ f.puts line
122
+ end
33
123
  end
34
124
  end
35
125
  end
36
126
 
37
- def self.get_url server_request_url
38
- url = URI.parse(server_request_url)
39
- http = Net::HTTP.new url.host, url.port
40
- if server_request_url =~ /^https/
41
- if ::OS.windows?
42
- unless @@https_seen_before
43
- Railsthemes::WinCacerts.fetch
44
- @@https_seen_before = true
127
+ # needs tests
128
+ def self.conditionally_install_gems *gem_names
129
+ if File.exists?('Gemfile')
130
+ lines = Utils.read_file('Gemfile').split("\n")
131
+ gem_names.each do |gem_name|
132
+ if lines.grep(/#{gem_name}/).empty?
133
+ lines << "gem '#{gem_name}'"
45
134
  end
46
- http.ca_file = 'C:/RailsInstaller/cacert.pem'
47
135
  end
48
- http.use_ssl = true
49
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
136
+ File.open('Gemfile', 'w') do |f|
137
+ lines.each do |line|
138
+ f.puts line
139
+ end
140
+ end
141
+
142
+ # actually install the gems
143
+ Safe.system_call 'bundle'
50
144
  end
51
- path = server_request_url.gsub(%r{https?://[^/]+}, '')
52
- http.request_get(path)
53
145
  end
54
146
  end
55
147
  end
@@ -1,5 +1,5 @@
1
1
  module Railsthemes
2
2
  unless defined?(Railsthemes::VERSION)
3
- VERSION = "1.1.pre"
3
+ VERSION = "1.1.pre.2"
4
4
  end
5
5
  end
data/lib/railsthemes.rb CHANGED
@@ -1,9 +1,30 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ require 'logger'
4
+ require 'fileutils'
5
+ require 'open-uri'
6
+ require 'net/http'
7
+ require 'rest-client'
8
+ require 'launchy'
9
+ require 'json'
1
10
  require 'railsthemes/version'
11
+ require 'railsthemes/logging'
2
12
  require 'railsthemes/safe'
3
13
  require 'railsthemes/utils'
4
14
  require 'railsthemes/tar'
5
15
  require 'railsthemes/installer'
6
- require 'railsthemes/win_cacerts'
16
+ require 'railsthemes/theme_installer'
17
+ require 'railsthemes/email_installer'
18
+ require 'railsthemes/ensurer'
7
19
 
8
20
  module Railsthemes
21
+ def self.server
22
+ return @server if @server
23
+ @server = 'https://railsthemes.com'
24
+ if File.exist?('railsthemes_server')
25
+ Logging.logger.warn "WARNING: Using railsthemes_server override!"
26
+ @server = File.read('railsthemes_server').gsub("\n", '')
27
+ end
28
+ @server
29
+ end
9
30
  end
data/railsthemes.gemspec CHANGED
@@ -17,4 +17,6 @@ Gem::Specification.new do |gem|
17
17
 
18
18
  gem.add_dependency "thor"
19
19
  gem.add_dependency "rest-client"
20
+ gem.add_dependency "launchy"
21
+ gem.add_dependency "json"
20
22
  end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+ require 'railsthemes'
3
+
4
+ describe Railsthemes::EmailInstaller do
5
+ before do
6
+ setup_logging
7
+ end
8
+ end
@@ -0,0 +1,215 @@
1
+ require 'spec_helper'
2
+ require 'railsthemes'
3
+
4
+ describe Railsthemes::Ensurer do
5
+ before do
6
+ setup_logger
7
+ end
8
+
9
+ describe :ensure_clean_install_possible do
10
+ it 'should not do twice normally' do
11
+ mock(Railsthemes::Ensurer).ensure_in_rails_root.times(1)
12
+ mock(Railsthemes::Ensurer).ensure_bundle_is_up_to_date.times(1)
13
+ mock(Railsthemes::Ensurer).ensure_railsthemes_is_not_in_gemfile.times(1)
14
+ mock(Railsthemes::Ensurer).ensure_vcs_is_clean.times(1)
15
+ mock(Railsthemes::Ensurer).ensure_rails_version_is_valid.times(1)
16
+ mock(Railsthemes::Ensurer).ensure_installer_is_up_to_date.times(1)
17
+ 2.times { Railsthemes::Ensurer.ensure_clean_install_possible }
18
+ end
19
+
20
+ it 'should do twice if force passed' do
21
+ mock(Railsthemes::Ensurer).ensure_in_rails_root.times(2)
22
+ mock(Railsthemes::Ensurer).ensure_bundle_is_up_to_date.times(2)
23
+ mock(Railsthemes::Ensurer).ensure_railsthemes_is_not_in_gemfile.times(2)
24
+ mock(Railsthemes::Ensurer).ensure_vcs_is_clean.times(2)
25
+ mock(Railsthemes::Ensurer).ensure_rails_version_is_valid.times(2)
26
+ mock(Railsthemes::Ensurer).ensure_installer_is_up_to_date.times(2)
27
+ 2.times { Railsthemes::Ensurer.ensure_clean_install_possible true }
28
+ end
29
+ end
30
+
31
+ describe :ask_to_install_unsupported do
32
+ it 'should abort if the user does not want to continue' do
33
+ mock(Railsthemes::Safe).yes?(/wish to install/) { false }
34
+ mock(Railsthemes::Safe).log_and_abort('Halting.')
35
+ Railsthemes::Ensurer.ask_to_install_unsupported
36
+ end
37
+
38
+ it 'should continue if the user wants to continue' do
39
+ mock(Railsthemes::Safe).yes?(/wish to install/) { true }
40
+ dont_allow(Railsthemes::Safe).log_and_abort(anything)
41
+ Railsthemes::Ensurer.ask_to_install_unsupported
42
+ end
43
+ end
44
+
45
+ describe '#ensure_installer_is_up_to_date' do
46
+ it 'should abort with message if the current installer version is < server recommendation' do
47
+ FakeWeb.register_uri :get, /\/installer\/version$/, :body => '1.0.4'
48
+ mock(Railsthemes::Safe).log_and_abort(anything) do |message|
49
+ message.should match(/Your version is older than the recommended version/)
50
+ message.should match(/Your version: 1\.0\.3/)
51
+ message.should match(/Recommended version: 1\.0\.4/)
52
+ end
53
+ with_installer_version '1.0.3' do
54
+ Railsthemes::Ensurer.ensure_installer_is_up_to_date
55
+ end
56
+ end
57
+
58
+ it 'should not abort if the current installer version equals server recommendation' do
59
+ FakeWeb.register_uri :get, /\/installer\/version$/, :body => '1.0.4'
60
+ dont_allow(Railsthemes::Safe).log_and_abort(anything)
61
+ with_installer_version '1.0.4' do
62
+ Railsthemes::Ensurer.ensure_installer_is_up_to_date
63
+ end
64
+ end
65
+
66
+ it 'should return nothing if the current installer version is > server recommendation' do
67
+ FakeWeb.register_uri :get, /\/installer\/version$/, :body => '1.0.4'
68
+ dont_allow(Railsthemes::Safe).log_and_abort(anything)
69
+ with_installer_version '1.0.5' do
70
+ Railsthemes::Ensurer.ensure_installer_is_up_to_date
71
+ end
72
+ end
73
+
74
+ it 'should return an error message on any HTTP errors' do
75
+ FakeWeb.register_uri :get, /\/installer\/version$/,
76
+ :body => '', :status => ['401', 'Unauthorized']
77
+ mock(Railsthemes::Safe).log_and_abort(/issue checking your installer version/)
78
+ Railsthemes::Ensurer.ensure_installer_is_up_to_date
79
+ end
80
+ end
81
+
82
+ describe :ensure_vcs_is_clean do
83
+ context 'when Git used' do
84
+ before do
85
+ Dir.mkdir('.git')
86
+ end
87
+
88
+ it 'should log error and abort when the vcs is unclean' do
89
+ mock(Railsthemes::Safe).system_call('git status -s') { '# modified: installer_spec.rb' }
90
+ mock(Railsthemes::Safe).log_and_abort(anything) do |message|
91
+ message.should match /Git reports/
92
+ message.should match /# modified: installer_spec\.rb/
93
+ message.should match /roll back or commit/
94
+ end
95
+ Railsthemes::Ensurer.ensure_vcs_is_clean
96
+ end
97
+
98
+ it 'should do nothing significant when the vcs is clean' do
99
+ mock(Railsthemes::Safe).system_call('git status -s') { '' }
100
+ dont_allow(Railsthemes::Safe).log_and_abort(anything)
101
+ Railsthemes::Ensurer.ensure_vcs_is_clean
102
+ end
103
+ end
104
+
105
+ context 'when Mercurial used' do
106
+ before do
107
+ Dir.mkdir('.hg')
108
+ end
109
+
110
+ it 'should exit when the vcs is unclean' do
111
+ mock(Railsthemes::Safe).system_call('hg status') { '? test.txt' }
112
+ mock(Railsthemes::Safe).log_and_abort(anything) do |message|
113
+ message.should match /Mercurial reports/
114
+ message.should match /\? test\.txt/
115
+ message.should match /roll back or commit/
116
+ end
117
+ Railsthemes::Ensurer.ensure_vcs_is_clean
118
+ end
119
+
120
+ it 'should do nothing significant when the vcs is clean' do
121
+ mock(Railsthemes::Safe).system_call('hg status') { '' }
122
+ dont_allow(Railsthemes::Safe).log_and_abort(anything)
123
+ Railsthemes::Ensurer.ensure_vcs_is_clean
124
+ end
125
+ end
126
+
127
+ context 'when Subversion used' do
128
+ before do
129
+ Dir.mkdir('.svn')
130
+ end
131
+
132
+ it 'should exit when the vcs is unclean' do
133
+ mock(Railsthemes::Safe).system_call('svn status') { 'M something.txt' }
134
+ mock(Railsthemes::Safe).log_and_abort(anything) do |message|
135
+ message.should match /Subversion reports/
136
+ message.should match /M something\.txt/
137
+ message.should match /roll back or commit/
138
+ end
139
+ Railsthemes::Ensurer.ensure_vcs_is_clean
140
+ end
141
+
142
+ it 'should do nothing significant when the vcs is clean' do
143
+ mock(Railsthemes::Safe).system_call('svn status') { '' }
144
+ Railsthemes::Ensurer.ensure_vcs_is_clean
145
+ end
146
+ end
147
+ end
148
+
149
+ describe '#rails_version' do
150
+ it 'should return the right version' do
151
+ gemfile = using_gem_specs :rails => '3.0.1'
152
+ Railsthemes::Ensurer.rails_version(gemfile).version.should == '3.0.1'
153
+ end
154
+
155
+ it 'should return nil if there is no rails present' do
156
+ gemfile = using_gem_specs
157
+ Railsthemes::Ensurer.rails_version(gemfile).should be_nil
158
+ end
159
+ end
160
+
161
+ describe '#ensure_rails_version_is_valid' do
162
+ it 'should ask the user if they still want to install when the gemfile does not exist' do
163
+ stub(Railsthemes::Ensurer).rails_version { Gem::Version.new('3.2.0') }
164
+ mock(Railsthemes::Ensurer).ask_to_install_unsupported
165
+ Railsthemes::Ensurer.ensure_rails_version_is_valid
166
+ end
167
+
168
+ context 'when gemfile exists' do
169
+ before do
170
+ FileUtils.touch('Gemfile.lock')
171
+ end
172
+
173
+ it 'should ask the user if they still want to install when the rails version is < 3.1' do
174
+ stub(Railsthemes::Ensurer).rails_version { Gem::Version.new('3.0.9') }
175
+ mock(Railsthemes::Ensurer).ask_to_install_unsupported
176
+ Railsthemes::Ensurer.ensure_rails_version_is_valid
177
+ end
178
+
179
+ it 'should not ask if they still want to install when the rails version is supported' do
180
+ stub(Railsthemes::Ensurer).rails_version { Gem::Version.new('3.1.0') }
181
+ dont_allow(Railsthemes::Ensurer).ask_to_install_unsupported
182
+ Railsthemes::Ensurer.ensure_rails_version_is_valid
183
+ end
184
+ end
185
+ end
186
+
187
+ describe :ensure_bundle_is_up_to_date do
188
+ it 'should not log message and abort if the bundle is up to date' do
189
+ mock(Railsthemes::Safe).system_call('bundle check') { "The Gemfile's dependencies are satisfied" }
190
+ dont_allow(Railsthemes::Safe).log_and_abort(anything)
191
+ Railsthemes::Ensurer.ensure_bundle_is_up_to_date
192
+
193
+ end
194
+
195
+ it 'should log message and abort if the bundle is not up to date' do
196
+ mock(Railsthemes::Safe).system_call('bundle check') { 'test not up to date' }
197
+ mock(Railsthemes::Safe).log_and_abort(/test not up to date/)
198
+ Railsthemes::Ensurer.ensure_bundle_is_up_to_date
199
+ end
200
+ end
201
+
202
+ describe :ensure_railsthemes_is_not_in_gemfile do
203
+ it 'should log and abort if railsthemes is in the Gemfile.lock' do
204
+ mock(Railsthemes::Safe).log_and_abort(/in your Gemfile/i)
205
+ gemfile = using_gem_specs :railsthemes => '1.0.4'
206
+ Railsthemes::Ensurer.ensure_railsthemes_is_not_in_gemfile gemfile
207
+ end
208
+
209
+ it 'should do nothing if railsthemes is not in the Gemfile.lock' do
210
+ dont_allow(Railsthemes::Safe).log_and_abort(anything)
211
+ gemfile = using_gem_specs
212
+ Railsthemes::Ensurer.ensure_railsthemes_is_not_in_gemfile gemfile
213
+ end
214
+ end
215
+ end