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 +4 -1
- data/README.md +9 -11
- data/bin/railsthemes +23 -3
- data/lib/railsthemes/installer.rb +161 -94
- data/lib/railsthemes/safe.rb +0 -5
- data/lib/railsthemes/utils.rb +14 -1
- data/lib/railsthemes/version.rb +1 -1
- data/railsthemes.gemspec +5 -2
- data/spec/fixtures/blank-assets/base/app/assets/images/bg/sprite.png +0 -0
- data/spec/fixtures/blank-assets/base/app/assets/images/image1.png +0 -0
- data/spec/fixtures/blank-assets/base/app/assets/javascripts/jquery.dataTables.js +0 -0
- data/spec/fixtures/blank-assets/base/app/assets/javascripts/scripts.js.erb +0 -0
- data/spec/fixtures/blank-assets/base/app/assets/stylesheets/style.css.erb +1 -0
- data/spec/fixtures/blank-assets/base/app/views/layouts/_interior_sidebar.html.erb +0 -0
- data/spec/fixtures/blank-assets/base/app/views/layouts/application.html.erb +0 -0
- data/spec/fixtures/blank-assets/base/app/views/layouts/homepage.html.erb +0 -0
- data/spec/fixtures/blank-assets/gems/formtastic/app/assets/stylesheets/formtastic.css.scss +0 -0
- data/spec/fixtures/blank-assets/gems/simple_form/app/assets/stylesheets/simple_form.css.scss +0 -0
- data/spec/lib/railsthemes/installer_spec.rb +259 -0
- data/spec/spec_helper.rb +4 -2
- metadata +58 -11
- data/spec/lib/railsthemes_spec.rb +0 -165
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
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
6
|
-
|
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
|
50
|
-
if File.directory?(
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
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?(
|
60
|
-
if File.exists?(
|
61
|
-
install_from_archive
|
62
|
-
# no need for post_installation, because we
|
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
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
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
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
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
|
-
|
89
|
-
|
90
|
-
|
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
|
96
|
-
|
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
|
100
|
-
|
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
|
108
|
-
|
109
|
-
|
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
|
113
|
-
|
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
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
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
|
126
|
-
|
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
|
143
|
+
filepath =~ /\.tar\.gz$/
|
131
144
|
end
|
132
145
|
|
133
146
|
def untar_string filepath, newdirpath
|
134
|
-
|
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
|
-
|
146
|
-
|
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
|
-
|
149
|
-
|
150
|
-
|
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
|
-
|
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
|
data/lib/railsthemes/safe.rb
CHANGED
data/lib/railsthemes/utils.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/railsthemes/version.rb
CHANGED
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 = ["
|
6
|
-
gem.email = ["
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
style.css.erb
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -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:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
|
+
- 1
|
7
8
|
- 0
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.1
|
10
|
+
version: 1.0.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
|
-
-
|
13
|
+
- Railsthemes
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-
|
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
|
-
-
|
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/
|
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.
|
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/
|
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
|