railsthemes 0.0.1 → 1.0.0

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/Gemfile CHANGED
@@ -2,11 +2,14 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in railsthemes.gemspec
4
4
  gemspec
5
+ gem 'thor'
6
+ gem 'rest-client'
5
7
 
6
8
  # development gems
7
9
  group :test do
8
10
  gem 'rspec'
9
11
  gem 'rr'
10
12
  gem 'autotest'
11
- gem "fakefs", :require => 'fakefs/safe'
13
+ gem 'fakefs', :require => 'fakefs/safe'
14
+ gem 'fakeweb'
12
15
  end
data/README.md CHANGED
@@ -1,18 +1,10 @@
1
1
  # Railsthemes
2
2
 
3
- TODO: Write a gem description
3
+ This is a gem that helps you install a theme for your Rails app from RailsThemes.com. First, purchase a theme from the website. Then, install this gem and run it. You will get a download code, and you can pass this to the installer to install the theme (see below usage.) The themes at RailsThemes.com work for Rails 3.1+ (any that use the asset pipeline.)
4
4
 
5
5
  ## Installation
6
6
 
7
- Add this line to your application's Gemfile:
8
-
9
- gem 'railsthemes'
10
-
11
- And then execute:
12
-
13
- $ bundle
14
-
15
- Or install it yourself as:
7
+ Install using rubygems:
16
8
 
17
9
  $ gem install railsthemes
18
10
 
@@ -20,7 +12,13 @@ Or install it yourself as:
20
12
 
21
13
  Desired usage:
22
14
 
23
- $ railsthemes install my_hash
15
+ $ railsthemes install download_code
16
+
17
+ ## Other notes
18
+
19
+ This has been tested with Ruby 1.8.7, and should work with higher versions. 1.8.7 is the lowest version that Rails 3.1+ uses.
20
+
21
+ Not sure if this will work for Windows users due to invoking tar on the command-line instead of using native Ruby. This is something that we can change going forward, just a matter of time.
24
22
 
25
23
  ## Contributing
26
24
 
data/bin/railsthemes CHANGED
@@ -1,6 +1,26 @@
1
1
  #!/usr/bin/env ruby
2
+ require "rubygems"
3
+ require "thor"
4
+ require "railsthemes"
2
5
 
3
- require 'railsthemes'
6
+ class Installer < Thor
7
+ desc "install CODE", "Install from RailsThemes.com using your download code"
8
+ method_option :file, :aliases => "-f", :desc => "Use local filename instead of downloading", :type => :boolean
4
9
 
5
- installer = Railsthemes::Installer.new
6
- installer.execute ARGV
10
+ def install code_or_file
11
+ if options[:file]
12
+ file = code_or_file
13
+ abort 'Please specify a file to install from' unless file
14
+ puts "Installing from file: #{file}."
15
+ Railsthemes::Installer.new.install_from_file_system file
16
+ else
17
+ code = code_or_file
18
+ abort 'Please specify a code to install from' unless code
19
+ Railsthemes::Installer.new.download_from_code code
20
+ end
21
+ end
22
+
23
+ # AP: other options could include list, remove, help, etc.
24
+ end
25
+
26
+ Installer.start ARGV
@@ -1,65 +1,47 @@
1
+ require 'rubygems'
1
2
  require 'date'
2
3
  require 'fileutils'
3
4
  require 'logger'
4
5
  require 'tmpdir'
6
+ require 'bundler'
7
+ require 'net/http'
8
+ require 'rest-client'
5
9
 
6
10
  module Railsthemes
7
11
  class Installer
8
12
  def initialize logger = nil
9
13
  @logger = logger
14
+ @server = File.exist?('railsthemes_server') ? File.read('railsthemes_server') : 'https://railsthemes.com'
10
15
  @logger ||= Logger.new(STDOUT)
16
+ # just print out basic information, not all of the extra logger stuff
11
17
  @logger.formatter = proc do |severity, datetime, progname, msg|
12
18
  "#{msg}\n"
13
19
  end
14
20
  end
15
21
 
16
- def execute args = []
17
- if args[0] == 'install' && args.length > 1
18
- install *args[1..-1]
19
- else
20
- print_usage
21
- end
22
- end
23
-
24
- def install *args
25
- ensure_in_rails_root
26
- if args[0] == '--file'
27
- if args[1]
28
- install_from_file_system args[1]
29
- else
30
- print_usage_and_abort "The parameter --file means we need another parameter after it to specify what file to load from."
31
- end
32
- elsif args[0] == '--help'
33
- print_usage
34
- else
35
- if args[0]
36
- download_from_hash args[0]
37
- else
38
- print_usage_and_abort "railsthemes expects the hash that you got from the website as a parameter in order to download the theme you bought."
39
- end
40
- end
41
- end
42
-
43
22
  def ensure_in_rails_root
44
23
  unless File.directory?('app') && File.directory?('public')
45
24
  Safe.log_and_abort 'Must be in the Rails root directory to use this gem.'
46
25
  end
47
26
  end
48
27
 
49
- def install_from_file_system filepath
50
- if File.directory?(filepath)
51
- files = files_under(filepath)
52
- @logger.info 'Copying assets...'
53
- files.each do |file|
54
- copy_with_replacement filepath, file
55
- end
56
- @logger.info 'Done copying assets.'
28
+ def install_from_file_system source_filepath
29
+ if File.directory?(source_filepath)
30
+ ensure_in_rails_root
31
+
32
+ @logger.info 'Installing...'
33
+ FileUtils.cp_r(File.join(source_filepath, 'base', '.'), '.')
34
+ gemfile_contents = File.read('Gemfile.lock')
35
+ install_gems_from(source_filepath, gems_used(File.read('Gemfile.lock')) - ['haml', 'sass'])
36
+
37
+ @logger.info 'Done installing.'
57
38
  post_copying_changes
58
39
  print_post_installation_instructions
59
- elsif archive?(filepath)
60
- if File.exists?(filepath)
61
- install_from_archive filepath
62
- # no need for post_installation, because we haven't
40
+ elsif archive?(source_filepath)
41
+ if File.exists?(source_filepath)
42
+ install_from_archive source_filepath
43
+ # no need for post_installation, because we will do this in the
44
+ # install_from_archive method
63
45
  else
64
46
  Safe.log_and_abort 'Cannot find the file you specified.'
65
47
  end
@@ -68,98 +50,183 @@ module Railsthemes
68
50
  end
69
51
  end
70
52
 
71
- # this happens after a successful copy so that we set up the environment correctly
72
- def post_copying_changes
73
- Utils.remove_file File.join('public', 'index.html')
74
- @logger.info 'Analyzing existing project structure...'
75
- create_welcome_controller unless routes_defined?
53
+ def install_gems_from source_filepath, gem_names
54
+ gems_that_we_can_install = Dir.entries("#{source_filepath}/gems").reject{|x| x == '.' || x == '..'}
55
+ (gem_names & gems_that_we_can_install).each do |gem_name|
56
+ FileUtils.cp_r(File.join(source_filepath, 'gems', gem_name, '.'), '.')
57
+ end
76
58
  end
77
59
 
78
- def create_welcome_controller
79
- Safe.system_call('rails g controller Welcome index')
80
- lines = []
81
- File.open('config/routes.rb').each do |line|
82
- if line =~ / # root :to => 'welcome#index'/
83
- lines << " root :to => 'welcome#index'"
84
- else
85
- lines << line
86
- end
60
+ def install_from_archive filepath
61
+ @logger.info "Extracting..."
62
+ with_tempdir do |tempdir|
63
+ Safe.system_call untar_string(filepath, tempdir)
64
+ @logger.info "Finished extracting."
65
+ install_from_file_system tempdir
87
66
  end
88
- File.open('config/routes.rb', 'w') do |f|
89
- lines.each do |line|
90
- f.puts line
67
+ end
68
+
69
+ def download_from_code code
70
+ check_vcs_status
71
+ if File.exists?('Gemfile.lock')
72
+ @logger.info "Downloading..."
73
+ with_tempdir do |tempdir|
74
+ archive = File.join(tempdir, 'archive.tar.gz')
75
+ send_gemfile code
76
+ config = get_primary_configuration(File.read('Gemfile.lock'))
77
+ dl_url = get_download_url "#{@server}/download?code=#{code}&config=#{config}"
78
+ if dl_url
79
+ Utils.download_file_to dl_url, archive
80
+ @logger.info "Finished downloading."
81
+ install_from_archive archive
82
+ else
83
+ Safe.log_and_abort("We didn't understand the code you gave to download the theme (#{code})")
84
+ end
91
85
  end
86
+ else
87
+ Safe.log_and_abort("We could not find your Gemfile.lock file.") unless File.exists?('Gemfile.lock')
92
88
  end
93
89
  end
94
90
 
95
- def routes_defined?
96
- Safe.system_call('rake routes').length > 0
91
+ def get_download_url server_request_url
92
+ response = nil
93
+ begin
94
+ response = Net::HTTP.get_response URI.parse(server_request_url)
95
+ rescue Exception => e
96
+ #@logger.info e.message
97
+ #@logger.info e.backtrace
98
+ end
99
+
100
+ response.body if response && response.code.to_s == '200'
97
101
  end
98
102
 
99
- def install_from_archive filepath
100
- tempdir = generate_tmpdir
101
- Dir.mkdir tempdir
102
- Safe.system_call untar_string(filepath, tempdir)
103
- install_from_file_system tempdir
104
- #FileUtils.rm_rf tempdir
103
+ def gems_used
104
+ gems_used File.read('Gemfile.lock')
105
105
  end
106
106
 
107
- def files_under filepath, accum = []
108
- files = Dir.chdir(filepath) { Dir['**/*'] }
109
- files.select{|f| !File.directory?(File.join(filepath, f))}
107
+ def gems_used contents
108
+ return [] if contents.strip == ''
109
+ lockfile = Bundler::LockfileParser.new(contents)
110
+ lockfile.specs.map(&:name)
110
111
  end
111
112
 
112
- def download_from_hash hash
113
- @logger.info "Downloading from hash #{hash}"
113
+ def get_primary_configuration contents
114
+ gems = gems_used(contents)
115
+ to_return = []
116
+ to_return << (gems.include?('haml') ? 'haml' : 'erb')
117
+ to_return << (gems.include?('sass') ? 'scss' : 'css')
118
+ to_return * ','
114
119
  end
115
120
 
116
- def copy_with_replacement filepath, entry
117
- if File.exists?(entry)
118
- # not sure if I should put in a cp -f here, might be better to toss error
119
- # so I'm using rename instead
120
- File.rename entry, "#{entry}.old"
121
+ def send_gemfile code
122
+ begin
123
+ response = RestClient.post("#{@server}/gemfiles/parse",
124
+ :code => code, :gemfile_lock => File.new('Gemfile.lock', 'rb'))
125
+ rescue Exception => e
126
+ #@logger.info e.message
127
+ #@logger.info e.backtrace
121
128
  end
122
- Utils.copy_with_path File.join(filepath, entry), entry
123
129
  end
124
130
 
125
- def generate_tmpdir
126
- File.join(Dir.tmpdir, DateTime.now.strftime("railsthemes-%Y%m%d-%H%M%s"))
131
+ def with_tempdir &block
132
+ tempdir = generate_tempdir_name
133
+ FileUtils.mkdir_p tempdir
134
+ yield tempdir
135
+ FileUtils.rm_rf tempdir
136
+ end
137
+
138
+ def generate_tempdir_name
139
+ File.join(Dir.tmpdir, DateTime.now.strftime("railsthemes-%Y%m%d-%H%M%S-#{rand(100000000)}"))
127
140
  end
128
141
 
129
142
  def archive? filepath
130
- filepath =~ /\.tar$/ || filepath =~ /\.tar\.gz$/
143
+ filepath =~ /\.tar\.gz$/
131
144
  end
132
145
 
133
146
  def untar_string filepath, newdirpath
134
- gzipped = (filepath =~ /\.gz$/) ? 'z' : ''
135
- "tar -#{gzipped}xf #{filepath} --strip 1"
147
+ "tar -zxf #{filepath}"
136
148
  end
137
149
 
138
- def print_usage
139
- @logger.info <<-EOS
140
- Usage:
141
- ------
142
- railsthemes install HASH
143
- install a theme from the railsthemes website
144
150
 
145
- railsthemes install --help
146
- this message
151
+ # this happens after a successful copy so that we set up the environment correctly
152
+ # for people to view the theme correctly
153
+ def post_copying_changes
154
+ Utils.remove_file File.join('public', 'index.html')
155
+ @logger.info 'Analyzing existing project structure...'
156
+ create_railsthemes_controller
157
+ end
158
+
159
+ def create_railsthemes_controller
160
+ FileUtils.mkdir_p(File.join('app', 'controllers'))
161
+ File.open(File.join('app', 'controllers', 'railsthemes_controller.rb'), 'w') do |f|
162
+ f.write <<-EOS
163
+ class RailsthemesController < ApplicationController
164
+ # normally every view will use your application layout
165
+ def inner
166
+ render :layout => 'application'
167
+ end
147
168
 
148
- railsthemes install --file filepath
149
- install from the local filesystem
150
- EOS
169
+ # this is a special layout
170
+ def landing
171
+ render :layout => 'landing'
172
+ end
173
+ end
174
+ EOS
175
+ end
176
+
177
+ lines = []
178
+ if File.exists?('config/routes.rb')
179
+ lines = File.read('config/routes.rb').split("\n")
180
+ last = lines.pop
181
+ lines << " match 'railsthemes/landing' => 'railsthemes#landing'"
182
+ lines << " match 'railsthemes/inner' => 'railsthemes#inner'"
183
+ lines << last
184
+ File.open('config/routes.rb', 'w') do |f|
185
+ lines.each do |line|
186
+ f.puts line
187
+ end
188
+ end
189
+ end
190
+ end
191
+
192
+ def check_vcs_status
193
+ result = ''
194
+ variety = ''
195
+ if File.directory?('.git')
196
+ variety = 'Git'
197
+ result = Safe.system_call('git status -s')
198
+ elsif File.directory?('.hg')
199
+ variety = 'Mercurial'
200
+ result = Safe.system_call('hg status')
201
+ elsif File.directory?('.svn')
202
+ variety = 'Subversion'
203
+ result = Safe.system_call('svn status')
204
+ end
205
+ unless result.size == 0
206
+ Safe.log_and_abort("\n#{variety} reports that you have the following pending changes:\n#{result}Please stash or commit the changes before proceeding to ensure that you can roll back after installing if you want.")
207
+ end
151
208
  end
152
209
 
153
210
  def print_post_installation_instructions
154
211
  @logger.info <<-EOS
155
- Your theme is installed!
156
212
 
157
- Make sure that you restart your server if it's currently running.
213
+ Yay! Your theme is installed!
214
+
215
+ =============================
216
+
217
+ What now?
218
+ 1) Ensure your new application layout file contains everything that you wanted
219
+ from the old one.
220
+ 2) Restart your development server if it is currently running (the asset pipeline can
221
+ be finnicky.)
222
+ 3) Check out the samples at:
223
+ http://localhost:3000/railsthemes/landing
224
+ http://localhost:3000/railsthemes/inner
225
+ 4) Let us know how it went: @railsthemes or team@railsthemes.com
158
226
  EOS
159
227
  end
160
228
 
161
229
  def print_usage_and_abort s
162
- print_usage
163
230
  Safe.log_and_abort s
164
231
  end
165
232
  end
@@ -4,16 +4,11 @@ require 'fileutils'
4
4
  module Railsthemes
5
5
  class Safe
6
6
  def self.system_call s
7
- verify_not_testing
8
7
  `#{s}`
9
8
  end
10
9
 
11
10
  def self.log_and_abort s
12
11
  abort s
13
12
  end
14
-
15
- def self.verify_not_testing
16
- false
17
- end
18
13
  end
19
14
  end
@@ -1,17 +1,30 @@
1
1
  require 'fileutils'
2
+ require 'open-uri'
2
3
 
3
4
  # a bunch of things that should never be called in testing due to side effects
4
5
  module Railsthemes
5
6
  class Utils
7
+ # remove file only if it exists
6
8
  def self.remove_file filepath
7
9
  if File.exists?(filepath)
8
10
  File.delete filepath
9
11
  end
10
12
  end
11
13
 
12
- def self.copy_with_path src, dest
14
+ # copy a file, ensuring that the directory is present
15
+ def self.copy_ensuring_directory_exists src, dest
13
16
  FileUtils.mkdir_p(File.dirname(dest)) # create directory if necessary
14
17
  FileUtils.cp src, dest
15
18
  end
19
+
20
+ # would be nice to put download status in the output (speed, progress, etc.)
21
+ def self.download_file_to url, save_to
22
+ File.open(save_to, "wb") do |saved_file|
23
+ # the following "open" is provided by open-uri
24
+ open(url) do |read_file|
25
+ saved_file.write(read_file.read)
26
+ end
27
+ end
28
+ end
16
29
  end
17
30
  end
@@ -1,5 +1,5 @@
1
1
  module Railsthemes
2
2
  unless defined?(Railsthemes::VERSION)
3
- VERSION = "0.0.1"
3
+ VERSION = "1.0.0"
4
4
  end
5
5
  end
data/railsthemes.gemspec CHANGED
@@ -2,8 +2,8 @@
2
2
  require File.expand_path('../lib/railsthemes/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |gem|
5
- gem.authors = ["railsthemes"]
6
- gem.email = ["panozzaj@gmail.com"]
5
+ gem.authors = ["Railsthemes"]
6
+ gem.email = ["anthony@railsthemes.com"]
7
7
  gem.description = %q{railsthemes.com installer gem}
8
8
  gem.summary = %q{Installs gems from railsthemes.com}
9
9
  gem.homepage = "https://github.com/RailsThemes/railsthemes"
@@ -14,4 +14,7 @@ Gem::Specification.new do |gem|
14
14
  gem.name = "railsthemes"
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = Railsthemes::VERSION
17
+
18
+ gem.add_dependency "thor"
19
+ gem.add_dependency "rest-client"
17
20
  end
@@ -0,0 +1,259 @@
1
+ require 'spec_helper'
2
+ require 'railsthemes'
3
+
4
+ describe Railsthemes::Installer do
5
+ def using_gems *gems
6
+ "GEM\nremote: https://rubygems.org/\nspecs:\n" +
7
+ gems.map{|gem| " #{gem}"}.join("\n") +
8
+ "\nGEM\n remote: https://rubygems.org/"
9
+ end
10
+
11
+ before do
12
+ @logger = Logger.new(File.join Dir.tmpdir, 'railsthemes.log')
13
+ @installer = Railsthemes::Installer.new @logger
14
+ stub(@installer).ensure_in_rails_root
15
+ stub(@installer).generate_tempdir_name { '/tmp' }
16
+ FileUtils.touch('Gemfile.lock')
17
+ end
18
+
19
+ describe :install_from_file_system do
20
+ context 'when the filepath is a directory' do
21
+ it 'should copy the files from that directory into the Rails app' do
22
+ FileUtils.mkdir_p('filepath/base')
23
+ FileUtils.touch('filepath/base/a')
24
+ FileUtils.touch('filepath/base/b')
25
+ FileUtils.mkdir_p('filepath/gems')
26
+ mock(@installer).post_copying_changes
27
+
28
+ @installer.install_from_file_system('filepath')
29
+ File.exists?('a').should be_true
30
+ File.exists?('b').should be_true
31
+ end
32
+ end
33
+
34
+ context 'when the filepath is an archive file' do
35
+ it 'should extract the archive file to a temp directory if the archive exists' do
36
+ archive = 'tarfile.tar.gz'
37
+ FileUtils.touch archive
38
+ mock(@installer).install_from_archive archive
39
+ @installer.install_from_file_system archive
40
+ end
41
+
42
+ it 'should print an error message and exit if the archive cannot be found' do
43
+ mock(Railsthemes::Safe).log_and_abort(/Cannot find/)
44
+ @installer.install_from_file_system 'tarfile.tar.gz'
45
+ end
46
+ end
47
+
48
+ context 'otherwise' do
49
+ it 'should print usage and report an error reading the file' do
50
+ mock(@installer).print_usage_and_abort(/either/)
51
+ @installer.install_from_file_system("does not exist")
52
+ end
53
+ end
54
+ end
55
+
56
+ describe :install_gems_from do
57
+ it 'should install the gems that we specify that match' do
58
+ FakeFS::FileSystem.clone('spec/fixtures')
59
+ @installer.install_gems_from("spec/fixtures/blank-assets", ['formtastic', 'kaminari'])
60
+ File.exist?(File.join('app', 'assets', 'stylesheets', 'formtastic.css.scss')).should be_true
61
+ File.exist?(File.join('app', 'assets', 'stylesheets', 'kaminari.css.scss')).should be_false
62
+ File.exist?(File.join('app', 'assets', 'stylesheets', 'simple_form.css.scss')).should be_false
63
+ end
64
+ end
65
+
66
+ describe :install_from_archive do
67
+ it 'should extract the archive correctly' do
68
+ mock(@installer).install_from_file_system '/tmp'
69
+ mock(@installer).untar_string('filepath', anything) { 'untar string' }
70
+ mock(Railsthemes::Safe).system_call('untar string')
71
+ @installer.install_from_archive 'filepath'
72
+ end
73
+ end
74
+
75
+ describe :untar_string do
76
+ it 'should return correct value for *.tar.gz file' do
77
+ result = @installer.untar_string 'file.tar.gz', 'newdirpath'
78
+ result.should == 'tar -zxf file.tar.gz'
79
+ end
80
+ end
81
+
82
+ describe :archive? do
83
+ it 'should be true for tar.gz file' do
84
+ @installer.archive?('test/a/b/c/d.tar.gz').should be_true
85
+ end
86
+
87
+ it 'should be false for other extensions' do
88
+ @installer.archive?('test/a/b/c.tar/d.zip').should be_false
89
+ end
90
+ end
91
+
92
+ describe 'end to end operation' do
93
+ def verify_end_to_end_operation
94
+ ['app/assets/images/image1.png',
95
+ 'app/assets/images/bg/sprite.png',
96
+ 'app/assets/javascripts/jquery.dataTables.js',
97
+ 'app/assets/javascripts/scripts.js.erb',
98
+ 'app/assets/stylesheets/style.css.erb',
99
+ 'app/views/layouts/_interior_sidebar.html.erb',
100
+ 'app/views/layouts/application.html.erb',
101
+ 'app/views/layouts/homepage.html.erb'].each do |filename|
102
+ File.exist?(filename).should be_true, "#{filename} was not present"
103
+ end
104
+ File.open('app/assets/stylesheets/style.css.erb').each do |line|
105
+ line.should match /style.css.erb/
106
+ end
107
+ end
108
+
109
+ before do
110
+ stub(@installer).post_copying_changes
111
+ FakeFS::FileSystem.clone('spec/fixtures')
112
+ end
113
+
114
+ it 'should extract correctly from directory' do
115
+ filename = 'spec/fixtures/blank-assets'
116
+ @installer.install_from_file_system filename
117
+ verify_end_to_end_operation
118
+ end
119
+
120
+ # TODO need to use a pure ruby solution to get this to mock in the file system right
121
+ it 'should extract correctly from archive' do
122
+ pending 'needs pure ruby untar solution'
123
+ end
124
+ end
125
+
126
+ describe :send_gemfile do
127
+ before do
128
+ File.open('Gemfile.lock', 'w') do |file|
129
+ file.puts "GEM\n remote: https://rubygems.org/"
130
+ end
131
+ end
132
+
133
+ it 'should hit the server with the Gemfile and return the results, arrayified' do
134
+ FakeFS.deactivate! # has an issue with generating tmpfiles otherwise
135
+ params = { :code => 'panozzaj@gmail.com:code', :gemfile_lock => File.new('Gemfile.lock', 'rb') }
136
+ FakeWeb.register_uri :post, 'https://railsthemes.com/gemfiles/parse',
137
+ :body => 'haml,scss', :parameters => params
138
+ @installer.send_gemfile('panozzaj@gmail.com:code')
139
+ end
140
+
141
+ it 'should return a blank array when there are issues' do
142
+ FakeFS.deactivate! # has an issue with generating tmpfiles otherwise
143
+ FakeWeb.register_uri :post, 'https://railsthemes.com/gemfiles/parse',
144
+ :body => '', :parameters => :any, :status => ['401', 'Unauthorized']
145
+ @installer.send_gemfile('panozzaj@gmail.com:code')
146
+ end
147
+ end
148
+
149
+ describe :download_from_code do
150
+ context 'when a gemfile.lock is not present' do
151
+ it 'should fail with a good message' do
152
+ File.unlink('Gemfile.lock')
153
+ mock(Railsthemes::Safe).log_and_abort(/could not find/)
154
+ @installer.download_from_code 'anything'
155
+ end
156
+ end
157
+
158
+ context 'when a gemfile.lock is present' do
159
+ before do
160
+ mock(@installer).check_vcs_status
161
+ mock(@installer).send_gemfile('panozzaj@gmail.com:code')
162
+ end
163
+
164
+ it 'should download the file correctly when valid configuration' do
165
+ FakeWeb.register_uri :get,
166
+ /download\?code=panozzaj@gmail.com:code&config=haml,scss/,
167
+ :body => 'auth_url'
168
+ mock(@installer).get_primary_configuration('') { 'haml,scss' }
169
+ mock(Railsthemes::Utils).download_file_to('auth_url', '/tmp/archive.tar.gz')
170
+ mock(@installer).install_from_archive '/tmp/archive.tar.gz'
171
+ @installer.download_from_code 'panozzaj@gmail.com:code'
172
+ end
173
+
174
+ it 'should fail with an error message on any error message' do
175
+ FakeWeb.register_uri :get,
176
+ 'https://railsthemes.com/download?code=panozzaj@gmail.com:code&config=',
177
+ :body => '', :status => ['401', 'Unauthorized']
178
+ mock(@installer).get_primary_configuration('') { '' }
179
+ mock(Railsthemes::Safe).log_and_abort(/didn't understand/)
180
+ @installer.download_from_code 'panozzaj@gmail.com:code'
181
+ end
182
+ end
183
+ end
184
+
185
+ describe '#get_primary_configuration' do
186
+ it 'should give haml+scss when haml and sass are in the Gemfile' do
187
+ gemfile = using_gems 'haml', 'sass'
188
+ @installer.get_primary_configuration(gemfile).should == 'haml,scss'
189
+ end
190
+
191
+ it 'should give haml+css when sass is not in the Gemfile' do
192
+ gemfile = using_gems 'haml'
193
+ @installer.get_primary_configuration(gemfile).should == 'haml,css'
194
+ end
195
+
196
+ it 'should give erb, scss when haml is not in the gemfile' do
197
+ gemfile = using_gems 'sass'
198
+ @installer.get_primary_configuration(gemfile).should == 'erb,scss'
199
+ end
200
+
201
+ it 'should give erb, scss when haml is not in the gemfile' do
202
+ gemfile = using_gems
203
+ @installer.get_primary_configuration(gemfile).should == 'erb,css'
204
+ end
205
+ end
206
+
207
+ describe :check_vcs_status do
208
+ context 'when git used' do
209
+ before do
210
+ Dir.mkdir('.git')
211
+ end
212
+
213
+ it 'should exit when the vcs is unclean' do
214
+ mock(Railsthemes::Safe).system_call('git status -s') { '# modified: installer_spec.rb' }
215
+ mock(Railsthemes::Safe).log_and_abort(/pending changes/)
216
+ @installer.check_vcs_status
217
+ end
218
+
219
+ it 'should do nothing significant when the vcs is clean' do
220
+ mock(Railsthemes::Safe).system_call('git status -s') { '' }
221
+ @installer.check_vcs_status
222
+ end
223
+ end
224
+
225
+ context 'when hg used' do
226
+ before do
227
+ Dir.mkdir('.hg')
228
+ end
229
+
230
+ it 'should exit when the vcs is unclean' do
231
+ mock(Railsthemes::Safe).system_call('hg status') { '? test.txt' }
232
+ mock(Railsthemes::Safe).log_and_abort(/pending changes/)
233
+ @installer.check_vcs_status
234
+ end
235
+
236
+ it 'should do nothing significant when the vcs is clean' do
237
+ mock(Railsthemes::Safe).system_call('hg status') { '' }
238
+ @installer.check_vcs_status
239
+ end
240
+ end
241
+
242
+ context 'when subversion used' do
243
+ before do
244
+ Dir.mkdir('.svn')
245
+ end
246
+
247
+ it 'should exit when the vcs is unclean' do
248
+ mock(Railsthemes::Safe).system_call('svn status') { 'M something.txt' }
249
+ mock(Railsthemes::Safe).log_and_abort(/pending changes/)
250
+ @installer.check_vcs_status
251
+ end
252
+
253
+ it 'should do nothing significant when the vcs is clean' do
254
+ mock(Railsthemes::Safe).system_call('svn status') { '' }
255
+ @installer.check_vcs_status
256
+ end
257
+ end
258
+ end
259
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,10 +1,12 @@
1
1
  require 'rubygems'
2
2
  require 'bundler/setup'
3
+ require 'logger'
3
4
  require 'fakefs/spec_helpers'
4
-
5
- require 'railsthemes'
5
+ require 'fakeweb'
6
6
 
7
7
  RSpec.configure do |config|
8
8
  config.mock_with :rr
9
9
  config.include FakeFS::SpecHelpers
10
10
  end
11
+
12
+ FakeWeb.allow_net_connect = false
metadata CHANGED
@@ -1,26 +1,53 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: railsthemes
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
+ - 1
7
8
  - 0
8
9
  - 0
9
- - 1
10
- version: 0.0.1
10
+ version: 1.0.0
11
11
  platform: ruby
12
12
  authors:
13
- - railsthemes
13
+ - Railsthemes
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-03-10 00:00:00 Z
19
- dependencies: []
20
-
18
+ date: 2012-04-20 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: thor
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: rest-client
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 3
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ type: :runtime
47
+ version_requirements: *id002
21
48
  description: railsthemes.com installer gem
22
49
  email:
23
- - panozzaj@gmail.com
50
+ - anthony@railsthemes.com
24
51
  executables:
25
52
  - railsthemes
26
53
  extensions: []
@@ -42,7 +69,17 @@ files:
42
69
  - lib/railsthemes/utils.rb
43
70
  - lib/railsthemes/version.rb
44
71
  - railsthemes.gemspec
45
- - spec/lib/railsthemes_spec.rb
72
+ - spec/fixtures/blank-assets/base/app/assets/images/bg/sprite.png
73
+ - spec/fixtures/blank-assets/base/app/assets/images/image1.png
74
+ - spec/fixtures/blank-assets/base/app/assets/javascripts/jquery.dataTables.js
75
+ - spec/fixtures/blank-assets/base/app/assets/javascripts/scripts.js.erb
76
+ - spec/fixtures/blank-assets/base/app/assets/stylesheets/style.css.erb
77
+ - spec/fixtures/blank-assets/base/app/views/layouts/_interior_sidebar.html.erb
78
+ - spec/fixtures/blank-assets/base/app/views/layouts/application.html.erb
79
+ - spec/fixtures/blank-assets/base/app/views/layouts/homepage.html.erb
80
+ - spec/fixtures/blank-assets/gems/formtastic/app/assets/stylesheets/formtastic.css.scss
81
+ - spec/fixtures/blank-assets/gems/simple_form/app/assets/stylesheets/simple_form.css.scss
82
+ - spec/lib/railsthemes/installer_spec.rb
46
83
  - spec/spec_helper.rb
47
84
  homepage: https://github.com/RailsThemes/railsthemes
48
85
  licenses: []
@@ -73,10 +110,20 @@ required_rubygems_version: !ruby/object:Gem::Requirement
73
110
  requirements: []
74
111
 
75
112
  rubyforge_project:
76
- rubygems_version: 1.8.7
113
+ rubygems_version: 1.8.21
77
114
  signing_key:
78
115
  specification_version: 3
79
116
  summary: Installs gems from railsthemes.com
80
117
  test_files:
81
- - spec/lib/railsthemes_spec.rb
118
+ - spec/fixtures/blank-assets/base/app/assets/images/bg/sprite.png
119
+ - spec/fixtures/blank-assets/base/app/assets/images/image1.png
120
+ - spec/fixtures/blank-assets/base/app/assets/javascripts/jquery.dataTables.js
121
+ - spec/fixtures/blank-assets/base/app/assets/javascripts/scripts.js.erb
122
+ - spec/fixtures/blank-assets/base/app/assets/stylesheets/style.css.erb
123
+ - spec/fixtures/blank-assets/base/app/views/layouts/_interior_sidebar.html.erb
124
+ - spec/fixtures/blank-assets/base/app/views/layouts/application.html.erb
125
+ - spec/fixtures/blank-assets/base/app/views/layouts/homepage.html.erb
126
+ - spec/fixtures/blank-assets/gems/formtastic/app/assets/stylesheets/formtastic.css.scss
127
+ - spec/fixtures/blank-assets/gems/simple_form/app/assets/stylesheets/simple_form.css.scss
128
+ - spec/lib/railsthemes/installer_spec.rb
82
129
  - spec/spec_helper.rb
@@ -1,165 +0,0 @@
1
- require 'spec_helper'
2
- require 'logger'
3
-
4
- describe Railsthemes do
5
- before do
6
- @logger = Logger.new(File.join Dir.tmpdir, 'railsthemes.log')
7
- @installer = Railsthemes::Installer.new @logger
8
- end
9
-
10
- describe :execute do
11
- it 'should print usage if no params given' do
12
- mock(@installer).print_usage
13
- @installer.execute
14
- end
15
-
16
- it 'should run the installer if installer is the first parameter' do
17
- mock(@installer).install 'a', 'b', 'c'
18
- @installer.execute(['install', 'a', 'b', 'c'])
19
- end
20
- end
21
-
22
- describe :install do
23
- before do
24
- stub(@installer).ensure_in_rails_root
25
- end
26
-
27
- context 'when --file is given as a parameter' do
28
- it 'should read from the file argument' do
29
- mock(@installer).install_from_file_system('filepath')
30
- @installer.install '--file', 'filepath'
31
- end
32
-
33
- it 'should print usage and error message and exit if filepath is nil' do
34
- dont_allow(@installer).install_from_file_system(anything)
35
- dont_allow(@installer).download_from_hash(anything)
36
- mock(@installer).print_usage_and_abort(/parameter/)
37
- @installer.install '--file'
38
- end
39
- end
40
-
41
- context 'hash given' do
42
- it 'should download that hash' do
43
- mock(@installer).download_from_hash('hash')
44
- @installer.install 'hash'
45
- end
46
- end
47
-
48
- context '--help given' do
49
- it 'should print the usage' do
50
- mock(@installer).print_usage
51
- @installer.install '--help'
52
- end
53
- end
54
-
55
- context 'when no parameters given' do
56
- it 'should print usage and error message and exit' do
57
- dont_allow(@installer).install_from_file_system(anything)
58
- dont_allow(@installer).download_from_hash(anything)
59
- mock(@installer).print_usage_and_abort(/parameter/)
60
- @installer.install '--file'
61
- end
62
- end
63
- end
64
-
65
- describe :install_from_file_system do
66
- context 'when the filepath is a directory' do
67
- it 'should copy the files from that directory into the Rails app' do
68
- FileUtils.mkdir('filepath')
69
- FileUtils.touch('filepath/a')
70
- FileUtils.touch('filepath/b')
71
- mock(@installer).post_copying_changes
72
-
73
- mock(@installer).copy_with_replacement('filepath', /a$/)
74
- mock(@installer).copy_with_replacement('filepath', /b$/)
75
- @installer.install_from_file_system('filepath')
76
- end
77
- end
78
-
79
- context 'when the filepath is an archive file' do
80
- it 'should extract the archive file to a temp directory if the archive exists' do
81
- archive = 'tarfile.tar'
82
- FileUtils.touch archive
83
- mock(@installer).install_from_archive archive
84
- @installer.install_from_file_system archive
85
- end
86
-
87
- it 'should print an error message and exit if the archive cannot be found' do
88
- mock(Railsthemes::Safe).log_and_abort(/Cannot find/)
89
- @installer.install_from_file_system 'tarfile.tar'
90
- end
91
- end
92
-
93
- context 'otherwise' do
94
- it 'should print usage and report an error reading the file' do
95
- mock(@installer).print_usage_and_abort(/either/)
96
- @installer.install_from_file_system("does not exist")
97
- end
98
- end
99
- end
100
-
101
- describe :copy_with_replacement do
102
- before do
103
- FileUtils.mkdir 'fp'
104
- FileUtils.touch 'fp/file'
105
- end
106
-
107
- context 'when the destination file does not exist' do
108
- it 'should copy the file to the local directory' do
109
- @installer.copy_with_replacement 'fp', 'file'
110
- File.exists?('file').should be_true
111
- end
112
- end
113
-
114
- context 'when the destination file exists' do
115
- before do
116
- FileUtils.touch 'file'
117
- end
118
-
119
- it 'should make a backup of existing file if it is present' do
120
- @installer.copy_with_replacement 'fp', 'file'
121
- File.exists?('file').should be_true
122
- File.exists?('file.old').should be_true
123
- end
124
- end
125
- end
126
-
127
- describe :install_from_archive do
128
- it 'should extract the archive correctly' do
129
- stub(@installer).generate_tmpdir { 'tmp' }
130
- mock(@installer).install_from_file_system 'tmp'
131
- mock(@installer).untar_string('filepath', anything) { 'untar string' }
132
- mock(Railsthemes::Safe).system_call('untar string')
133
- @installer.install_from_archive 'filepath'
134
- end
135
- end
136
-
137
- describe :untar_string do
138
- it 'should return correct value for *.tar.gz file' do
139
- result = @installer.untar_string 'file.tar.gz', 'newdirpath'
140
- result.should == 'tar -zxf file.tar.gz'
141
- end
142
-
143
- it 'should return correct value for *.tar file' do
144
- result = @installer.untar_string 'file.tar', 'newdirpath'
145
- result.should == 'tar -xf file.tar'
146
- end
147
- end
148
-
149
- describe :archive? do
150
- it 'should be true for tar file' do
151
- @installer.archive?('test/a/b/c/d.tar').should be_true
152
- end
153
-
154
- it 'should be true for tar.gz file' do
155
- @installer.archive?('test/a/b/c/d.tar.gz').should be_true
156
- end
157
-
158
- it 'should be false for other extensions' do
159
- @installer.archive?('test/a/b/c.tar/d.zip').should be_false
160
- end
161
- end
162
-
163
- describe :download_from_hash
164
-
165
- end